summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2018-02-07 15:54:20 -0700
committerJens Axboe <axboe@kernel.dk>2018-02-07 15:54:20 -0700
commit61a695184fcc8f225327206b88320279dd8684af (patch)
tree6cbda2b0e7de94ebad95072d17cc0aa82c9d8ab3
parent9e05c864993c5442227f83ae1694a737d7a102ed (diff)
parent581e400ff935d34d95811258586128bf11baef15 (diff)
Merge branch 'master' into test
* master: (1190 commits) ASoC: stm32: add of dependency for stm32 drivers ASoC: mt8173-rt5650: fix child-node lookup ASoC: dapm: fix debugfs read using path->connected platform/x86: samsung-laptop: Re-use DEFINE_SHOW_ATTRIBUTE() macro platform/x86: ideapad-laptop: Re-use DEFINE_SHOW_ATTRIBUTE() macro platform/x86: dell-laptop: Re-use DEFINE_SHOW_ATTRIBUTE() macro seq_file: Introduce DEFINE_SHOW_ATTRIBUTE() helper macro Documentation/sysctl/user.txt: fix typo MAINTAINERS: update ARM/QUALCOMM SUPPORT patterns MAINTAINERS: update various PALM patterns MAINTAINERS: update "ARM/OXNAS platform support" patterns MAINTAINERS: update Cortina/Gemini patterns MAINTAINERS: remove ARM/CLKDEV SUPPORT file pattern MAINTAINERS: remove ANDROID ION pattern mm: docs: add blank lines to silence sphinx "Unexpected indentation" errors mm: docs: fix parameter names mismatch mm: docs: fixup punctuation pipe: read buffer limits atomically pipe: simplify round_pipe_size() pipe: reject F_SETPIPE_SZ with size over UINT_MAX ...
-rw-r--r--Documentation/ABI/testing/sysfs-driver-samsung-laptop2
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt6
-rw-r--r--Documentation/admin-guide/thunderbolt.rst66
-rw-r--r--Documentation/bpf/bpf_devel_QA.txt31
-rw-r--r--Documentation/devicetree/bindings/media/cec-gpio.txt6
-rw-r--r--Documentation/devicetree/bindings/media/i2c/mt9m111.txt4
-rw-r--r--Documentation/devicetree/bindings/media/i2c/ov5640.txt46
-rw-r--r--Documentation/devicetree/bindings/media/i2c/ov7740.txt47
-rw-r--r--Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt7
-rw-r--r--Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt55
-rw-r--r--Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt2
-rw-r--r--Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt5
-rw-r--r--Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt22
-rw-r--r--Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt60
-rw-r--r--Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt58
-rw-r--r--Documentation/devicetree/bindings/pwm/pwm-meson.txt2
-rw-r--r--Documentation/devicetree/bindings/thermal/armada-thermal.txt37
-rw-r--r--Documentation/devicetree/bindings/thermal/rcar-thermal.txt1
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--Documentation/devicetree/bindings/watchdog/cortina,gemini-watchdog.txt17
-rw-r--r--Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.txt (renamed from Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt)11
-rw-r--r--Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt4
-rw-r--r--Documentation/devicetree/bindings/watchdog/realtek,rtd119x.txt17
-rw-r--r--Documentation/devicetree/bindings/watchdog/renesas-wdt.txt3
-rw-r--r--Documentation/devicetree/bindings/watchdog/sprd-wdt.txt19
-rw-r--r--Documentation/filesystems/overlayfs.txt106
-rw-r--r--Documentation/infiniband/user_verbs.txt2
-rw-r--r--Documentation/media/dmx.h.rst.exceptions2
-rw-r--r--Documentation/media/kapi/cec-core.rst14
-rw-r--r--Documentation/media/kapi/dtv-ca.rst2
-rw-r--r--Documentation/media/kapi/dtv-common.rst11
-rw-r--r--Documentation/media/kapi/dtv-demux.rst8
-rw-r--r--Documentation/media/kapi/dtv-frontend.rst8
-rw-r--r--Documentation/media/kapi/dtv-net.rst2
-rw-r--r--Documentation/media/kapi/rc-core.rst82
-rw-r--r--Documentation/media/kapi/v4l2-dev.rst17
-rw-r--r--Documentation/media/kapi/v4l2-event.rst67
-rw-r--r--Documentation/media/lirc.h.rst.exceptions31
-rw-r--r--Documentation/media/uapi/dvb/dmx-expbuf.rst88
-rw-r--r--Documentation/media/uapi/dvb/dmx-mmap.rst116
-rw-r--r--Documentation/media/uapi/dvb/dmx-munmap.rst54
-rw-r--r--Documentation/media/uapi/dvb/dmx-qbuf.rst83
-rw-r--r--Documentation/media/uapi/dvb/dmx-querybuf.rst63
-rw-r--r--Documentation/media/uapi/dvb/dmx-reqbufs.rst74
-rw-r--r--Documentation/media/uapi/dvb/dmx_fcalls.rst6
-rw-r--r--Documentation/media/uapi/dvb/fe_property_parameters.rst18
-rw-r--r--Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst2
-rw-r--r--Documentation/media/uapi/rc/lirc-dev-intro.rst75
-rw-r--r--Documentation/media/uapi/rc/lirc-func.rst1
-rw-r--r--Documentation/media/uapi/rc/lirc-get-features.rst25
-rw-r--r--Documentation/media/uapi/rc/lirc-get-length.rst44
-rw-r--r--Documentation/media/uapi/rc/lirc-get-rec-mode.rst45
-rw-r--r--Documentation/media/uapi/rc/lirc-get-send-mode.rst40
-rw-r--r--Documentation/media/uapi/rc/lirc-read.rst15
-rw-r--r--Documentation/media/uapi/rc/lirc-write.rst19
-rw-r--r--Documentation/media/uapi/v4l/meta-formats.rst1
-rw-r--r--Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst51
-rw-r--r--Documentation/media/uapi/v4l/pixfmt-rgb.rst1
-rw-r--r--Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst335
-rw-r--r--Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst2
-rw-r--r--Documentation/mips/AU1xxx_IDE.README7
-rw-r--r--Documentation/networking/ip-sysctl.txt4
-rw-r--r--Documentation/process/index.rst1
-rw-r--r--Documentation/process/kernel-docs.rst2
-rw-r--r--Documentation/process/maintainer-pgp-guide.rst929
-rw-r--r--Documentation/sysctl/user.txt2
-rw-r--r--Documentation/watchdog/watchdog-parameters.txt23
-rw-r--r--MAINTAINERS148
-rw-r--r--Makefile54
-rw-r--r--arch/Kconfig16
-rw-r--r--arch/alpha/kernel/console.c1
-rw-r--r--arch/arm/boot/dts/omap3-n900.dts2
-rw-r--r--arch/arm/include/asm/bitops.h1
-rw-r--r--arch/arm/include/asm/pci.h5
-rw-r--r--arch/arm/kernel/bios32.c2
-rw-r--r--arch/arm/mach-mvebu/Kconfig1
-rw-r--r--arch/arm64/Kconfig1
-rw-r--r--arch/arm64/include/asm/kasan.h17
-rw-r--r--arch/arm64/include/asm/memory.h3
-rw-r--r--arch/arm64/kernel/entry.S4
-rw-r--r--arch/arm64/kernel/perf_event.c5
-rw-r--r--arch/arm64/mm/kasan_init.c3
-rw-r--r--arch/arm64/mm/mmu.c9
-rw-r--r--arch/ia64/kernel/perfmon.c13
-rw-r--r--arch/ia64/mm/discontig.c6
-rw-r--r--arch/ia64/mm/init.c18
-rw-r--r--arch/m68k/include/asm/bitops.h3
-rw-r--r--arch/mips/Kconfig23
-rw-r--r--arch/mips/Makefile8
-rw-r--r--arch/mips/bcm47xx/Platform1
-rw-r--r--arch/mips/boot/compressed/Makefile6
-rw-r--r--arch/mips/boot/dts/ingenic/Makefile1
-rw-r--r--arch/mips/boot/dts/ingenic/gcw0.dts62
-rw-r--r--arch/mips/boot/dts/ingenic/jz4770.dtsi212
-rw-r--r--arch/mips/configs/bigsur_defconfig1
-rw-r--r--arch/mips/configs/gcw0_defconfig27
-rw-r--r--arch/mips/configs/generic/board-ranchu.config30
-rw-r--r--arch/mips/configs/ip27_defconfig1
-rw-r--r--arch/mips/configs/ip32_defconfig1
-rw-r--r--arch/mips/configs/malta_defconfig5
-rw-r--r--arch/mips/configs/malta_kvm_defconfig4
-rw-r--r--arch/mips/configs/malta_kvm_guest_defconfig4
-rw-r--r--arch/mips/configs/malta_qemu_32r6_defconfig1
-rw-r--r--arch/mips/configs/maltaaprp_defconfig1
-rw-r--r--arch/mips/configs/maltasmvp_defconfig1
-rw-r--r--arch/mips/configs/maltasmvp_eva_defconfig1
-rw-r--r--arch/mips/configs/maltaup_defconfig1
-rw-r--r--arch/mips/configs/maltaup_xpa_defconfig5
-rw-r--r--arch/mips/configs/nlm_xlp_defconfig1
-rw-r--r--arch/mips/configs/nlm_xlr_defconfig1
-rw-r--r--arch/mips/configs/pnx8335_stb225_defconfig1
-rw-r--r--arch/mips/configs/sb1250_swarm_defconfig1
-rw-r--r--arch/mips/generic/Kconfig10
-rw-r--r--arch/mips/generic/Makefile1
-rw-r--r--arch/mips/generic/board-ranchu.c93
-rw-r--r--arch/mips/generic/irq.c18
-rw-r--r--arch/mips/include/asm/bootinfo.h2
-rw-r--r--arch/mips/include/asm/checksum.h2
-rw-r--r--arch/mips/include/asm/mach-loongson64/boot_param.h2
-rw-r--r--arch/mips/include/asm/machine.h2
-rw-r--r--arch/mips/include/asm/mipsregs.h702
-rw-r--r--arch/mips/include/asm/msa.h63
-rw-r--r--arch/mips/jazz/setup.c8
-rw-r--r--arch/mips/jz4740/Kconfig10
-rw-r--r--arch/mips/jz4740/prom.c25
-rw-r--r--arch/mips/jz4740/setup.c22
-rw-r--r--arch/mips/jz4740/time.c2
-rw-r--r--arch/mips/kernel/branch.c2
-rw-r--r--arch/mips/kernel/cps-vec.S17
-rw-r--r--arch/mips/kernel/ftrace.c2
-rw-r--r--arch/mips/kernel/setup.c39
-rw-r--r--arch/mips/kernel/smp-cps.c2
-rw-r--r--arch/mips/kernel/watch.c31
-rw-r--r--arch/mips/loongson64/Kconfig2
-rw-r--r--arch/mips/loongson64/common/mem.c2
-rw-r--r--arch/mips/loongson64/loongson-3/numa.c2
-rw-r--r--arch/mips/math-emu/cp1emu.c28
-rw-r--r--arch/mips/math-emu/dp_add.c3
-rw-r--r--arch/mips/math-emu/dp_div.c1
-rw-r--r--arch/mips/math-emu/dp_fmax.c2
-rw-r--r--arch/mips/math-emu/dp_fmin.c2
-rw-r--r--arch/mips/math-emu/dp_maddf.c8
-rw-r--r--arch/mips/math-emu/dp_mul.c4
-rw-r--r--arch/mips/math-emu/dp_sqrt.c8
-rw-r--r--arch/mips/math-emu/dp_sub.c2
-rw-r--r--arch/mips/math-emu/ieee754dp.h3
-rw-r--r--arch/mips/math-emu/sp_add.c3
-rw-r--r--arch/mips/math-emu/sp_div.c1
-rw-r--r--arch/mips/math-emu/sp_fdp.c3
-rw-r--r--arch/mips/math-emu/sp_fmax.c2
-rw-r--r--arch/mips/math-emu/sp_fmin.c2
-rw-r--r--arch/mips/math-emu/sp_maddf.c3
-rw-r--r--arch/mips/math-emu/sp_mul.c1
-rw-r--r--arch/mips/math-emu/sp_sqrt.c3
-rw-r--r--arch/mips/math-emu/sp_sub.c1
-rw-r--r--arch/mips/math-emu/sp_tlong.c1
-rw-r--r--arch/mips/mm/dma-default.c6
-rw-r--r--arch/mips/mm/sc-mips.c9
-rw-r--r--arch/mips/mti-malta/malta-setup.c10
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c4
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/include/asm/membarrier.h27
-rw-r--r--arch/powerpc/kernel/eeh.c6
-rw-r--r--arch/powerpc/kernel/pci-common.c10
-rw-r--r--arch/powerpc/kernel/pci-hotplug.c20
-rw-r--r--arch/powerpc/kernel/pci_32.c3
-rw-r--r--arch/powerpc/kernel/pci_of_scan.c7
-rw-r--r--arch/powerpc/mm/init_64.c17
-rw-r--r--arch/powerpc/mm/mem.c11
-rw-r--r--arch/powerpc/mm/mmu_context.c7
-rw-r--r--arch/powerpc/platforms/maple/time.c2
-rw-r--r--arch/powerpc/platforms/powermac/feature.c2
-rw-r--r--arch/powerpc/sysdev/i8259.c6
-rw-r--r--arch/powerpc/sysdev/mv64x60_pci.c4
-rw-r--r--arch/riscv/Kconfig10
-rw-r--r--arch/riscv/include/asm/Kbuild1
-rw-r--r--arch/riscv/include/asm/csr.h14
-rw-r--r--arch/riscv/include/asm/ftrace.h10
-rw-r--r--arch/riscv/include/asm/mmu_context.h17
-rw-r--r--arch/riscv/include/asm/tlbflush.h20
-rw-r--r--arch/riscv/include/asm/unistd.h1
-rw-r--r--arch/riscv/kernel/Makefile7
-rw-r--r--arch/riscv/kernel/entry.S9
-rw-r--r--arch/riscv/kernel/ftrace.c41
-rw-r--r--arch/riscv/kernel/head.S6
-rw-r--r--arch/riscv/kernel/mcount.S126
-rw-r--r--arch/riscv/kernel/setup.c44
-rw-r--r--arch/riscv/kernel/vdso.c2
-rw-r--r--arch/riscv/mm/fault.c4
-rw-r--r--arch/riscv/mm/init.c12
-rw-r--r--arch/s390/mm/init.c7
-rw-r--r--arch/s390/mm/vmem.c6
-rw-r--r--arch/score/kernel/setup.c4
-rw-r--r--arch/sh/mm/init.c10
-rw-r--r--arch/sparc/mm/init_64.c5
-rw-r--r--arch/unicore32/include/asm/bitops.h2
-rw-r--r--arch/x86/Kconfig4
-rw-r--r--arch/x86/entry/entry_32.S5
-rw-r--r--arch/x86/entry/entry_64.S4
-rw-r--r--arch/x86/events/perf_event.h3
-rw-r--r--arch/x86/include/asm/intel-family.h6
-rw-r--r--arch/x86/include/asm/intel_pmc_ipc.h6
-rw-r--r--arch/x86/include/asm/kasan.h12
-rw-r--r--arch/x86/include/asm/pmc_core.h27
-rw-r--r--arch/x86/include/asm/sync_core.h28
-rw-r--r--arch/x86/mm/init_32.c9
-rw-r--r--arch/x86/mm/init_64.c94
-rw-r--r--arch/x86/mm/tlb.c6
-rw-r--r--arch/x86/pci/irq.c3
-rw-r--r--arch/x86/pci/xen.c4
-rw-r--r--drivers/Makefile5
-rw-r--r--drivers/acpi/acpi_lpit.c1
-rw-r--r--drivers/acpi/nfit/core.c26
-rw-r--r--drivers/acpi/nfit/nfit.h1
-rw-r--r--drivers/ata/pata_ali.c3
-rw-r--r--drivers/block/DAC960.c38
-rw-r--r--drivers/block/DAC960.h4
-rw-r--r--drivers/char/agp/nvidia-agp.c12
-rw-r--r--drivers/char/agp/sworks-agp.c3
-rw-r--r--drivers/clk/ingenic/Makefile1
-rw-r--r--drivers/clk/ingenic/cgu.c94
-rw-r--r--drivers/clk/ingenic/cgu.h4
-rw-r--r--drivers/clk/ingenic/jz4770-cgu.c483
-rw-r--r--drivers/clk/ingenic/jz4780-cgu.c2
-rw-r--r--drivers/dax/device.c2
-rw-r--r--drivers/dax/pmem.c20
-rw-r--r--drivers/dax/super.c10
-rw-r--r--drivers/firmware/edd.c8
-rw-r--r--drivers/firmware/iscsi_ibft.c5
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c16
-rw-r--r--drivers/gpu/drm/gma500/gma_device.c4
-rw-r--r--drivers/gpu/drm/gma500/mid_bios.c12
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c10
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h18
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/arb.c4
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/hw.c10
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c10
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_lvds.c1
-rw-r--r--drivers/ide/sl82c105.c5
-rw-r--r--drivers/infiniband/Kconfig7
-rw-r--r--drivers/infiniband/core/nldev.c4
-rw-r--r--drivers/infiniband/core/uverbs_std_types.c2
-rw-r--r--drivers/infiniband/hw/bnxt_re/ib_verbs.c7
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_fp.c4
-rw-r--r--drivers/infiniband/hw/bnxt_re/qplib_res.c18
-rw-r--r--drivers/infiniband/hw/hfi1/chip.c82
-rw-r--r--drivers/infiniband/hw/hfi1/chip.h4
-rw-r--r--drivers/infiniband/hw/hfi1/debugfs.c9
-rw-r--r--drivers/infiniband/hw/hfi1/driver.c51
-rw-r--r--drivers/infiniband/hw/hfi1/file_ops.c4
-rw-r--r--drivers/infiniband/hw/hfi1/hfi.h26
-rw-r--r--drivers/infiniband/hw/hfi1/init.c31
-rw-r--r--drivers/infiniband/hw/hfi1/iowait.h9
-rw-r--r--drivers/infiniband/hw/hfi1/mad.c127
-rw-r--r--drivers/infiniband/hw/hfi1/mad.h47
-rw-r--r--drivers/infiniband/hw/hfi1/pcie.c23
-rw-r--r--drivers/infiniband/hw/hfi1/pio.c15
-rw-r--r--drivers/infiniband/hw/hfi1/qp.c4
-rw-r--r--drivers/infiniband/hw/hfi1/qp.h13
-rw-r--r--drivers/infiniband/hw/hfi1/rc.c51
-rw-r--r--drivers/infiniband/hw/hfi1/ruc.c47
-rw-r--r--drivers/infiniband/hw/hfi1/sdma.c16
-rw-r--r--drivers/infiniband/hw/hfi1/sdma.h1
-rw-r--r--drivers/infiniband/hw/hfi1/trace.c8
-rw-r--r--drivers/infiniband/hw/hfi1/trace_ibhdrs.h16
-rw-r--r--drivers/infiniband/hw/hfi1/trace_rx.h30
-rw-r--r--drivers/infiniband/hw/hfi1/uc.c9
-rw-r--r--drivers/infiniband/hw/hfi1/ud.c39
-rw-r--r--drivers/infiniband/hw/hfi1/verbs.c10
-rw-r--r--drivers/infiniband/hw/hfi1/verbs.h24
-rw-r--r--drivers/infiniband/hw/hfi1/verbs_txreq.h7
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_common.h6
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_device.h10
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v1.c60
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v1.h258
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v2.c58
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_hw_v2.h283
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_main.c3
-rw-r--r--drivers/infiniband/hw/hns/hns_roce_qp.c18
-rw-r--r--drivers/infiniband/hw/qedr/main.c59
-rw-r--r--drivers/infiniband/hw/qib/qib_rc.c3
-rw-r--r--drivers/infiniband/hw/qib/qib_uc.c3
-rw-r--r--drivers/infiniband/hw/qib/qib_ud.c3
-rw-r--r--drivers/infiniband/sw/rxe/rxe_av.c14
-rw-r--r--drivers/infiniband/sw/rxe/rxe_loc.h10
-rw-r--r--drivers/infiniband/sw/rxe/rxe_qp.c15
-rw-r--r--drivers/infiniband/sw/rxe/rxe_verbs.c10
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c3
-rw-r--r--drivers/iommu/amd_iommu.c3
-rw-r--r--drivers/iommu/amd_iommu_init.c9
-rw-r--r--drivers/iommu/amd_iommu_v2.c3
-rw-r--r--drivers/irqchip/irq-i8259.c4
-rw-r--r--drivers/macintosh/via-pmu.c2
-rw-r--r--drivers/media/Kconfig20
-rw-r--r--drivers/media/cec/cec-adap.c81
-rw-r--r--drivers/media/cec/cec-api.c32
-rw-r--r--drivers/media/cec/cec-core.c27
-rw-r--r--drivers/media/cec/cec-priv.h2
-rw-r--r--drivers/media/common/Kconfig1
-rw-r--r--drivers/media/common/Makefile2
-rw-r--r--drivers/media/common/b2c2/Makefile1
-rw-r--r--drivers/media/common/b2c2/flexcop-common.h8
-rw-r--r--drivers/media/common/saa7146/saa7146_video.c17
-rw-r--r--drivers/media/common/siano/Makefile4
-rw-r--r--drivers/media/common/siano/smsdvb-debugfs.c29
-rw-r--r--drivers/media/common/siano/smsdvb-main.c10
-rw-r--r--drivers/media/common/siano/smsir.c35
-rw-r--r--drivers/media/common/siano/smsir.h37
-rw-r--r--drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c8
-rw-r--r--drivers/media/common/v4l2-tpg/v4l2-tpg-core.c2
-rw-r--r--drivers/media/common/videobuf2/Kconfig31
-rw-r--r--drivers/media/common/videobuf2/Makefile7
-rw-r--r--drivers/media/common/videobuf2/videobuf2-core.c (renamed from drivers/media/v4l2-core/videobuf2-core.c)53
-rw-r--r--drivers/media/common/videobuf2/videobuf2-dma-contig.c (renamed from drivers/media/v4l2-core/videobuf2-dma-contig.c)6
-rw-r--r--drivers/media/common/videobuf2/videobuf2-dma-sg.c (renamed from drivers/media/v4l2-core/videobuf2-dma-sg.c)7
-rw-r--r--drivers/media/common/videobuf2/videobuf2-dvb.c (renamed from drivers/media/v4l2-core/videobuf2-dvb.c)0
-rw-r--r--drivers/media/common/videobuf2/videobuf2-memops.c (renamed from drivers/media/v4l2-core/videobuf2-memops.c)0
-rw-r--r--drivers/media/common/videobuf2/videobuf2-v4l2.c (renamed from drivers/media/v4l2-core/videobuf2-v4l2.c)2
-rw-r--r--drivers/media/common/videobuf2/videobuf2-vmalloc.c (renamed from drivers/media/v4l2-core/videobuf2-vmalloc.c)0
-rw-r--r--drivers/media/dvb-core/Kconfig13
-rw-r--r--drivers/media/dvb-core/Makefile7
-rw-r--r--drivers/media/dvb-core/dmxdev.c232
-rw-r--r--drivers/media/dvb-core/dvb_ca_en50221.c9
-rw-r--r--drivers/media/dvb-core/dvb_demux.c47
-rw-r--r--drivers/media/dvb-core/dvb_frontend.c183
-rw-r--r--drivers/media/dvb-core/dvb_math.c2
-rw-r--r--drivers/media/dvb-core/dvb_net.c74
-rw-r--r--drivers/media/dvb-core/dvb_ringbuffer.c2
-rw-r--r--drivers/media/dvb-core/dvb_vb2.c430
-rw-r--r--drivers/media/dvb-core/dvbdev.c2
-rw-r--r--drivers/media/dvb-frontends/Makefile1
-rw-r--r--drivers/media/dvb-frontends/a8293.h2
-rw-r--r--drivers/media/dvb-frontends/af9013_priv.h2
-rw-r--r--drivers/media/dvb-frontends/af9033_priv.h4
-rw-r--r--drivers/media/dvb-frontends/as102_fe.c2
-rw-r--r--drivers/media/dvb-frontends/ascot2e.c6
-rw-r--r--drivers/media/dvb-frontends/atbm8830.c2
-rw-r--r--drivers/media/dvb-frontends/au8522_common.c2
-rw-r--r--drivers/media/dvb-frontends/au8522_dig.c2
-rw-r--r--drivers/media/dvb-frontends/au8522_priv.h220
-rw-r--r--drivers/media/dvb-frontends/bcm3510.c2
-rw-r--r--drivers/media/dvb-frontends/cx22700.c2
-rw-r--r--drivers/media/dvb-frontends/cx22702.c2
-rw-r--r--drivers/media/dvb-frontends/cx24110.c2
-rw-r--r--drivers/media/dvb-frontends/cx24113.c2
-rw-r--r--drivers/media/dvb-frontends/cx24116.c4
-rw-r--r--drivers/media/dvb-frontends/cx24117.c2
-rw-r--r--drivers/media/dvb-frontends/cx24120.c2
-rw-r--r--drivers/media/dvb-frontends/cx24123.c2
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_priv.h4
-rw-r--r--drivers/media/dvb-frontends/cxd2841er.c23
-rw-r--r--drivers/media/dvb-frontends/dib0070.c2
-rw-r--r--drivers/media/dvb-frontends/dib0090.c2
-rw-r--r--drivers/media/dvb-frontends/dib3000mb.c2
-rw-r--r--drivers/media/dvb-frontends/dib3000mc.c2
-rw-r--r--drivers/media/dvb-frontends/dib7000m.c2
-rw-r--r--drivers/media/dvb-frontends/dib7000p.c4
-rw-r--r--drivers/media/dvb-frontends/dib8000.c4
-rw-r--r--drivers/media/dvb-frontends/dib9000.c4
-rw-r--r--drivers/media/dvb-frontends/dibx000_common.c8
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/Makefile1
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drx39xxj.h2
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drx_driver.h2
-rw-r--r--drivers/media/dvb-frontends/drx39xyj/drxj.c16
-rw-r--r--drivers/media/dvb-frontends/drxd_hard.c27
-rw-r--r--drivers/media/dvb-frontends/drxk.h6
-rw-r--r--drivers/media/dvb-frontends/drxk_hard.c6
-rw-r--r--drivers/media/dvb-frontends/ds3000.c2
-rw-r--r--drivers/media/dvb-frontends/dvb-pll.h2
-rw-r--r--drivers/media/dvb-frontends/dvb_dummy_fe.c2
-rw-r--r--drivers/media/dvb-frontends/dvb_dummy_fe.h2
-rw-r--r--drivers/media/dvb-frontends/ec100.c2
-rw-r--r--drivers/media/dvb-frontends/gp8psk-fe.c2
-rw-r--r--drivers/media/dvb-frontends/helene.c6
-rw-r--r--drivers/media/dvb-frontends/horus3a.c6
-rw-r--r--drivers/media/dvb-frontends/isl6405.c2
-rw-r--r--drivers/media/dvb-frontends/isl6421.c2
-rw-r--r--drivers/media/dvb-frontends/isl6423.c2
-rw-r--r--drivers/media/dvb-frontends/itd1000.c7
-rw-r--r--drivers/media/dvb-frontends/ix2505v.h2
-rw-r--r--drivers/media/dvb-frontends/l64781.c2
-rw-r--r--drivers/media/dvb-frontends/lg2160.h2
-rw-r--r--drivers/media/dvb-frontends/lgdt3305.c2
-rw-r--r--drivers/media/dvb-frontends/lgdt3305.h2
-rw-r--r--drivers/media/dvb-frontends/lgdt3306a.c2
-rw-r--r--drivers/media/dvb-frontends/lgdt3306a.h2
-rw-r--r--drivers/media/dvb-frontends/lgdt330x.c4
-rw-r--r--drivers/media/dvb-frontends/lgs8gl5.c2
-rw-r--r--drivers/media/dvb-frontends/lgs8gxx.c2
-rw-r--r--drivers/media/dvb-frontends/lnbh25.c2
-rw-r--r--drivers/media/dvb-frontends/lnbp21.c2
-rw-r--r--drivers/media/dvb-frontends/lnbp22.c2
-rw-r--r--drivers/media/dvb-frontends/m88ds3103_priv.h4
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.c13
-rw-r--r--drivers/media/dvb-frontends/m88rs2000.h2
-rw-r--r--drivers/media/dvb-frontends/mb86a16.c15
-rw-r--r--drivers/media/dvb-frontends/mb86a16.h2
-rw-r--r--drivers/media/dvb-frontends/mb86a20s.c4
-rw-r--r--drivers/media/dvb-frontends/mn88472_priv.h4
-rw-r--r--drivers/media/dvb-frontends/mn88473.c2
-rw-r--r--drivers/media/dvb-frontends/mn88473_priv.h4
-rw-r--r--drivers/media/dvb-frontends/mt312.c7
-rw-r--r--drivers/media/dvb-frontends/mt352.c2
-rw-r--r--drivers/media/dvb-frontends/mxl5xx.c11
-rw-r--r--drivers/media/dvb-frontends/mxl5xx.h2
-rw-r--r--drivers/media/dvb-frontends/nxt200x.c2
-rw-r--r--drivers/media/dvb-frontends/nxt6000.c2
-rw-r--r--drivers/media/dvb-frontends/or51132.c4
-rw-r--r--drivers/media/dvb-frontends/or51211.c4
-rw-r--r--drivers/media/dvb-frontends/rtl2830_priv.h4
-rw-r--r--drivers/media/dvb-frontends/rtl2832_priv.h4
-rw-r--r--drivers/media/dvb-frontends/rtl2832_sdr.h2
-rw-r--r--drivers/media/dvb-frontends/s5h1409.c2
-rw-r--r--drivers/media/dvb-frontends/s5h1411.c2
-rw-r--r--drivers/media/dvb-frontends/s5h1420.c2
-rw-r--r--drivers/media/dvb-frontends/s5h1432.c2
-rw-r--r--drivers/media/dvb-frontends/s921.c2
-rw-r--r--drivers/media/dvb-frontends/si2165.c613
-rw-r--r--drivers/media/dvb-frontends/si2165.h37
-rw-r--r--drivers/media/dvb-frontends/si2165_priv.h114
-rw-r--r--drivers/media/dvb-frontends/si2168.c3
-rw-r--r--drivers/media/dvb-frontends/si2168_priv.h2
-rw-r--r--drivers/media/dvb-frontends/si21xx.c2
-rw-r--r--drivers/media/dvb-frontends/si21xx.h2
-rw-r--r--drivers/media/dvb-frontends/sp2.h2
-rw-r--r--drivers/media/dvb-frontends/sp2_priv.h2
-rw-r--r--drivers/media/dvb-frontends/sp8870.c2
-rw-r--r--drivers/media/dvb-frontends/sp887x.c2
-rw-r--r--drivers/media/dvb-frontends/stb0899_algo.c3
-rw-r--r--drivers/media/dvb-frontends/stb0899_drv.c15
-rw-r--r--drivers/media/dvb-frontends/stb0899_drv.h4
-rw-r--r--drivers/media/dvb-frontends/stb0899_priv.h4
-rw-r--r--drivers/media/dvb-frontends/stb6000.h2
-rw-r--r--drivers/media/dvb-frontends/stb6100.c8
-rw-r--r--drivers/media/dvb-frontends/stb6100.h2
-rw-r--r--drivers/media/dvb-frontends/stb6100_cfg.h2
-rw-r--r--drivers/media/dvb-frontends/stb6100_proc.h2
-rw-r--r--drivers/media/dvb-frontends/stv0288.c2
-rw-r--r--drivers/media/dvb-frontends/stv0288.h2
-rw-r--r--drivers/media/dvb-frontends/stv0297.c2
-rw-r--r--drivers/media/dvb-frontends/stv0297.h2
-rw-r--r--drivers/media/dvb-frontends/stv0299.c2
-rw-r--r--drivers/media/dvb-frontends/stv0299.h2
-rw-r--r--drivers/media/dvb-frontends/stv0367.c8
-rw-r--r--drivers/media/dvb-frontends/stv0367.h2
-rw-r--r--drivers/media/dvb-frontends/stv0900.h2
-rw-r--r--drivers/media/dvb-frontends/stv0900_core.c2
-rw-r--r--drivers/media/dvb-frontends/stv0900_init.h34
-rw-r--r--drivers/media/dvb-frontends/stv0900_priv.h2
-rw-r--r--drivers/media/dvb-frontends/stv090x.c43
-rw-r--r--drivers/media/dvb-frontends/stv090x_priv.h4
-rw-r--r--drivers/media/dvb-frontends/stv0910.c227
-rw-r--r--drivers/media/dvb-frontends/stv0910_regs.h1854
-rw-r--r--drivers/media/dvb-frontends/stv6110.h2
-rw-r--r--drivers/media/dvb-frontends/stv6110x.c8
-rw-r--r--drivers/media/dvb-frontends/stv6110x_priv.h6
-rw-r--r--drivers/media/dvb-frontends/stv6111.c46
-rw-r--r--drivers/media/dvb-frontends/tc90522.c2
-rw-r--r--drivers/media/dvb-frontends/tc90522.h2
-rw-r--r--drivers/media/dvb-frontends/tda10021.c2
-rw-r--r--drivers/media/dvb-frontends/tda10023.c4
-rw-r--r--drivers/media/dvb-frontends/tda10048.c4
-rw-r--r--drivers/media/dvb-frontends/tda1004x.c2
-rw-r--r--drivers/media/dvb-frontends/tda10071_priv.h2
-rw-r--r--drivers/media/dvb-frontends/tda10086.c2
-rw-r--r--drivers/media/dvb-frontends/tda18271c2dd.c3
-rw-r--r--drivers/media/dvb-frontends/tda18271c2dd.h4
-rw-r--r--drivers/media/dvb-frontends/tda665x.c2
-rw-r--r--drivers/media/dvb-frontends/tda8083.c2
-rw-r--r--drivers/media/dvb-frontends/tda8261.c2
-rw-r--r--drivers/media/dvb-frontends/tda826x.h2
-rw-r--r--drivers/media/dvb-frontends/ts2020.c6
-rw-r--r--drivers/media/dvb-frontends/tua6100.h2
-rw-r--r--drivers/media/dvb-frontends/ves1820.c2
-rw-r--r--drivers/media/dvb-frontends/ves1x93.c2
-rw-r--r--drivers/media/dvb-frontends/zd1301_demod.h2
-rw-r--r--drivers/media/dvb-frontends/zl10036.h2
-rw-r--r--drivers/media/dvb-frontends/zl10039.c6
-rw-r--r--drivers/media/dvb-frontends/zl10353.c2
-rw-r--r--drivers/media/firewire/Makefile2
-rw-r--r--drivers/media/firewire/firedtv-avc.c6
-rw-r--r--drivers/media/firewire/firedtv-ci.c2
-rw-r--r--drivers/media/firewire/firedtv-dvb.c8
-rw-r--r--drivers/media/firewire/firedtv-fe.c8
-rw-r--r--drivers/media/firewire/firedtv-fw.c2
-rw-r--r--drivers/media/firewire/firedtv.h12
-rw-r--r--drivers/media/i2c/Kconfig26
-rw-r--r--drivers/media/i2c/Makefile2
-rw-r--r--drivers/media/i2c/adv7180.c12
-rw-r--r--drivers/media/i2c/adv7343.c2
-rw-r--r--drivers/media/i2c/adv7393.c2
-rw-r--r--drivers/media/i2c/adv748x/adv748x-afe.c1
-rw-r--r--drivers/media/i2c/adv748x/adv748x-core.c16
-rw-r--r--drivers/media/i2c/adv748x/adv748x-csi2.c13
-rw-r--r--drivers/media/i2c/adv748x/adv748x.h1
-rw-r--r--drivers/media/i2c/adv7604.c1
-rw-r--r--drivers/media/i2c/as3645a.c880
-rw-r--r--drivers/media/i2c/cx25840/Makefile2
-rw-r--r--drivers/media/i2c/cx25840/cx25840-core.c35
-rw-r--r--drivers/media/i2c/cx25840/cx25840-core.h2
-rw-r--r--drivers/media/i2c/cx25840/cx25840-ir.c6
-rw-r--r--drivers/media/i2c/dw9714.c22
-rw-r--r--drivers/media/i2c/imx274.c4
-rw-r--r--drivers/media/i2c/ir-kbd-i2c.c540
-rw-r--r--drivers/media/i2c/ks0127.c2
-rw-r--r--drivers/media/i2c/mt9m111.c49
-rw-r--r--drivers/media/i2c/mt9v011.c13
-rw-r--r--drivers/media/i2c/mt9v032.c21
-rw-r--r--drivers/media/i2c/ov2640.c4
-rw-r--r--drivers/media/i2c/ov2659.c4
-rw-r--r--drivers/media/i2c/ov5640.c326
-rw-r--r--drivers/media/i2c/ov7670.c90
-rw-r--r--drivers/media/i2c/ov7740.c1214
-rw-r--r--drivers/media/i2c/ov9650.c10
-rw-r--r--drivers/media/i2c/saa6752hs.c8
-rw-r--r--drivers/media/i2c/saa7115.c60
-rw-r--r--drivers/media/i2c/saa711x_regs.h14
-rw-r--r--drivers/media/i2c/saa7127.c162
-rw-r--r--drivers/media/i2c/saa717x.c12
-rw-r--r--drivers/media/i2c/smiapp/smiapp-core.c2
-rw-r--r--drivers/media/i2c/tda7432.c1
-rw-r--r--drivers/media/i2c/ths7303.c2
-rw-r--r--drivers/media/i2c/tvaudio.c4
-rw-r--r--drivers/media/i2c/tvp514x.c4
-rw-r--r--drivers/media/i2c/tvp5150.c13
-rw-r--r--drivers/media/i2c/tvp5150_reg.h9
-rw-r--r--drivers/media/i2c/tvp7002_reg.h6
-rw-r--r--drivers/media/i2c/vpx3220.c2
-rw-r--r--drivers/media/mmc/siano/Makefile2
-rw-r--r--drivers/media/pci/Kconfig2
-rw-r--r--drivers/media/pci/Makefile3
-rw-r--r--drivers/media/pci/b2c2/Makefile1
-rw-r--r--drivers/media/pci/bt8xx/Makefile2
-rw-r--r--drivers/media/pci/bt8xx/bt878.c7
-rw-r--r--drivers/media/pci/bt8xx/bttv-cards.c273
-rw-r--r--drivers/media/pci/bt8xx/bttv-input.c8
-rw-r--r--drivers/media/pci/bt8xx/bttv.h5
-rw-r--r--drivers/media/pci/bt8xx/bttvp.h6
-rw-r--r--drivers/media/pci/bt8xx/dst.c2
-rw-r--r--drivers/media/pci/bt8xx/dst_ca.c4
-rw-r--r--drivers/media/pci/bt8xx/dvb-bt8xx.c8
-rw-r--r--drivers/media/pci/bt8xx/dvb-bt8xx.h4
-rw-r--r--drivers/media/pci/cobalt/Kconfig1
-rw-r--r--drivers/media/pci/cx18/Makefile1
-rw-r--r--drivers/media/pci/cx18/cx18-alsa-pcm.c2
-rw-r--r--drivers/media/pci/cx18/cx18-av-audio.c2
-rw-r--r--drivers/media/pci/cx18/cx18-av-core.c18
-rw-r--r--drivers/media/pci/cx18/cx18-av-core.h2
-rw-r--r--drivers/media/pci/cx18/cx18-cards.c8
-rw-r--r--drivers/media/pci/cx18/cx18-cards.h40
-rw-r--r--drivers/media/pci/cx18/cx18-driver.h58
-rw-r--r--drivers/media/pci/cx18/cx18-fileops.c2
-rw-r--r--drivers/media/pci/cx18/cx18-firmware.c96
-rw-r--r--drivers/media/pci/cx18/cx18-i2c.c13
-rw-r--r--drivers/media/pci/cx18/cx18-mailbox.c8
-rw-r--r--drivers/media/pci/cx18/cx18-streams.c4
-rw-r--r--drivers/media/pci/cx18/cx18-vbi.c2
-rw-r--r--drivers/media/pci/cx18/cx23418.h88
-rw-r--r--drivers/media/pci/cx23885/Makefile2
-rw-r--r--drivers/media/pci/cx23885/altera-ci.c6
-rw-r--r--drivers/media/pci/cx23885/cimax2.c4
-rw-r--r--drivers/media/pci/cx23885/cimax2.h2
-rw-r--r--drivers/media/pci/cx23885/cx23885-cards.c6
-rw-r--r--drivers/media/pci/cx23885/cx23885-dvb.c6
-rw-r--r--drivers/media/pci/cx23885/cx23885-input.c15
-rw-r--r--drivers/media/pci/cx23885/cx23885-video.c2
-rw-r--r--drivers/media/pci/cx23885/cx23885.h4
-rw-r--r--drivers/media/pci/cx23885/cx23888-ir.c6
-rw-r--r--drivers/media/pci/cx25821/Makefile2
-rw-r--r--drivers/media/pci/cx25821/cx25821-alsa.c4
-rw-r--r--drivers/media/pci/cx88/Makefile3
-rw-r--r--drivers/media/pci/cx88/cx88-blackbird.c3
-rw-r--r--drivers/media/pci/cx88/cx88-video.c10
-rw-r--r--drivers/media/pci/cx88/cx88.h4
-rw-r--r--drivers/media/pci/ddbridge/Makefile5
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-ci.c359
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-ci.h31
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-core.c651
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-hw.c8
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-i2c.c16
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-main.c23
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-max.c (renamed from drivers/media/pci/ddbridge/ddbridge-maxs8.c)54
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-max.h (renamed from drivers/media/pci/ddbridge/ddbridge-maxs8.h)12
-rw-r--r--drivers/media/pci/ddbridge/ddbridge-regs.h32
-rw-r--r--drivers/media/pci/ddbridge/ddbridge.h105
-rw-r--r--drivers/media/pci/dm1105/Makefile2
-rw-r--r--drivers/media/pci/dm1105/dm1105.c12
-rw-r--r--drivers/media/pci/intel/Makefile5
-rw-r--r--drivers/media/pci/intel/ipu3/Kconfig19
-rw-r--r--drivers/media/pci/intel/ipu3/Makefile1
-rw-r--r--drivers/media/pci/intel/ipu3/ipu3-cio2.c2048
-rw-r--r--drivers/media/pci/intel/ipu3/ipu3-cio2.h449
-rw-r--r--drivers/media/pci/ivtv/Makefile2
-rw-r--r--drivers/media/pci/ivtv/ivtv-cards.c2
-rw-r--r--drivers/media/pci/ivtv/ivtv-cards.h148
-rw-r--r--drivers/media/pci/ivtv/ivtv-driver.h102
-rw-r--r--drivers/media/pci/ivtv/ivtv-firmware.c36
-rw-r--r--drivers/media/pci/ivtv/ivtv-i2c.c46
-rw-r--r--drivers/media/pci/ivtv/ivtv-ioctl.c74
-rw-r--r--drivers/media/pci/ivtv/ivtv-mailbox.c182
-rw-r--r--drivers/media/pci/mantis/Makefile2
-rw-r--r--drivers/media/pci/mantis/hopper_cards.c10
-rw-r--r--drivers/media/pci/mantis/hopper_vp3028.c10
-rw-r--r--drivers/media/pci/mantis/mantis_ca.c10
-rw-r--r--drivers/media/pci/mantis/mantis_cards.c10
-rw-r--r--drivers/media/pci/mantis/mantis_dma.c10
-rw-r--r--drivers/media/pci/mantis/mantis_dvb.c10
-rw-r--r--drivers/media/pci/mantis/mantis_evm.c10
-rw-r--r--drivers/media/pci/mantis/mantis_hif.c10
-rw-r--r--drivers/media/pci/mantis/mantis_i2c.c10
-rw-r--r--drivers/media/pci/mantis/mantis_input.c10
-rw-r--r--drivers/media/pci/mantis/mantis_ioc.c10
-rw-r--r--drivers/media/pci/mantis/mantis_link.h2
-rw-r--r--drivers/media/pci/mantis/mantis_pci.c10
-rw-r--r--drivers/media/pci/mantis/mantis_pcmcia.c10
-rw-r--r--drivers/media/pci/mantis/mantis_reg.h6
-rw-r--r--drivers/media/pci/mantis/mantis_uart.c10
-rw-r--r--drivers/media/pci/mantis/mantis_vp1033.c10
-rw-r--r--drivers/media/pci/mantis/mantis_vp1034.c10
-rw-r--r--drivers/media/pci/mantis/mantis_vp1034.h2
-rw-r--r--drivers/media/pci/mantis/mantis_vp1041.c220
-rw-r--r--drivers/media/pci/mantis/mantis_vp2033.c10
-rw-r--r--drivers/media/pci/mantis/mantis_vp2040.c10
-rw-r--r--drivers/media/pci/mantis/mantis_vp3028.h2
-rw-r--r--drivers/media/pci/mantis/mantis_vp3030.c10
-rw-r--r--drivers/media/pci/meye/meye.c2
-rw-r--r--drivers/media/pci/netup_unidvb/Makefile1
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb.h2
-rw-r--r--drivers/media/pci/netup_unidvb/netup_unidvb_core.c2
-rw-r--r--drivers/media/pci/ngene/Makefile1
-rw-r--r--drivers/media/pci/ngene/ngene.h14
-rw-r--r--drivers/media/pci/pluto2/Makefile2
-rw-r--r--drivers/media/pci/pluto2/pluto2.c14
-rw-r--r--drivers/media/pci/pt1/Makefile2
-rw-r--r--drivers/media/pci/pt1/pt1.c29
-rw-r--r--drivers/media/pci/pt1/va1j5jf8007s.c4
-rw-r--r--drivers/media/pci/pt1/va1j5jf8007s.h2
-rw-r--r--drivers/media/pci/pt1/va1j5jf8007t.c6
-rw-r--r--drivers/media/pci/pt1/va1j5jf8007t.h2
-rw-r--r--drivers/media/pci/pt3/Makefile1
-rw-r--r--drivers/media/pci/pt3/pt3.c8
-rw-r--r--drivers/media/pci/pt3/pt3.h6
-rw-r--r--drivers/media/pci/pt3/pt3_i2c.c1
-rw-r--r--drivers/media/pci/saa7134/Makefile2
-rw-r--r--drivers/media/pci/saa7134/saa7134-cards.c64
-rw-r--r--drivers/media/pci/saa7134/saa7134-dvb.c6
-rw-r--r--drivers/media/pci/saa7134/saa7134-input.c3
-rw-r--r--drivers/media/pci/saa7134/saa7134-video.c6
-rw-r--r--drivers/media/pci/saa7134/saa7134.h8
-rw-r--r--drivers/media/pci/saa7146/hexium_gemini.c25
-rw-r--r--drivers/media/pci/saa7146/hexium_orion.c21
-rw-r--r--drivers/media/pci/saa7146/mxb.c29
-rw-r--r--drivers/media/pci/saa7164/Makefile4
-rw-r--r--drivers/media/pci/saa7164/saa7164.h10
-rw-r--r--drivers/media/pci/smipcie/Makefile1
-rw-r--r--drivers/media/pci/smipcie/smipcie.h12
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-core.c17
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-gpio.c2
-rw-r--r--drivers/media/pci/ttpci/Makefile2
-rw-r--r--drivers/media/pci/ttpci/av7110.c2
-rw-r--r--drivers/media/pci/ttpci/av7110.h16
-rw-r--r--drivers/media/pci/ttpci/budget-av.c8
-rw-r--r--drivers/media/pci/ttpci/budget-ci.c212
-rw-r--r--drivers/media/pci/ttpci/budget.h12
-rw-r--r--drivers/media/pci/ttpci/dvb_filter.h2
-rw-r--r--drivers/media/pci/tw5864/tw5864-video.c2
-rw-r--r--drivers/media/pci/zoran/videocodec.c1
-rw-r--r--drivers/media/pci/zoran/zoran_driver.c38
-rw-r--r--drivers/media/pci/zoran/zr36057.h4
-rw-r--r--drivers/media/platform/Kconfig38
-rw-r--r--drivers/media/platform/Makefile16
-rw-r--r--drivers/media/platform/am437x/am437x-vpfe.c6
-rw-r--r--drivers/media/platform/arv.c54
-rw-r--r--drivers/media/platform/atmel/atmel-isc.c6
-rw-r--r--drivers/media/platform/atmel/atmel-isi.c2
-rw-r--r--drivers/media/platform/blackfin/ppi.c2
-rw-r--r--drivers/media/platform/coda/coda-bit.c23
-rw-r--r--drivers/media/platform/coda/coda-common.c13
-rw-r--r--drivers/media/platform/coda/coda_regs.h3
-rw-r--r--drivers/media/platform/coda/imx-vdoa.c8
-rw-r--r--drivers/media/platform/davinci/dm355_ccdc.c4
-rw-r--r--drivers/media/platform/davinci/dm355_ccdc_regs.h6
-rw-r--r--drivers/media/platform/davinci/dm644x_ccdc.c6
-rw-r--r--drivers/media/platform/davinci/dm644x_ccdc_regs.h4
-rw-r--r--drivers/media/platform/davinci/isif_regs.h6
-rw-r--r--drivers/media/platform/davinci/vpfe_capture.c8
-rw-r--r--drivers/media/platform/davinci/vpif.h4
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c10
-rw-r--r--drivers/media/platform/davinci/vpss.c10
-rw-r--r--drivers/media/platform/exynos-gsc/gsc-m2m.c4
-rw-r--r--drivers/media/platform/exynos4-is/Kconfig2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-core.c4
-rw-r--r--drivers/media/platform/exynos4-is/fimc-core.h2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp.c14
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.c7
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.h4
-rw-r--r--drivers/media/platform/exynos4-is/fimc-m2m.c10
-rw-r--r--drivers/media/platform/exynos4-is/media-dev.c4
-rw-r--r--drivers/media/platform/m2m-deinterlace.c12
-rw-r--r--drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c3
-rw-r--r--drivers/media/platform/mtk-vcodec/vdec_vpu_if.h2
-rw-r--r--drivers/media/platform/omap/omap_vout.c12
-rw-r--r--drivers/media/platform/omap3isp/isp.c2
-rw-r--r--drivers/media/platform/pxa_camera.c35
-rw-r--r--drivers/media/platform/qcom/camss-8x16/camss.c2
-rw-r--r--drivers/media/platform/qcom/venus/core.h4
-rw-r--r--drivers/media/platform/qcom/venus/hfi_cmds.c73
-rw-r--r--drivers/media/platform/qcom/venus/hfi_helper.h4
-rw-r--r--drivers/media/platform/qcom/venus/venc.c48
-rw-r--r--drivers/media/platform/qcom/venus/venc_ctrls.c59
-rw-r--r--drivers/media/platform/rcar-vin/rcar-core.c2
-rw-r--r--drivers/media/platform/rcar_drif.c4
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c2
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c6
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_common.h3
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c10
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc_enc.c2
-rw-r--r--drivers/media/platform/sh_vou.c2
-rw-r--r--drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c7
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c2
-rw-r--r--drivers/media/platform/soc_camera/soc_scale_crop.c4
-rw-r--r--drivers/media/platform/sti/bdisp/bdisp-debug.c2
-rw-r--r--drivers/media/platform/sti/bdisp/bdisp-filter.h2
-rw-r--r--drivers/media/platform/sti/bdisp/bdisp-hw.c4
-rw-r--r--drivers/media/platform/sti/bdisp/bdisp-reg.h2
-rw-r--r--drivers/media/platform/sti/bdisp/bdisp-v4l2.c2
-rw-r--r--drivers/media/platform/sti/bdisp/bdisp.h2
-rw-r--r--drivers/media/platform/sti/c8sectpfe/Kconfig2
-rw-r--r--drivers/media/platform/sti/c8sectpfe/Makefile5
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.c15
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h13
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c19
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.h5
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.c9
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.h9
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c11
-rw-r--r--drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.h5
-rw-r--r--drivers/media/platform/sti/cec/stih-cec.c5
-rw-r--r--drivers/media/platform/sti/delta/delta-cfg.h2
-rw-r--r--drivers/media/platform/sti/delta/delta-debug.c2
-rw-r--r--drivers/media/platform/sti/delta/delta-debug.h2
-rw-r--r--drivers/media/platform/sti/delta/delta-ipc.c2
-rw-r--r--drivers/media/platform/sti/delta/delta-ipc.h2
-rw-r--r--drivers/media/platform/sti/delta/delta-mem.c2
-rw-r--r--drivers/media/platform/sti/delta/delta-mem.h2
-rw-r--r--drivers/media/platform/sti/delta/delta-mjpeg-dec.c2
-rw-r--r--drivers/media/platform/sti/delta/delta-mjpeg-fw.h2
-rw-r--r--drivers/media/platform/sti/delta/delta-mjpeg-hdr.c2
-rw-r--r--drivers/media/platform/sti/delta/delta-mjpeg.h2
-rw-r--r--drivers/media/platform/sti/delta/delta-v4l2.c2
-rw-r--r--drivers/media/platform/sti/delta/delta.h2
-rw-r--r--drivers/media/platform/sti/hva/hva-debugfs.c2
-rw-r--r--drivers/media/platform/sti/hva/hva-h264.c2
-rw-r--r--drivers/media/platform/sti/hva/hva-hw.c2
-rw-r--r--drivers/media/platform/sti/hva/hva-hw.h2
-rw-r--r--drivers/media/platform/sti/hva/hva-mem.c2
-rw-r--r--drivers/media/platform/sti/hva/hva-mem.h2
-rw-r--r--drivers/media/platform/sti/hva/hva-v4l2.c2
-rw-r--r--drivers/media/platform/sti/hva/hva.h4
-rw-r--r--drivers/media/platform/stm32/stm32-dcmi.c2
-rw-r--r--drivers/media/platform/tegra-cec/tegra_cec.c5
-rw-r--r--drivers/media/platform/ti-vpe/cal.c5
-rw-r--r--drivers/media/platform/via-camera.h2
-rw-r--r--drivers/media/platform/vimc/vimc-common.h5
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c65
-rw-r--r--drivers/media/platform/vivid/vivid-core.c2
-rw-r--r--drivers/media/platform/vivid/vivid-core.h5
-rw-r--r--drivers/media/platform/vivid/vivid-ctrls.c35
-rw-r--r--drivers/media/platform/vivid/vivid-radio-rx.c11
-rw-r--r--drivers/media/platform/vivid/vivid-radio-tx.c8
-rw-r--r--drivers/media/platform/vivid/vivid-rds-gen.c2
-rw-r--r--drivers/media/platform/vivid/vivid-rds-gen.h1
-rw-r--r--drivers/media/platform/vivid/vivid-vbi-gen.c2
-rw-r--r--drivers/media/platform/vivid/vivid-vid-cap.c9
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c16
-rw-r--r--drivers/media/platform/xilinx/xilinx-vipp.c18
-rw-r--r--drivers/media/radio/radio-aimslab.c2
-rw-r--r--drivers/media/radio/radio-aztech.c2
-rw-r--r--drivers/media/radio/radio-cadet.c4
-rw-r--r--drivers/media/radio/radio-gemtek.c8
-rw-r--r--drivers/media/radio/radio-maxiradio.c2
-rw-r--r--drivers/media/radio/radio-mr800.c24
-rw-r--r--drivers/media/radio/radio-rtrack2.c2
-rw-r--r--drivers/media/radio/radio-sf16fmi.c4
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c2
-rw-r--r--drivers/media/radio/radio-si476x.c16
-rw-r--r--drivers/media/radio/radio-tea5764.c2
-rw-r--r--drivers/media/radio/radio-terratec.c6
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c24
-rw-r--r--drivers/media/radio/tea575x.c2
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.h10
-rw-r--r--drivers/media/rc/Kconfig35
-rw-r--r--drivers/media/rc/Makefile5
-rw-r--r--drivers/media/rc/iguanair.c19
-rw-r--r--drivers/media/rc/imon.c55
-rw-r--r--drivers/media/rc/ir-jvc-decoder.c1
-rw-r--r--drivers/media/rc/ir-lirc-codec.c448
-rw-r--r--drivers/media/rc/ir-mce_kbd-decoder.c18
-rw-r--r--drivers/media/rc/ir-nec-decoder.c20
-rw-r--r--drivers/media/rc/ir-rc5-decoder.c44
-rw-r--r--drivers/media/rc/ir-rc6-decoder.c32
-rw-r--r--drivers/media/rc/ir-sanyo-decoder.c38
-rw-r--r--drivers/media/rc/ir-sharp-decoder.c1
-rw-r--r--drivers/media/rc/ir-sony-decoder.c1
-rw-r--r--drivers/media/rc/ir-spi.c15
-rw-r--r--drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c17
-rw-r--r--drivers/media/rc/keymaps/rc-apac-viewcomp.c17
-rw-r--r--drivers/media/rc/keymaps/rc-asus-pc39.c17
-rw-r--r--drivers/media/rc/keymaps/rc-asus-ps3-100.c17
-rw-r--r--drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c17
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-a16d.c17
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-cardbus.c17
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-dvbt.c17
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-m135a.c15
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia.c17
-rw-r--r--drivers/media/rc/keymaps/rc-avertv-303.c17
-rw-r--r--drivers/media/rc/keymaps/rc-behold-columbus.c23
-rw-r--r--drivers/media/rc/keymaps/rc-behold.c17
-rw-r--r--drivers/media/rc/keymaps/rc-budget-ci-old.c17
-rw-r--r--drivers/media/rc/keymaps/rc-cinergy-1400.c17
-rw-r--r--drivers/media/rc/keymaps/rc-cinergy.c17
-rw-r--r--drivers/media/rc/keymaps/rc-dib0700-nec.c27
-rw-r--r--drivers/media/rc/keymaps/rc-dib0700-rc5.c27
-rw-r--r--drivers/media/rc/keymaps/rc-dm1105-nec.c17
-rw-r--r--drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c17
-rw-r--r--drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c17
-rw-r--r--drivers/media/rc/keymaps/rc-em-terratec.c17
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv-fm53.c17
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv.c17
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv2.c17
-rw-r--r--drivers/media/rc/keymaps/rc-evga-indtube.c17
-rw-r--r--drivers/media/rc/keymaps/rc-eztv.c17
-rw-r--r--drivers/media/rc/keymaps/rc-flydvb.c17
-rw-r--r--drivers/media/rc/keymaps/rc-flyvideo.c17
-rw-r--r--drivers/media/rc/keymaps/rc-fusionhdtv-mce.c17
-rw-r--r--drivers/media/rc/keymaps/rc-gadmei-rm008z.c17
-rw-r--r--drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c17
-rw-r--r--drivers/media/rc/keymaps/rc-gotview7135.c17
-rw-r--r--drivers/media/rc/keymaps/rc-hauppauge.c29
-rw-r--r--drivers/media/rc/keymaps/rc-iodata-bctv7e.c17
-rw-r--r--drivers/media/rc/keymaps/rc-kaiomy.c17
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-315u.c17
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c17
-rw-r--r--drivers/media/rc/keymaps/rc-manli.c17
-rw-r--r--drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c17
-rw-r--r--drivers/media/rc/keymaps/rc-msi-tvanywhere.c17
-rw-r--r--drivers/media/rc/keymaps/rc-nebula.c17
-rw-r--r--drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c17
-rw-r--r--drivers/media/rc/keymaps/rc-norwood.c17
-rw-r--r--drivers/media/rc/keymaps/rc-npgtech.c17
-rw-r--r--drivers/media/rc/keymaps/rc-pctv-sedna.c17
-rw-r--r--drivers/media/rc/keymaps/rc-pinnacle-color.c17
-rw-r--r--drivers/media/rc/keymaps/rc-pinnacle-grey.c17
-rw-r--r--drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c17
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-002t.c17
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-mk12.c17
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-new.c17
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview.c17
-rw-r--r--drivers/media/rc/keymaps/rc-powercolor-real-angel.c17
-rw-r--r--drivers/media/rc/keymaps/rc-proteus-2309.c17
-rw-r--r--drivers/media/rc/keymaps/rc-purpletv.c17
-rw-r--r--drivers/media/rc/keymaps/rc-pv951.c17
-rw-r--r--drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c17
-rw-r--r--drivers/media/rc/keymaps/rc-tbs-nec.c17
-rw-r--r--drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c17
-rw-r--r--drivers/media/rc/keymaps/rc-tevii-nec.c17
-rw-r--r--drivers/media/rc/keymaps/rc-tt-1500.c17
-rw-r--r--drivers/media/rc/keymaps/rc-videomate-s350.c17
-rw-r--r--drivers/media/rc/keymaps/rc-videomate-tv-pvr.c17
-rw-r--r--drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c19
-rw-r--r--drivers/media/rc/keymaps/rc-winfast.c17
-rw-r--r--drivers/media/rc/lirc_dev.c981
-rw-r--r--drivers/media/rc/rc-core-priv.h72
-rw-r--r--drivers/media/rc/rc-ir-raw.c86
-rw-r--r--drivers/media/rc/rc-main.c248
-rw-r--r--drivers/media/rc/winbond-cir.c2
-rw-r--r--drivers/media/tuners/Kconfig7
-rw-r--r--drivers/media/tuners/Makefile2
-rw-r--r--drivers/media/tuners/e4000.h2
-rw-r--r--drivers/media/tuners/fc0011.h2
-rw-r--r--drivers/media/tuners/fc0012.h2
-rw-r--r--drivers/media/tuners/fc0013.h2
-rw-r--r--drivers/media/tuners/fc2580.h2
-rw-r--r--drivers/media/tuners/it913x.h2
-rw-r--r--drivers/media/tuners/m88rs6000t.h2
-rw-r--r--drivers/media/tuners/max2165.c2
-rw-r--r--drivers/media/tuners/mc44s803.c2
-rw-r--r--drivers/media/tuners/mt2060.c2
-rw-r--r--drivers/media/tuners/mt2063.c4
-rw-r--r--drivers/media/tuners/mt2063.h2
-rw-r--r--drivers/media/tuners/mt20xx.h2
-rw-r--r--drivers/media/tuners/mt2131.c2
-rw-r--r--drivers/media/tuners/mt2266.c2
-rw-r--r--drivers/media/tuners/mxl301rf.h2
-rw-r--r--drivers/media/tuners/mxl5005s.c25
-rw-r--r--drivers/media/tuners/mxl5005s.h2
-rw-r--r--drivers/media/tuners/mxl5007t.h2
-rw-r--r--drivers/media/tuners/qm1d1c0042.h2
-rw-r--r--drivers/media/tuners/qt1010.c4
-rw-r--r--drivers/media/tuners/qt1010.h2
-rw-r--r--drivers/media/tuners/r820t.c69
-rw-r--r--drivers/media/tuners/r820t.h2
-rw-r--r--drivers/media/tuners/si2157.c2
-rw-r--r--drivers/media/tuners/si2157.h2
-rw-r--r--drivers/media/tuners/tda18212.h2
-rw-r--r--drivers/media/tuners/tda18218.h2
-rw-r--r--drivers/media/tuners/tda18250.c902
-rw-r--r--drivers/media/tuners/tda18250.h51
-rw-r--r--drivers/media/tuners/tda18250_priv.h145
-rw-r--r--drivers/media/tuners/tda18271.h2
-rw-r--r--drivers/media/tuners/tda827x.h4
-rw-r--r--drivers/media/tuners/tda8290.c78
-rw-r--r--drivers/media/tuners/tda8290.h2
-rw-r--r--drivers/media/tuners/tda9887.c4
-rw-r--r--drivers/media/tuners/tda9887.h2
-rw-r--r--drivers/media/tuners/tea5761.c15
-rw-r--r--drivers/media/tuners/tea5761.h2
-rw-r--r--drivers/media/tuners/tea5767.c21
-rw-r--r--drivers/media/tuners/tea5767.h2
-rw-r--r--drivers/media/tuners/tua9001.h2
-rw-r--r--drivers/media/tuners/tuner-i2c.h2
-rw-r--r--drivers/media/tuners/tuner-simple.c2
-rw-r--r--drivers/media/tuners/tuner-simple.h2
-rw-r--r--drivers/media/tuners/tuner-xc2028-types.h5
-rw-r--r--drivers/media/tuners/tuner-xc2028.c26
-rw-r--r--drivers/media/tuners/tuner-xc2028.h9
-rw-r--r--drivers/media/tuners/xc4000.c7
-rw-r--r--drivers/media/tuners/xc5000.c24
-rw-r--r--drivers/media/usb/as102/Makefile1
-rw-r--r--drivers/media/usb/as102/as102_drv.c2
-rw-r--r--drivers/media/usb/as102/as102_drv.h6
-rw-r--r--drivers/media/usb/as102/as10x_cmd_cfg.c6
-rw-r--r--drivers/media/usb/au0828/Makefile1
-rw-r--r--drivers/media/usb/au0828/au0828-cards.h2
-rw-r--r--drivers/media/usb/au0828/au0828-input.c25
-rw-r--r--drivers/media/usb/au0828/au0828-video.c2
-rw-r--r--drivers/media/usb/au0828/au0828.h18
-rw-r--r--drivers/media/usb/b2c2/Makefile1
-rw-r--r--drivers/media/usb/cpia2/cpia2_usb.c14
-rw-r--r--drivers/media/usb/cpia2/cpia2_v4l.c4
-rw-r--r--drivers/media/usb/cx231xx/Makefile2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-audio.c6
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-avcore.c4
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c30
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-core.c2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-dvb.c8
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-i2c.c2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-input.c28
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h2
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-reg.h20
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-video.c4
-rw-r--r--drivers/media/usb/cx231xx/cx231xx.h1
-rw-r--r--drivers/media/usb/dvb-usb-v2/Makefile1
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.h2
-rw-r--r--drivers/media/usb/dvb-usb-v2/az6007.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb.h10
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvbsky.c92
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c39
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c9
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h2
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h2
-rw-r--r--drivers/media/usb/dvb-usb/Kconfig2
-rw-r--r--drivers/media/usb/dvb-usb/Makefile1
-rw-r--r--drivers/media/usb/dvb-usb/az6027.c218
-rw-r--r--drivers/media/usb/dvb-usb/cxusb.c10
-rw-r--r--drivers/media/usb/dvb-usb/dib0700.h2
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_core.c26
-rw-r--r--drivers/media/usb/dvb-usb/dib0700_devices.c110
-rw-r--r--drivers/media/usb/dvb-usb/dvb-usb.h10
-rw-r--r--drivers/media/usb/dvb-usb/dw2102.c2
-rw-r--r--drivers/media/usb/dvb-usb/friio-fe.c5
-rw-r--r--drivers/media/usb/dvb-usb/pctv452e.c10
-rw-r--r--drivers/media/usb/dvb-usb/ttusb2.c2
-rw-r--r--drivers/media/usb/em28xx/Kconfig14
-rw-r--r--drivers/media/usb/em28xx/Makefile2
-rw-r--r--drivers/media/usb/em28xx/em28xx-cards.c1
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c9
-rw-r--r--drivers/media/usb/gspca/autogain_functions.c28
-rw-r--r--drivers/media/usb/gspca/benq.c8
-rw-r--r--drivers/media/usb/gspca/conex.c13
-rw-r--r--drivers/media/usb/gspca/cpia1.c76
-rw-r--r--drivers/media/usb/gspca/dtcs033.c28
-rw-r--r--drivers/media/usb/gspca/etoms.c38
-rw-r--r--drivers/media/usb/gspca/finepix.c4
-rw-r--r--drivers/media/usb/gspca/gl860/gl860.c37
-rw-r--r--drivers/media/usb/gspca/gspca.c153
-rw-r--r--drivers/media/usb/gspca/gspca.h9
-rw-r--r--drivers/media/usb/gspca/jeilinj.c19
-rw-r--r--drivers/media/usb/gspca/jl2005bcd.c45
-rw-r--r--drivers/media/usb/gspca/kinect.c11
-rw-r--r--drivers/media/usb/gspca/konica.c28
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_core.c34
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_mt9m111.c21
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_ov7660.c11
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_ov9650.c26
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_po1030.c27
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_s5k4aa.c16
-rw-r--r--drivers/media/usb/gspca/m5602/m5602_s5k83a.c2
-rw-r--r--drivers/media/usb/gspca/mars.c4
-rw-r--r--drivers/media/usb/gspca/mr97310a.c29
-rw-r--r--drivers/media/usb/gspca/nw80x.c24
-rw-r--r--drivers/media/usb/gspca/ov519.c155
-rw-r--r--drivers/media/usb/gspca/ov534.c25
-rw-r--r--drivers/media/usb/gspca/ov534_9.c23
-rw-r--r--drivers/media/usb/gspca/pac207.c16
-rw-r--r--drivers/media/usb/gspca/pac7302.c2
-rw-r--r--drivers/media/usb/gspca/pac7311.c2
-rw-r--r--drivers/media/usb/gspca/pac_common.h7
-rw-r--r--drivers/media/usb/gspca/sn9c2028.c34
-rw-r--r--drivers/media/usb/gspca/sn9c2028.h7
-rw-r--r--drivers/media/usb/gspca/sn9c20x.c2
-rw-r--r--drivers/media/usb/gspca/sonixj.c58
-rw-r--r--drivers/media/usb/gspca/spca1528.c17
-rw-r--r--drivers/media/usb/gspca/spca500.c66
-rw-r--r--drivers/media/usb/gspca/spca501.c10
-rw-r--r--drivers/media/usb/gspca/spca505.c6
-rw-r--r--drivers/media/usb/gspca/spca506.c16
-rw-r--r--drivers/media/usb/gspca/spca508.c20
-rw-r--r--drivers/media/usb/gspca/spca561.c20
-rw-r--r--drivers/media/usb/gspca/sq905.c16
-rw-r--r--drivers/media/usb/gspca/sq905c.c37
-rw-r--r--drivers/media/usb/gspca/sq930x.c29
-rw-r--r--drivers/media/usb/gspca/stk014.c6
-rw-r--r--drivers/media/usb/gspca/stk1135.c15
-rw-r--r--drivers/media/usb/gspca/stv0680.c36
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx.c76
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx.h2
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c10
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c23
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c2
-rw-r--r--drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c16
-rw-r--r--drivers/media/usb/gspca/sunplus.c36
-rw-r--r--drivers/media/usb/gspca/t613.c24
-rw-r--r--drivers/media/usb/gspca/topro.c6
-rw-r--r--drivers/media/usb/gspca/touptek.c89
-rw-r--r--drivers/media/usb/gspca/vc032x.c51
-rw-r--r--drivers/media/usb/gspca/w996Xcf.c9
-rw-r--r--drivers/media/usb/gspca/xirlink_cit.c32
-rw-r--r--drivers/media/usb/gspca/zc3xx.c83
-rw-r--r--drivers/media/usb/hdpvr/Makefile4
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-core.c37
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-i2c.c23
-rw-r--r--drivers/media/usb/hdpvr/hdpvr-video.c26
-rw-r--r--drivers/media/usb/hdpvr/hdpvr.h19
-rw-r--r--drivers/media/usb/pulse8-cec/pulse8-cec.c4
-rw-r--r--drivers/media/usb/pvrusb2/Makefile2
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-devattr.c12
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-dvb.c2
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-dvb.h8
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-hdw.c15
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c13
-rw-r--r--drivers/media/usb/pvrusb2/pvrusb2-v4l2.c34
-rw-r--r--drivers/media/usb/pwc/pwc.h6
-rw-r--r--drivers/media/usb/s2255/s2255drv.c13
-rw-r--r--drivers/media/usb/siano/Makefile1
-rw-r--r--drivers/media/usb/siano/smsusb.c2
-rw-r--r--drivers/media/usb/stk1160/Makefile4
-rw-r--r--drivers/media/usb/stkwebcam/stk-sensor.c44
-rw-r--r--drivers/media/usb/stkwebcam/stk-webcam.c2
-rw-r--r--drivers/media/usb/tm6000/Makefile2
-rw-r--r--drivers/media/usb/tm6000/tm6000-alsa.c18
-rw-r--r--drivers/media/usb/tm6000/tm6000-cards.c21
-rw-r--r--drivers/media/usb/tm6000/tm6000-core.c24
-rw-r--r--drivers/media/usb/tm6000/tm6000-i2c.c24
-rw-r--r--drivers/media/usb/tm6000/tm6000-regs.h14
-rw-r--r--drivers/media/usb/tm6000/tm6000-stds.c18
-rw-r--r--drivers/media/usb/tm6000/tm6000-usb-isoc.h14
-rw-r--r--drivers/media/usb/tm6000/tm6000-video.c26
-rw-r--r--drivers/media/usb/tm6000/tm6000.h24
-rw-r--r--drivers/media/usb/ttusb-budget/Makefile2
-rw-r--r--drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c26
-rw-r--r--drivers/media/usb/ttusb-dec/Makefile2
-rw-r--r--drivers/media/usb/ttusb-dec/ttusb_dec.c26
-rw-r--r--drivers/media/usb/ttusb-dec/ttusbdecfe.c2
-rw-r--r--drivers/media/usb/usbtv/Kconfig16
-rw-r--r--drivers/media/usb/usbvision/Makefile1
-rw-r--r--drivers/media/usb/usbvision/usbvision-video.c3
-rw-r--r--drivers/media/usb/uvc/Makefile2
-rw-r--r--drivers/media/usb/uvc/uvc_driver.c243
-rw-r--r--drivers/media/usb/uvc/uvc_isight.c12
-rw-r--r--drivers/media/usb/uvc/uvc_metadata.c179
-rw-r--r--drivers/media/usb/uvc/uvc_queue.c44
-rw-r--r--drivers/media/usb/uvc/uvc_status.c5
-rw-r--r--drivers/media/usb/uvc/uvc_v4l2.c4
-rw-r--r--drivers/media/usb/uvc/uvc_video.c187
-rw-r--r--drivers/media/usb/uvc/uvcvideo.h35
-rw-r--r--drivers/media/v4l2-core/Kconfig36
-rw-r--r--drivers/media/v4l2-core/Makefile8
-rw-r--r--drivers/media/v4l2-core/v4l2-async.c16
-rw-r--r--drivers/media/v4l2-core/v4l2-common.c27
-rw-r--r--drivers/media/v4l2-core/v4l2-compat-ioctl32.c1040
-rw-r--r--drivers/media/v4l2-core/v4l2-dev.c10
-rw-r--r--drivers/media/v4l2-core/v4l2-dv-timings.c2
-rw-r--r--drivers/media/v4l2-core/v4l2-fwnode.c10
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c212
-rw-r--r--drivers/media/v4l2-core/v4l2-mc.c2
-rw-r--r--drivers/mfd/ab8500-debugfs.c14
-rw-r--r--drivers/mmc/host/Kconfig4
-rw-r--r--drivers/mmc/host/meson-gx-mmc.c1
-rw-r--r--drivers/mmc/host/sdhci.c164
-rw-r--r--drivers/mmc/host/sdhci.h3
-rw-r--r--drivers/net/ethernet/amd/xgbe/xgbe-drv.c2
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c10
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h1
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h7
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_hw.h1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c113
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c10
-rw-r--r--drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h2
-rw-r--r--drivers/net/ethernet/ibm/ibmvnic.c14
-rw-r--r--drivers/net/ethernet/intel/e100.c12
-rw-r--r--drivers/net/ethernet/mediatek/mtk_eth_soc.c1
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c2
-rw-r--r--drivers/net/ethernet/netronome/nfp/bpf/main.h24
-rw-r--r--drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c10
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_net.h6
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h43
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c21
-rw-r--r--drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c6
-rw-r--r--drivers/net/ethernet/tundra/tsi108_eth.c36
-rw-r--r--drivers/net/netdevsim/bpf.c5
-rw-r--r--drivers/net/phy/mdio_bus.c3
-rw-r--r--drivers/nvdimm/btt.c2
-rw-r--r--drivers/nvdimm/bus.c3
-rw-r--r--drivers/nvdimm/namespace_devs.c2
-rw-r--r--drivers/nvdimm/nd.h9
-rw-r--r--drivers/nvdimm/pfn_devs.c27
-rw-r--r--drivers/nvdimm/pmem.c41
-rw-r--r--drivers/nvdimm/pmem.h1
-rw-r--r--drivers/nvdimm/region_devs.c13
-rw-r--r--drivers/of/Kconfig16
-rw-r--r--drivers/of/Makefile2
-rw-r--r--drivers/of/address.c9
-rw-r--r--drivers/of/of_pci.c384
-rw-r--r--drivers/of/of_pci_irq.c131
-rw-r--r--drivers/pci/Kconfig3
-rw-r--r--drivers/pci/Makefile14
-rw-r--r--drivers/pci/access.c9
-rw-r--r--drivers/pci/ats.c1
-rw-r--r--drivers/pci/bus.c5
-rw-r--r--drivers/pci/cadence/Kconfig27
-rw-r--r--drivers/pci/cadence/Makefile4
-rw-r--r--drivers/pci/cadence/pcie-cadence-ep.c542
-rw-r--r--drivers/pci/cadence/pcie-cadence-host.c336
-rw-r--r--drivers/pci/cadence/pcie-cadence.c126
-rw-r--r--drivers/pci/cadence/pcie-cadence.h311
-rw-r--r--drivers/pci/dwc/Kconfig70
-rw-r--r--drivers/pci/dwc/Makefile6
-rw-r--r--drivers/pci/dwc/pci-dra7xx.c47
-rw-r--r--drivers/pci/dwc/pci-exynos.c227
-rw-r--r--drivers/pci/dwc/pci-imx6.c5
-rw-r--r--drivers/pci/dwc/pci-keystone-dw.c6
-rw-r--r--drivers/pci/dwc/pci-keystone.c10
-rw-r--r--drivers/pci/dwc/pci-keystone.h6
-rw-r--r--drivers/pci/dwc/pci-layerscape.c5
-rw-r--r--drivers/pci/dwc/pcie-armada8k.c5
-rw-r--r--drivers/pci/dwc/pcie-artpec6.c475
-rw-r--r--drivers/pci/dwc/pcie-designware-ep.c140
-rw-r--r--drivers/pci/dwc/pcie-designware-host.c20
-rw-r--r--drivers/pci/dwc/pcie-designware-plat.c5
-rw-r--r--drivers/pci/dwc/pcie-designware.c7
-rw-r--r--drivers/pci/dwc/pcie-designware.h41
-rw-r--r--drivers/pci/dwc/pcie-hisi.c5
-rw-r--r--drivers/pci/dwc/pcie-histb.c5
-rw-r--r--drivers/pci/dwc/pcie-kirin.c5
-rw-r--r--drivers/pci/dwc/pcie-qcom.c14
-rw-r--r--drivers/pci/dwc/pcie-spear13xx.c5
-rw-r--r--drivers/pci/ecam.c13
-rw-r--r--drivers/pci/endpoint/Kconfig1
-rw-r--r--drivers/pci/endpoint/Makefile1
-rw-r--r--drivers/pci/endpoint/functions/Kconfig1
-rw-r--r--drivers/pci/endpoint/functions/Makefile1
-rw-r--r--drivers/pci/endpoint/functions/pci-epf-test.c54
-rw-r--r--drivers/pci/endpoint/pci-ep-cfs.c78
-rw-r--r--drivers/pci/endpoint/pci-epc-core.c85
-rw-r--r--drivers/pci/endpoint/pci-epc-mem.c13
-rw-r--r--drivers/pci/endpoint/pci-epf-core.c17
-rw-r--r--drivers/pci/host-bridge.c1
-rw-r--r--drivers/pci/host/Kconfig2
-rw-r--r--drivers/pci/host/Makefile2
-rw-r--r--drivers/pci/host/pci-aardvark.c5
-rw-r--r--drivers/pci/host/pci-host-common.c87
-rw-r--r--drivers/pci/host/pci-host-generic.c13
-rw-r--r--drivers/pci/host/pci-hyperv.c12
-rw-r--r--drivers/pci/host/pci-mvebu.c5
-rw-r--r--drivers/pci/host/pci-rcar-gen2.c5
-rw-r--r--drivers/pci/host/pci-tegra.c171
-rw-r--r--drivers/pci/host/pci-thunder-ecam.c5
-rw-r--r--drivers/pci/host/pci-thunder-pem.c13
-rw-r--r--drivers/pci/host/pci-v3-semi.c1
-rw-r--r--drivers/pci/host/pci-versatile.c12
-rw-r--r--drivers/pci/host/pci-xgene-msi.c11
-rw-r--r--drivers/pci/host/pci-xgene.c13
-rw-r--r--drivers/pci/host/pcie-altera-msi.c13
-rw-r--r--drivers/pci/host/pcie-altera.c13
-rw-r--r--drivers/pci/host/pcie-iproc-bcma.c10
-rw-r--r--drivers/pci/host/pcie-iproc-msi.c10
-rw-r--r--drivers/pci/host/pcie-iproc-platform.c17
-rw-r--r--drivers/pci/host/pcie-iproc.c18
-rw-r--r--drivers/pci/host/pcie-iproc.h12
-rw-r--r--drivers/pci/host/pcie-mediatek.c10
-rw-r--r--drivers/pci/host/pcie-rcar.c12
-rw-r--r--drivers/pci/host/pcie-rockchip.c6
-rw-r--r--drivers/pci/host/pcie-xilinx-nwl.c6
-rw-r--r--drivers/pci/host/pcie-xilinx.c6
-rw-r--r--drivers/pci/host/vmd.c10
-rw-r--r--drivers/pci/hotplug/Kconfig1
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c16
-rw-r--r--drivers/pci/hotplug/acpiphp.h16
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c16
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c20
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c16
-rw-r--r--drivers/pci/hotplug/cpci_hotplug.h16
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_core.c16
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_pci.c16
-rw-r--r--drivers/pci/hotplug/cpcihp_generic.c21
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.c21
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.h21
-rw-r--r--drivers/pci/hotplug/cpqphp.h16
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c19
-rw-r--r--drivers/pci/hotplug/cpqphp_ctrl.c16
-rw-r--r--drivers/pci/hotplug/cpqphp_nvram.c16
-rw-r--r--drivers/pci/hotplug/cpqphp_nvram.h16
-rw-r--r--drivers/pci/hotplug/cpqphp_pci.c34
-rw-r--r--drivers/pci/hotplug/cpqphp_sysfs.c16
-rw-r--r--drivers/pci/hotplug/ibmphp.h16
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c36
-rw-r--r--drivers/pci/hotplug/ibmphp_ebda.c16
-rw-r--r--drivers/pci/hotplug/ibmphp_hpc.c16
-rw-r--r--drivers/pci/hotplug/ibmphp_pci.c76
-rw-r--r--drivers/pci/hotplug/ibmphp_res.c54
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c16
-rw-r--r--drivers/pci/hotplug/pciehp.h16
-rw-r--r--drivers/pci/hotplug/pciehp_core.c16
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c16
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c28
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c28
-rw-r--r--drivers/pci/hotplug/pcihp_skeleton.c16
-rw-r--r--drivers/pci/hotplug/pnv_php.c45
-rw-r--r--drivers/pci/hotplug/rpadlpar.h6
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c6
-rw-r--r--drivers/pci/hotplug/rpadlpar_sysfs.c6
-rw-r--r--drivers/pci/hotplug/rpaphp.h16
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c16
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c16
-rw-r--r--drivers/pci/hotplug/rpaphp_slot.c16
-rw-r--r--drivers/pci/hotplug/s390_pci_hpc.c3
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c41
-rw-r--r--drivers/pci/hotplug/shpchp.h24
-rw-r--r--drivers/pci/hotplug/shpchp_core.c21
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c16
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c16
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c28
-rw-r--r--drivers/pci/hotplug/shpchp_sysfs.c16
-rw-r--r--drivers/pci/iov.c11
-rw-r--r--drivers/pci/irq.c7
-rw-r--r--drivers/pci/mmap.c5
-rw-r--r--drivers/pci/msi.c8
-rw-r--r--drivers/pci/of.c571
-rw-r--r--drivers/pci/pci-acpi.c3
-rw-r--r--drivers/pci/pci-driver.c4
-rw-r--r--drivers/pci/pci-mid.c5
-rw-r--r--drivers/pci/pci-stub.c5
-rw-r--r--drivers/pci/pci-sysfs.c30
-rw-r--r--drivers/pci/pci.c158
-rw-r--r--drivers/pci/pci.h74
-rw-r--r--drivers/pci/pcie/Kconfig3
-rw-r--r--drivers/pci/pcie/aer/Kconfig1
-rw-r--r--drivers/pci/pcie/aer/Kconfig.debug1
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c22
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c7
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c31
-rw-r--r--drivers/pci/pcie/aer/aerdrv_errprint.c27
-rw-r--r--drivers/pci/pcie/aer/ecrc.c16
-rw-r--r--drivers/pci/pcie/aspm.c80
-rw-r--r--drivers/pci/pcie/pcie-dpc.c256
-rw-r--r--drivers/pci/pcie/pme.c11
-rw-r--r--drivers/pci/pcie/portdrv_acpi.c5
-rw-r--r--drivers/pci/pcie/portdrv_bus.c1
-rw-r--r--drivers/pci/pcie/portdrv_core.c4
-rw-r--r--drivers/pci/pcie/ptm.c12
-rw-r--r--drivers/pci/probe.c372
-rw-r--r--drivers/pci/quirks.c210
-rw-r--r--drivers/pci/remove.c1
-rw-r--r--drivers/pci/rom.c9
-rw-r--r--drivers/pci/search.c1
-rw-r--r--drivers/pci/setup-bus.c49
-rw-r--r--drivers/pci/setup-irq.c5
-rw-r--r--drivers/pci/setup-res.c40
-rw-r--r--drivers/pci/slot.c1
-rw-r--r--drivers/pci/switch/Kconfig2
-rw-r--r--drivers/pci/switch/Makefile1
-rw-r--r--drivers/pci/switch/switchtec.c14
-rw-r--r--drivers/pci/syscall.c4
-rw-r--r--drivers/pci/vc.c23
-rw-r--r--drivers/pci/vpd.c1
-rw-r--r--drivers/pci/xen-pcifront.c23
-rw-r--r--drivers/perf/arm_dsu_pmu.c6
-rw-r--r--drivers/platform/Kconfig2
-rw-r--r--drivers/platform/Makefile1
-rw-r--r--drivers/platform/mellanox/Kconfig26
-rw-r--r--drivers/platform/mellanox/Makefile6
-rw-r--r--drivers/platform/mellanox/mlxreg-hotplug.c638
-rw-r--r--drivers/platform/x86/Kconfig56
-rw-r--r--drivers/platform/x86/Makefile4
-rw-r--r--drivers/platform/x86/acer-wireless.c71
-rw-r--r--drivers/platform/x86/alienware-wmi.c17
-rw-r--r--drivers/platform/x86/apple-gmux.c48
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c13
-rw-r--r--drivers/platform/x86/dell-laptop.c274
-rw-r--r--drivers/platform/x86/dell-smbios.c8
-rw-r--r--drivers/platform/x86/dell-wmi.c3
-rw-r--r--drivers/platform/x86/gpd-pocket-fan.c216
-rw-r--r--drivers/platform/x86/ideapad-laptop.c56
-rw-r--r--drivers/platform/x86/intel-hid.c41
-rw-r--r--drivers/platform/x86/intel-vbtn.c65
-rw-r--r--drivers/platform/x86/intel_chtdc_ti_pwrbtn.c93
-rw-r--r--drivers/platform/x86/intel_int0002_vgpio.c2
-rw-r--r--drivers/platform/x86/intel_pmc_core.c280
-rw-r--r--drivers/platform/x86/intel_pmc_core.h29
-rw-r--r--drivers/platform/x86/intel_pmc_ipc.c33
-rw-r--r--drivers/platform/x86/intel_telemetry_debugfs.c83
-rw-r--r--drivers/platform/x86/mlx-platform.c324
-rw-r--r--drivers/platform/x86/mlxcpld-hotplug.c515
-rw-r--r--drivers/platform/x86/pmc_atom.c42
-rw-r--r--drivers/platform/x86/samsung-laptop.c18
-rw-r--r--drivers/platform/x86/silead_dmi.c175
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c18
-rw-r--r--drivers/pps/generators/pps_gen_parport.c40
-rw-r--r--drivers/pwm/pwm-meson.c26
-rw-r--r--drivers/pwm/pwm-stmpe.c2
-rw-r--r--drivers/pwm/sysfs.c1
-rw-r--r--drivers/rapidio/devices/tsi721_dma.c17
-rw-r--r--drivers/rapidio/rio.c110
-rw-r--r--drivers/regulator/core.c2
-rw-r--r--drivers/remoteproc/qcom_adsp_pil.c8
-rw-r--r--drivers/remoteproc/qcom_common.c21
-rw-r--r--drivers/remoteproc/qcom_common.h4
-rw-r--r--drivers/remoteproc/qcom_q6v5_pil.c18
-rw-r--r--drivers/remoteproc/qcom_wcnss.c8
-rw-r--r--drivers/remoteproc/remoteproc_core.c83
-rw-r--r--drivers/remoteproc/remoteproc_elf_loader.c59
-rw-r--r--drivers/remoteproc/remoteproc_internal.h57
-rw-r--r--drivers/remoteproc/remoteproc_virtio.c2
-rw-r--r--drivers/remoteproc/st_slim_rproc.c32
-rw-r--r--drivers/rpmsg/qcom_glink_native.c1
-rw-r--r--drivers/rpmsg/qcom_glink_smem.c5
-rw-r--r--drivers/rpmsg/qcom_smd.c66
-rw-r--r--drivers/s390/block/Kconfig1
-rw-r--r--drivers/s390/block/dcssblk.c3
-rw-r--r--drivers/sbus/char/openprom.c5
-rw-r--r--drivers/staging/media/Kconfig17
-rw-r--r--drivers/staging/media/Makefile2
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-gc0310.c10
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-gc2235.c8
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-lm3554.c38
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c8
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-ov2680.c10
-rw-r--r--drivers/staging/media/atomisp/i2c/atomisp-ov2722.c17
-rw-r--r--drivers/staging/media/atomisp/i2c/ov2680.h1
-rw-r--r--drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c94
-rw-r--r--drivers/staging/media/atomisp/i2c/ov5693/ov5693.h2
-rw-r--r--drivers/staging/media/atomisp/i2c/ov8858.c43
-rw-r--r--drivers/staging/media/atomisp/include/linux/atomisp.h2
-rw-r--r--drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c17
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h5
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c5
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c2
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c12
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8.host.c24
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c1
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h2
-rw-r--r--drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c8
-rw-r--r--drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c129
-rw-r--r--drivers/staging/media/cxd2099/Makefile1
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.c30
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.h16
-rw-r--r--drivers/staging/media/davinci_vpfe/TODO10
-rw-r--r--drivers/staging/media/imx/TODO63
-rw-r--r--drivers/staging/media/imx/imx-ic-prp.c4
-rw-r--r--drivers/staging/media/imx/imx-media-capture.c8
-rw-r--r--drivers/staging/media/imx/imx-media-csi.c189
-rw-r--r--drivers/staging/media/imx/imx-media-dev.c400
-rw-r--r--drivers/staging/media/imx/imx-media-internal-sd.c253
-rw-r--r--drivers/staging/media/imx/imx-media-of.c278
-rw-r--r--drivers/staging/media/imx/imx-media-utils.c122
-rw-r--r--drivers/staging/media/imx/imx-media.h189
-rw-r--r--drivers/staging/media/imx/imx6-mipi-csi2.c4
-rw-r--r--drivers/staging/media/lirc/Kconfig21
-rw-r--r--drivers/staging/media/lirc/Makefile6
-rw-r--r--drivers/staging/media/lirc/TODO36
-rw-r--r--drivers/staging/media/lirc/lirc_zilog.c1653
-rw-r--r--drivers/staging/media/omap4iss/iss.c2
-rw-r--r--drivers/staging/media/tegra-vde/Kconfig8
-rw-r--r--drivers/staging/media/tegra-vde/Makefile1
-rw-r--r--drivers/staging/media/tegra-vde/TODO4
-rw-r--r--drivers/staging/media/tegra-vde/tegra-vde.c1213
-rw-r--r--drivers/staging/media/tegra-vde/uapi.h78
-rw-r--r--drivers/thermal/Kconfig4
-rw-r--r--drivers/thermal/armada_thermal.c253
-rw-r--r--drivers/thermal/hisi_thermal.c2
-rw-r--r--drivers/thermal/imx_thermal.c74
-rw-r--r--drivers/thermal/int340x_thermal/int3400_thermal.c12
-rw-r--r--drivers/thermal/mtk_thermal.c9
-rw-r--r--drivers/thermal/of-thermal.c1
-rw-r--r--drivers/thermal/power_allocator.c2
-rw-r--r--drivers/thermal/tegra/soctherm.c103
-rw-r--r--drivers/thermal/thermal_hwmon.c20
-rw-r--r--drivers/thermal/x86_pkg_temp_thermal.c4
-rw-r--r--drivers/usb/host/ehci-st.c1
-rw-r--r--drivers/video/console/dummycon.c1
-rw-r--r--drivers/video/console/vgacon.c34
-rw-r--r--drivers/video/fbdev/Kconfig2
-rw-r--r--drivers/video/fbdev/atmel_lcdfb.c8
-rw-r--r--drivers/video/fbdev/aty/radeon_base.c18
-rw-r--r--drivers/video/fbdev/au1200fb.h286
-rw-r--r--drivers/video/fbdev/auo_k190x.c3
-rw-r--r--drivers/video/fbdev/intelfb/intelfbhw.c4
-rw-r--r--drivers/video/fbdev/mmp/core.c5
-rw-r--r--drivers/video/fbdev/mxsfb.c45
-rw-r--r--drivers/video/fbdev/nvidia/nv_hw.c11
-rw-r--r--drivers/video/fbdev/nvidia/nv_setup.c3
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/dispc.c39
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/dss.c45
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c5
-rw-r--r--drivers/video/fbdev/omap2/omapfb/dss/hdmi_phy.c31
-rw-r--r--drivers/video/fbdev/pxa3xx-gcu.c16
-rw-r--r--drivers/video/fbdev/riva/fbdev.c2
-rw-r--r--drivers/video/fbdev/riva/nv_driver.c7
-rw-r--r--drivers/video/fbdev/riva/riva_hw.c20
-rw-r--r--drivers/video/fbdev/riva/riva_hw.h3
-rw-r--r--drivers/video/fbdev/smscufx.c5
-rw-r--r--drivers/video/fbdev/udlfb.c655
-rw-r--r--drivers/video/fbdev/vfb.c17
-rw-r--r--drivers/video/fbdev/vga16fb.c1
-rw-r--r--drivers/video/fbdev/vt8500lcdfb.c4
-rw-r--r--drivers/video/fbdev/wm8505fb.c4
-rw-r--r--drivers/watchdog/Kconfig41
-rw-r--r--drivers/watchdog/Makefile7
-rw-r--r--drivers/watchdog/advantechwdt.c2
-rw-r--r--drivers/watchdog/alim1535_wdt.c2
-rw-r--r--drivers/watchdog/aspeed_wdt.c21
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c433
-rw-r--r--drivers/watchdog/da9062_wdt.c48
-rw-r--r--drivers/watchdog/davinci_wdt.c38
-rw-r--r--drivers/watchdog/dw_wdt.c18
-rw-r--r--drivers/watchdog/eurotechwdt.c2
-rw-r--r--drivers/watchdog/f71808e_wdt.c4
-rw-r--r--drivers/watchdog/ftwdt010_wdt.c236
-rw-r--r--drivers/watchdog/gemini_wdt.c229
-rw-r--r--drivers/watchdog/gpio_wdt.c58
-rw-r--r--drivers/watchdog/hpwdt.c12
-rw-r--r--drivers/watchdog/i6300esb.c377
-rw-r--r--drivers/watchdog/ib700wdt.c2
-rw-r--r--drivers/watchdog/imx2_wdt.c20
-rw-r--r--drivers/watchdog/jz4740_wdt.c1
-rw-r--r--drivers/watchdog/mei_wdt.c7
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c83
-rw-r--r--drivers/watchdog/mt7621_wdt.c34
-rw-r--r--drivers/watchdog/orion_wdt.c2
-rw-r--r--drivers/watchdog/pcwd_pci.c2
-rw-r--r--drivers/watchdog/pcwd_usb.c5
-rw-r--r--drivers/watchdog/rtd119x_wdt.c168
-rw-r--r--drivers/watchdog/sp5100_tco.c710
-rw-r--r--drivers/watchdog/sp5100_tco.h57
-rw-r--r--drivers/watchdog/sprd_wdt.c399
-rw-r--r--drivers/watchdog/stm32_iwdg.c6
-rw-r--r--drivers/watchdog/sunxi_wdt.c7
-rw-r--r--drivers/watchdog/watchdog_core.c1
-rw-r--r--drivers/watchdog/watchdog_dev.c125
-rw-r--r--drivers/watchdog/wdt_pci.c2
-rw-r--r--drivers/watchdog/xen_wdt.c255
-rw-r--r--fs/Kconfig7
-rw-r--r--fs/affs/dir.c2
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/compat_ioctl.c22
-rw-r--r--fs/dcache.c88
-rw-r--r--fs/exofs/dir.c2
-rw-r--r--fs/ext2/dir.c2
-rw-r--r--fs/ext2/super.c9
-rw-r--r--fs/ext4/dir.c4
-rw-r--r--fs/ext4/inline.c2
-rw-r--r--fs/ext4/super.c9
-rw-r--r--fs/fat/namei_vfat.c2
-rw-r--r--fs/hfsplus/dir.c4
-rw-r--r--fs/hfsplus/hfsplus_fs.h3
-rw-r--r--fs/hfsplus/inode.c7
-rw-r--r--fs/hfsplus/super.c2
-rw-r--r--fs/inode.c1
-rw-r--r--fs/nfs/inode.c6
-rw-r--r--fs/nilfs2/segbuf.c2
-rw-r--r--fs/nilfs2/segbuf.h4
-rw-r--r--fs/nilfs2/segment.c2
-rw-r--r--fs/nilfs2/segment.h2
-rw-r--r--fs/nilfs2/sufile.c2
-rw-r--r--fs/nilfs2/sufile.h2
-rw-r--r--fs/nilfs2/super.c4
-rw-r--r--fs/nilfs2/sysfs.c21
-rw-r--r--fs/nilfs2/the_nilfs.h8
-rw-r--r--fs/ocfs2/dir.c4
-rw-r--r--fs/overlayfs/Kconfig31
-rw-r--r--fs/overlayfs/Makefile3
-rw-r--r--fs/overlayfs/copy_up.c188
-rw-r--r--fs/overlayfs/dir.c175
-rw-r--r--fs/overlayfs/export.c715
-rw-r--r--fs/overlayfs/inode.c106
-rw-r--r--fs/overlayfs/namei.c533
-rw-r--r--fs/overlayfs/overlayfs.h66
-rw-r--r--fs/overlayfs/ovl_entry.h11
-rw-r--r--fs/overlayfs/readdir.c57
-rw-r--r--fs/overlayfs/super.c125
-rw-r--r--fs/overlayfs/util.c108
-rw-r--r--fs/pipe.c57
-rw-r--r--fs/proc/array.c8
-rw-r--r--fs/proc/base.c70
-rw-r--r--fs/proc/consoles.c3
-rw-r--r--fs/proc/fd.c2
-rw-r--r--fs/proc/generic.c18
-rw-r--r--fs/proc/inode.c11
-rw-r--r--fs/proc/internal.h29
-rw-r--r--fs/proc/kcore.c18
-rw-r--r--fs/proc/proc_net.c4
-rw-r--r--fs/proc/self.c9
-rw-r--r--fs/proc/thread_self.c8
-rw-r--r--fs/proc/vmcore.c6
-rw-r--r--fs/udf/udftime.c5
-rw-r--r--fs/ufs/dir.c2
-rw-r--r--fs/xfs/libxfs/xfs_sb.c4
-rw-r--r--fs/xfs/xfs_super.c24
-rw-r--r--fs/xfs/xfs_super.h7
-rw-r--r--include/asm-generic/audit_dir_write.h2
-rw-r--r--include/asm-generic/bitops/find.h20
-rw-r--r--include/asm-generic/pci_iomap.h6
-rw-r--r--include/asm-generic/qrwlock_types.h1
-rw-r--r--include/dt-bindings/clock/jz4770-cgu.h58
-rw-r--r--include/linux/bitmap.h63
-rw-r--r--include/linux/build_bug.h2
-rw-r--r--include/linux/compiler-clang.h8
-rw-r--r--include/linux/cpumask.h2
-rw-r--r--include/linux/cpuset.h6
-rw-r--r--include/linux/crash_dump.h12
-rw-r--r--include/linux/dcache.h2
-rw-r--r--include/linux/fb.h5
-rw-r--r--include/linux/genl_magic_func.h12
-rw-r--r--include/linux/ioport.h2
-rw-r--r--include/linux/iversion.h22
-rw-r--r--include/linux/jump_label.h4
-rw-r--r--include/linux/kallsyms.h2
-rw-r--r--include/linux/kasan.h15
-rw-r--r--include/linux/kfifo.h3
-rw-r--r--include/linux/led-class-flash.h4
-rw-r--r--include/linux/libnvdimm.h11
-rw-r--r--include/linux/lockref.h2
-rw-r--r--include/linux/memblock.h4
-rw-r--r--include/linux/memory_hotplug.h29
-rw-r--r--include/linux/memremap.h77
-rw-r--r--include/linux/mlx5/driver.h2
-rw-r--r--include/linux/mm.h22
-rw-r--r--include/linux/module.h2
-rw-r--r--include/linux/mutex.h4
-rw-r--r--include/linux/netdevice.h6
-rw-r--r--include/linux/of_pci.h8
-rw-r--r--include/linux/pci-aspm.h35
-rw-r--r--include/linux/pci-dma-compat.h27
-rw-r--r--include/linux/pci-ecam.h13
-rw-r--r--include/linux/pci-ep-cfs.h5
-rw-r--r--include/linux/pci-epc.h48
-rw-r--r--include/linux/pci-epf.h5
-rw-r--r--include/linux/pci.h441
-rw-r--r--include/linux/pci_hotplug.h16
-rw-r--r--include/linux/pci_ids.h2
-rw-r--r--include/linux/pfn_t.h13
-rw-r--r--include/linux/pipe_fs_i.h5
-rw-r--r--include/linux/platform_data/mlxcpld-hotplug.h99
-rw-r--r--include/linux/platform_data/mlxreg.h144
-rw-r--r--include/linux/remoteproc.h21
-rw-r--r--include/linux/sched.h13
-rw-r--r--include/linux/sched/mm.h35
-rw-r--r--include/linux/seq_file.h14
-rw-r--r--include/linux/switchtec.h3
-rw-r--r--include/linux/sync_core.h21
-rw-r--r--include/linux/sysctl.h3
-rw-r--r--include/linux/uuid.h1
-rw-r--r--include/media/cec.h18
-rw-r--r--include/media/demux.h (renamed from drivers/media/dvb-core/demux.h)0
-rw-r--r--include/media/dmxdev.h (renamed from drivers/media/dvb-core/dmxdev.h)43
-rw-r--r--include/media/drv-intf/cx2341x.h144
-rw-r--r--include/media/drv-intf/exynos-fimc.h3
-rw-r--r--include/media/drv-intf/msp3400.h62
-rw-r--r--include/media/drv-intf/saa7146.h2
-rw-r--r--include/media/dvb-usb-ids.h (renamed from drivers/media/dvb-core/dvb-usb-ids.h)3
-rw-r--r--include/media/dvb_ca_en50221.h (renamed from drivers/media/dvb-core/dvb_ca_en50221.h)2
-rw-r--r--include/media/dvb_demux.h (renamed from drivers/media/dvb-core/dvb_demux.h)25
-rw-r--r--include/media/dvb_frontend.h (renamed from drivers/media/dvb-core/dvb_frontend.h)19
-rw-r--r--include/media/dvb_math.h (renamed from drivers/media/dvb-core/dvb_math.h)0
-rw-r--r--include/media/dvb_net.h (renamed from drivers/media/dvb-core/dvb_net.h)2
-rw-r--r--include/media/dvb_ringbuffer.h (renamed from drivers/media/dvb-core/dvb_ringbuffer.h)0
-rw-r--r--include/media/dvb_vb2.h266
-rw-r--r--include/media/dvbdev.h (renamed from drivers/media/dvb-core/dvbdev.h)4
-rw-r--r--include/media/i2c-addr.h43
-rw-r--r--include/media/i2c/as3645a.h66
-rw-r--r--include/media/i2c/bt819.h4
-rw-r--r--include/media/i2c/ir-kbd-i2c.h6
-rw-r--r--include/media/i2c/m52790.h52
-rw-r--r--include/media/i2c/saa7115.h12
-rw-r--r--include/media/i2c/tvaudio.h17
-rw-r--r--include/media/i2c/upd64031a.h6
-rw-r--r--include/media/lirc.h1
-rw-r--r--include/media/lirc_dev.h192
-rw-r--r--include/media/media-entity.h11
-rw-r--r--include/media/rc-core.h69
-rw-r--r--include/media/rc-map.h54
-rw-r--r--include/media/tpg/v4l2-tpg.h (renamed from include/media/v4l2-tpg.h)45
-rw-r--r--include/media/tuner-types.h15
-rw-r--r--include/media/v4l2-async.h39
-rw-r--r--include/media/v4l2-common.h145
-rw-r--r--include/media/v4l2-ctrls.h11
-rw-r--r--include/media/v4l2-dev.h140
-rw-r--r--include/media/v4l2-device.h246
-rw-r--r--include/media/v4l2-dv-timings.h16
-rw-r--r--include/media/v4l2-event.h36
-rw-r--r--include/media/v4l2-flash-led-class.h12
-rw-r--r--include/media/v4l2-fwnode.h12
-rw-r--r--include/media/v4l2-mediabus.h80
-rw-r--r--include/media/v4l2-subdev.h150
-rw-r--r--include/media/v4l2-tpg-colors.h68
-rw-r--r--include/media/videobuf-dvb.h10
-rw-r--r--include/media/videobuf2-core.h519
-rw-r--r--include/media/videobuf2-dvb.h11
-rw-r--r--include/media/videobuf2-memops.h8
-rw-r--r--include/media/videobuf2-v4l2.h112
-rw-r--r--include/net/erspan.h26
-rw-r--r--include/rdma/ib_hdrs.h19
-rw-r--r--include/rdma/ib_verbs.h20
-rw-r--r--include/sound/soc.h2
-rw-r--r--include/uapi/asm-generic/siginfo.h4
-rw-r--r--include/uapi/linux/dvb/dmx.h63
-rw-r--r--include/uapi/linux/dvb/frontend.h40
-rw-r--r--include/uapi/linux/dvb/version.h2
-rw-r--r--include/uapi/linux/dvb/video.h20
-rw-r--r--include/uapi/linux/input-event-codes.h1
-rw-r--r--include/uapi/linux/lirc.h82
-rw-r--r--include/uapi/linux/membarrier.h74
-rw-r--r--include/uapi/linux/ndctl.h56
-rw-r--r--include/uapi/linux/pci_regs.h30
-rw-r--r--include/uapi/linux/switchtec_ioctl.h3
-rw-r--r--include/uapi/linux/uuid.h1
-rw-r--r--include/uapi/linux/uvcvideo.h26
-rw-r--r--include/uapi/linux/v4l2-controls.h96
-rw-r--r--include/uapi/linux/videodev2.h63
-rw-r--r--include/uapi/rdma/rdma_netlink.h14
-rw-r--r--include/video/udlfb.h3
-rw-r--r--init/Kconfig9
-rw-r--r--ipc/mqueue.c2
-rw-r--r--ipc/msg.c20
-rw-r--r--ipc/sem.c10
-rw-r--r--ipc/shm.c20
-rw-r--r--ipc/util.c5
-rw-r--r--kernel/async.c20
-rw-r--r--kernel/bpf/core.c32
-rw-r--r--kernel/cgroup/cpuset.c4
-rw-r--r--kernel/compat.c2
-rw-r--r--kernel/configs/tiny.config4
-rw-r--r--kernel/fork.c60
-rw-r--r--kernel/futex.c20
-rw-r--r--kernel/irq/spurious.c1
-rw-r--r--kernel/kcov.c4
-rw-r--r--kernel/memremap.c174
-rw-r--r--kernel/module.c7
-rw-r--r--kernel/pid.c13
-rw-r--r--kernel/ptrace.c27
-rw-r--r--kernel/relay.c1
-rw-r--r--kernel/resource.c39
-rw-r--r--kernel/sched/core.c76
-rw-r--r--kernel/sched/fair.c101
-rw-r--r--kernel/sched/membarrier.c177
-rw-r--r--kernel/sched/rt.c29
-rw-r--r--kernel/sched/sched.h2
-rw-r--r--kernel/sched/stats.h6
-rw-r--r--kernel/sched/topology.c13
-rw-r--r--kernel/sysctl.c33
-rw-r--r--kernel/taskstats.c6
-rw-r--r--kernel/time/hrtimer.c1
-rw-r--r--lib/Kconfig.debug11
-rw-r--r--lib/Kconfig.kasan11
-rw-r--r--lib/Makefile2
-rw-r--r--lib/bitmap.c137
-rw-r--r--lib/cpumask.c9
-rw-r--r--lib/find_bit.c59
-rw-r--r--lib/find_bit_benchmark.c (renamed from lib/test_find_bit.c)70
-rw-r--r--lib/pci_iomap.c1
-rw-r--r--lib/stackdepot.c19
-rw-r--r--lib/test_bitmap.c295
-rw-r--r--lib/test_kasan.c107
-rw-r--r--lib/test_sort.c6
-rw-r--r--lib/ubsan.c64
-rw-r--r--lib/ubsan.h17
-rw-r--r--mm/bootmem.c2
-rw-r--r--mm/gup.c7
-rw-r--r--mm/hmm.c13
-rw-r--r--mm/kasan/kasan.c108
-rw-r--r--mm/kasan/kasan.h55
-rw-r--r--mm/kasan/report.c11
-rw-r--r--mm/ksm.c2
-rw-r--r--mm/maccess.c2
-rw-r--r--mm/memblock.c6
-rw-r--r--mm/memcontrol.c6
-rw-r--r--mm/memory.c20
-rw-r--r--mm/memory_hotplug.c39
-rw-r--r--mm/mempool.c6
-rw-r--r--mm/mlock.c2
-rw-r--r--mm/nommu.c2
-rw-r--r--mm/page_alloc.c6
-rw-r--r--mm/pagewalk.c1
-rw-r--r--mm/process_vm_access.c10
-rw-r--r--mm/slab.c6
-rw-r--r--mm/slub.c10
-rw-r--r--mm/sparse-vmemmap.c67
-rw-r--r--mm/sparse.c43
-rw-r--r--mm/swap.c4
-rw-r--r--mm/userfaultfd.c1
-rw-r--r--mm/vmscan.c1
-rw-r--r--mm/z3fold.c4
-rw-r--r--mm/zbud.c4
-rw-r--r--mm/zpool.c46
-rw-r--r--net/bluetooth/hci_debugfs.c13
-rw-r--r--net/bpf/test_run.c4
-rw-r--r--net/core/ethtool.c53
-rw-r--r--net/ipv4/ip_gre.c14
-rw-r--r--net/ipv6/ip6_gre.c15
-rw-r--r--net/ipv6/mcast.c8
-rw-r--r--net/rds/ib.c3
-rw-r--r--net/sched/cls_u32.c21
-rw-r--r--net/sctp/ipv6.c10
-rw-r--r--net/sctp/protocol.c10
-rw-r--r--samples/bpf/Makefile2
-rw-r--r--samples/bpf/bpf_load.c102
-rw-r--r--samples/bpf/bpf_load.h2
-rw-r--r--samples/bpf/tcbpf2_kern.c41
-rwxr-xr-xsamples/bpf/test_tunnel_bpf.sh4
-rw-r--r--samples/bpf/xdp1_user.c4
-rw-r--r--samples/bpf/xdp_redirect_cpu_user.c6
-rw-r--r--samples/bpf/xdp_redirect_map_user.c8
-rw-r--r--samples/bpf/xdp_redirect_user.c8
-rw-r--r--samples/bpf/xdp_router_ipv4_user.c10
-rw-r--r--samples/bpf/xdp_rxq_info_user.c4
-rw-r--r--samples/bpf/xdp_tx_iptunnel_user.c6
-rw-r--r--scripts/Makefile.kasan35
-rw-r--r--scripts/Makefile.lib2
-rw-r--r--scripts/Makefile.ubsan1
-rwxr-xr-xscripts/checkpatch.pl144
-rw-r--r--scripts/mod/modpost.c2
-rw-r--r--security/integrity/ima/ima_main.c2
-rw-r--r--security/yama/yama_lsm.c11
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c17
-rw-r--r--sound/soc/atmel/sam9x5_wm8731.c12
-rw-r--r--sound/soc/codecs/ak4613.c78
-rw-r--r--sound/soc/codecs/dmic.c2
-rw-r--r--sound/soc/codecs/max98373.c4
-rw-r--r--sound/soc/codecs/max98373.h5
-rw-r--r--sound/soc/codecs/sgtl5000.c2
-rw-r--r--sound/soc/codecs/twl4030.c2
-rw-r--r--sound/soc/codecs/twl6040.c2
-rw-r--r--sound/soc/intel/Kconfig3
-rw-r--r--sound/soc/intel/boards/Kconfig1
-rw-r--r--sound/soc/intel/boards/kbl_rt5663_max98927.c95
-rw-r--r--sound/soc/intel/skylake/Makefile5
-rw-r--r--sound/soc/intel/skylake/skl-i2s.h31
-rw-r--r--sound/soc/intel/skylake/skl-messages.c1
-rw-r--r--sound/soc/intel/skylake/skl-nhlt.c41
-rw-r--r--sound/soc/intel/skylake/skl-ssp-clk.c429
-rw-r--r--sound/soc/intel/skylake/skl-ssp-clk.h38
-rw-r--r--sound/soc/intel/skylake/skl.h6
-rw-r--r--sound/soc/mediatek/mt2701/mt2701-afe-pcm.c32
-rw-r--r--sound/soc/mediatek/mt8173/mt8173-rt5650.c11
-rw-r--r--sound/soc/rockchip/rk3399_gru_sound.c19
-rw-r--r--sound/soc/soc-compress.c79
-rw-r--r--sound/soc/soc-core.c12
-rw-r--r--sound/soc/soc-dapm.c2
-rw-r--r--sound/soc/soc-pcm.c7
-rw-r--r--sound/soc/stm/Kconfig6
-rw-r--r--sound/soc/sunxi/sun8i-codec.c82
-rw-r--r--tools/arch/powerpc/include/uapi/asm/kvm.h25
-rw-r--r--tools/arch/s390/include/uapi/asm/kvm.h5
-rw-r--r--tools/arch/x86/include/asm/cpufeatures.h24
-rw-r--r--tools/arch/x86/include/asm/disabled-features.h3
-rw-r--r--tools/arch/x86/include/asm/required-features.h3
-rw-r--r--tools/include/asm-generic/bitops/find.h16
-rw-r--r--tools/include/uapi/linux/if_link.h943
-rw-r--r--tools/include/uapi/linux/kvm.h4
-rw-r--r--tools/include/uapi/linux/netlink.h251
-rw-r--r--tools/include/uapi/linux/sched.h5
-rw-r--r--tools/include/uapi/sound/asound.h9
-rw-r--r--tools/lib/bpf/Build2
-rw-r--r--tools/lib/bpf/Makefile6
-rw-r--r--tools/lib/bpf/bpf.c135
-rw-r--r--tools/lib/bpf/bpf.h2
-rw-r--r--tools/lib/bpf/libbpf.c4
-rw-r--r--tools/lib/bpf/libbpf.h6
-rw-r--r--tools/lib/bpf/nlattr.c187
-rw-r--r--tools/lib/bpf/nlattr.h72
-rw-r--r--tools/lib/find_bit.c39
-rw-r--r--tools/lib/subcmd/pager.c5
-rw-r--r--tools/perf/.gitignore1
-rw-r--r--tools/perf/builtin-record.c3
-rw-r--r--tools/perf/builtin-trace.c5
-rw-r--r--tools/perf/perf.h1
-rw-r--r--tools/perf/util/evsel.c13
-rw-r--r--tools/testing/nvdimm/Kbuild4
-rw-r--r--tools/testing/nvdimm/acpi_nfit_test.c8
-rw-r--r--tools/testing/nvdimm/device_dax_test.c8
-rw-r--r--tools/testing/nvdimm/libnvdimm_test.c8
-rw-r--r--tools/testing/nvdimm/pmem_test.c8
-rw-r--r--tools/testing/nvdimm/test/iomap.c7
-rw-r--r--tools/testing/nvdimm/test/nfit.c498
-rw-r--r--tools/testing/nvdimm/test/nfit_test.h134
-rw-r--r--tools/testing/nvdimm/watermark.h21
-rw-r--r--tools/testing/selftests/bpf/.gitignore1
-rw-r--r--tools/testing/selftests/bpf/Makefile4
-rw-r--r--tools/testing/selftests/bpf/test_verifier.c14
-rw-r--r--tools/testing/selftests/membarrier/membarrier_test.c237
1825 files changed, 43314 insertions, 25966 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-samsung-laptop b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
index 63c1ad0212fc..34d3a3359cf4 100644
--- a/Documentation/ABI/testing/sysfs-driver-samsung-laptop
+++ b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
@@ -3,7 +3,7 @@ Date: January 1, 2010
KernelVersion: 2.6.33
Contact: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Description: Some Samsung laptops have different "performance levels"
- that are can be modified by a function key, and by this
+ that can be modified by a function key, and by this
sysfs file. These values don't always make a whole lot
of sense, but some users like to modify them to keep
their fans quiet at all costs. Reading from this file
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 512ccafa45b1..39ac9d4fad7f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3711,7 +3711,11 @@
[KNL, SMP] Set scheduler's default relax_domain_level.
See Documentation/cgroup-v1/cpusets.txt.
- reserve= [KNL,BUGS] Force the kernel to ignore some iomem area
+ reserve= [KNL,BUGS] Force kernel to ignore I/O ports or memory
+ Format: <base1>,<size1>[,<base2>,<size2>,...]
+ Reserve I/O ports or memory so the kernel won't use
+ them. If <base> is less than 0x10000, the region
+ is assumed to be I/O ports; otherwise it is memory.
reservetop= [X86-32]
Format: nn[KMG]
diff --git a/Documentation/admin-guide/thunderbolt.rst b/Documentation/admin-guide/thunderbolt.rst
index 9b55952039a6..9948ec36a204 100644
--- a/Documentation/admin-guide/thunderbolt.rst
+++ b/Documentation/admin-guide/thunderbolt.rst
@@ -3,13 +3,13 @@
=============
The interface presented here is not meant for end users. Instead there
should be a userspace tool that handles all the low-level details, keeps
-database of the authorized devices and prompts user for new connections.
+a database of the authorized devices and prompts users for new connections.
More details about the sysfs interface for Thunderbolt devices can be
found in ``Documentation/ABI/testing/sysfs-bus-thunderbolt``.
Those users who just want to connect any device without any sort of
-manual work, can add following line to
+manual work can add following line to
``/etc/udev/rules.d/99-local.rules``::
ACTION=="add", SUBSYSTEM=="thunderbolt", ATTR{authorized}=="0", ATTR{authorized}="1"
@@ -20,7 +20,7 @@ vulnerable to DMA attacks.
Security levels and how to use them
-----------------------------------
-Starting from Intel Falcon Ridge Thunderbolt controller there are 4
+Starting with Intel Falcon Ridge Thunderbolt controller there are 4
security levels available. The reason for these is the fact that the
connected devices can be DMA masters and thus read contents of the host
memory without CPU and OS knowing about it. There are ways to prevent
@@ -37,14 +37,14 @@ The security levels are as follows:
user
User is asked whether the device is allowed to be connected.
Based on the device identification information available through
- ``/sys/bus/thunderbolt/devices``. user then can do the decision.
+ ``/sys/bus/thunderbolt/devices``, the user then can make the decision.
In BIOS settings this is typically called *Unique ID*.
secure
User is asked whether the device is allowed to be connected. In
addition to UUID the device (if it supports secure connect) is sent
a challenge that should match the expected one based on a random key
- written to ``key`` sysfs attribute. In BIOS settings this is
+ written to the ``key`` sysfs attribute. In BIOS settings this is
typically called *One time saved key*.
dponly
@@ -78,7 +78,7 @@ When a device is plugged in it will appear in sysfs as follows::
/sys/bus/thunderbolt/devices/0-1/unique_id - e0376f00-0300-0100-ffff-ffffffffffff
The ``authorized`` attribute reads 0 which means no PCIe tunnels are
-created yet. The user can authorize the device by simply::
+created yet. The user can authorize the device by simply entering::
# echo 1 > /sys/bus/thunderbolt/devices/0-1/authorized
@@ -86,7 +86,7 @@ This will create the PCIe tunnels and the device is now connected.
If the device supports secure connect, and the domain security level is
set to ``secure``, it has an additional attribute ``key`` which can hold
-a random 32 byte value used for authorization and challenging the device in
+a random 32-byte value used for authorization and challenging the device in
future connects::
/sys/bus/thunderbolt/devices/0-3/authorized - 0
@@ -99,12 +99,12 @@ future connects::
Notice the key is empty by default.
-If the user does not want to use secure connect it can just ``echo 1``
+If the user does not want to use secure connect they can just ``echo 1``
to the ``authorized`` attribute and the PCIe tunnels will be created in
-the same way than in ``user`` security level.
+the same way as in the ``user`` security level.
If the user wants to use secure connect, the first time the device is
-plugged a key needs to be created and send to the device::
+plugged a key needs to be created and sent to the device::
# key=$(openssl rand -hex 32)
# echo $key > /sys/bus/thunderbolt/devices/0-3/key
@@ -121,27 +121,27 @@ device using the same key::
If the challenge the device returns back matches the one we expect based
on the key, the device is connected and the PCIe tunnels are created.
-However, if the challenge failed no tunnels are created and error is
+However, if the challenge fails no tunnels are created and error is
returned to the user.
-If the user still wants to connect the device it can either approve
-the device without a key or write new key and write 1 to the
+If the user still wants to connect the device they can either approve
+the device without a key or write a new key and write 1 to the
``authorized`` file to get the new key stored on the device NVM.
Upgrading NVM on Thunderbolt device or host
-------------------------------------------
-Since most of the functionality is handled in a firmware running on a
+Since most of the functionality is handled in firmware running on a
host controller or a device, it is important that the firmware can be
upgraded to the latest where possible bugs in it have been fixed.
Typically OEMs provide this firmware from their support site.
-There is also a central site which has links where to download firmwares
+There is also a central site which has links where to download firmware
for some machines:
`Thunderbolt Updates <https://thunderbolttechnology.net/updates>`_
-Before you upgrade firmware on a device or host, please make sure it is
-the suitable. Failing to do that may render the device (or host) in a
+Before you upgrade firmware on a device or host, please make sure it is a
+suitable upgrade. Failing to do that may render the device (or host) in a
state where it cannot be used properly anymore without special tools!
Host NVM upgrade on Apple Macs is not supported.
@@ -151,7 +151,7 @@ Thunderbolt device so that the host controller appears. It does not
matter which device is connected (unless you are upgrading NVM on a
device - then you need to connect that particular device).
-Note OEM-specific method to power the controller up ("force power") may
+Note an OEM-specific method to power the controller up ("force power") may
be available for your system in which case there is no need to plug in a
Thunderbolt device.
@@ -171,7 +171,7 @@ it comes back the driver notices it and initiates a full power cycle.
After a while the host controller appears again and this time it should
be fully functional.
-We can verify that the new NVM firmware is active by running following
+We can verify that the new NVM firmware is active by running the following
commands::
# cat /sys/bus/thunderbolt/devices/0-0/nvm_authenticate
@@ -179,38 +179,38 @@ commands::
# cat /sys/bus/thunderbolt/devices/0-0/nvm_version
18.0
-If ``nvm_authenticate`` contains anything else than 0x0 it is the error
+If ``nvm_authenticate`` contains anything other than 0x0 it is the error
code from the last authentication cycle, which means the authentication
of the NVM image failed.
Note names of the NVMem devices ``nvm_activeN`` and ``nvm_non_activeN``
-depends on the order they are registered in the NVMem subsystem. N in
+depend on the order they are registered in the NVMem subsystem. N in
the name is the identifier added by the NVMem subsystem.
Upgrading NVM when host controller is in safe mode
--------------------------------------------------
If the existing NVM is not properly authenticated (or is missing) the
-host controller goes into safe mode which means that only available
-functionality is flashing new NVM image. When in this mode the reading
+host controller goes into safe mode which means that the only available
+functionality is flashing a new NVM image. When in this mode, reading
``nvm_version`` fails with ``ENODATA`` and the device identification
information is missing.
To recover from this mode, one needs to flash a valid NVM image to the
-host host controller in the same way it is done in the previous chapter.
+host controller in the same way it is done in the previous chapter.
Networking over Thunderbolt cable
---------------------------------
-Thunderbolt technology allows software communication across two hosts
+Thunderbolt technology allows software communication between two hosts
connected by a Thunderbolt cable.
-It is possible to tunnel any kind of traffic over Thunderbolt link but
+It is possible to tunnel any kind of traffic over a Thunderbolt link but
currently we only support Apple ThunderboltIP protocol.
-If the other host is running Windows or macOS only thing you need to
-do is to connect Thunderbolt cable between the two hosts, the
-``thunderbolt-net`` is loaded automatically. If the other host is also
-Linux you should load ``thunderbolt-net`` manually on one host (it does
-not matter which one)::
+If the other host is running Windows or macOS, the only thing you need to
+do is to connect a Thunderbolt cable between the two hosts; the
+``thunderbolt-net`` driver is loaded automatically. If the other host is
+also Linux you should load ``thunderbolt-net`` manually on one host (it
+does not matter which one)::
# modprobe thunderbolt-net
@@ -220,12 +220,12 @@ is built-in to the kernel image, there is no need to do anything.
The driver will create one virtual ethernet interface per Thunderbolt
port which are named like ``thunderbolt0`` and so on. From this point
you can either use standard userspace tools like ``ifconfig`` to
-configure the interface or let your GUI to handle it automatically.
+configure the interface or let your GUI handle it automatically.
Forcing power
-------------
Many OEMs include a method that can be used to force the power of a
-thunderbolt controller to an "On" state even if nothing is connected.
+Thunderbolt controller to an "On" state even if nothing is connected.
If supported by your machine this will be exposed by the WMI bus with
a sysfs attribute called "force_power".
diff --git a/Documentation/bpf/bpf_devel_QA.txt b/Documentation/bpf/bpf_devel_QA.txt
index cefef855dea4..84cbb302f2b5 100644
--- a/Documentation/bpf/bpf_devel_QA.txt
+++ b/Documentation/bpf/bpf_devel_QA.txt
@@ -516,4 +516,35 @@ A: LLVM has a -mcpu selector for the BPF back end in order to allow the
By the way, the BPF kernel selftests run with -mcpu=probe for better
test coverage.
+Q: In some cases clang flag "-target bpf" is used but in other cases the
+ default clang target, which matches the underlying architecture, is used.
+ What is the difference and when I should use which?
+
+A: Although LLVM IR generation and optimization try to stay architecture
+ independent, "-target <arch>" still has some impact on generated code:
+
+ - BPF program may recursively include header file(s) with file scope
+ inline assembly codes. The default target can handle this well,
+ while bpf target may fail if bpf backend assembler does not
+ understand these assembly codes, which is true in most cases.
+
+ - When compiled without -g, additional elf sections, e.g.,
+ .eh_frame and .rela.eh_frame, may be present in the object file
+ with default target, but not with bpf target.
+
+ - The default target may turn a C switch statement into a switch table
+ lookup and jump operation. Since the switch table is placed
+ in the global readonly section, the bpf program will fail to load.
+ The bpf target does not support switch table optimization.
+ The clang option "-fno-jump-tables" can be used to disable
+ switch table generation.
+
+ You should use default target when:
+
+ - Your program includes a header file, e.g., ptrace.h, which eventually
+ pulls in some header files containing file scope host assembly codes.
+ - You can add "-fno-jump-tables" to work around the switch table issue.
+
+ Otherwise, you can use bpf target.
+
Happy BPF hacking!
diff --git a/Documentation/devicetree/bindings/media/cec-gpio.txt b/Documentation/devicetree/bindings/media/cec-gpio.txt
index 46a0bac8b3b9..12fcd55ed153 100644
--- a/Documentation/devicetree/bindings/media/cec-gpio.txt
+++ b/Documentation/devicetree/bindings/media/cec-gpio.txt
@@ -4,6 +4,10 @@ The HDMI CEC GPIO module supports CEC implementations where the CEC line
is hooked up to a pull-up GPIO line and - optionally - the HPD line is
hooked up to another GPIO line.
+Please note: the maximum voltage for the CEC line is 3.63V, for the HPD
+line it is 5.3V. So you may need some sort of level conversion circuitry
+when connecting them to a GPIO line.
+
Required properties:
- compatible: value must be "cec-gpio".
- cec-gpios: gpio that the CEC line is connected to. The line should be
@@ -21,7 +25,7 @@ the following property is optional:
Example for the Raspberry Pi 3 where the CEC line is connected to
pin 26 aka BCM7 aka CE1 on the GPIO pin header and the HPD line is
-connected to pin 11 aka BCM17:
+connected to pin 11 aka BCM17 (some level shifter is needed for this!):
#include <dt-bindings/gpio/gpio.h>
diff --git a/Documentation/devicetree/bindings/media/i2c/mt9m111.txt b/Documentation/devicetree/bindings/media/i2c/mt9m111.txt
index ed5a334b1e57..6b910036b57e 100644
--- a/Documentation/devicetree/bindings/media/i2c/mt9m111.txt
+++ b/Documentation/devicetree/bindings/media/i2c/mt9m111.txt
@@ -6,6 +6,8 @@ interface.
Required Properties:
- compatible: value should be "micron,mt9m111"
+- clocks: reference to the master clock.
+- clock-names: shall be "mclk".
For further reading on port node refer to
Documentation/devicetree/bindings/media/video-interfaces.txt.
@@ -16,6 +18,8 @@ Example:
mt9m111@5d {
compatible = "micron,mt9m111";
reg = <0x5d>;
+ clocks = <&mclk>;
+ clock-names = "mclk";
remote = <&pxa_camera>;
port {
diff --git a/Documentation/devicetree/bindings/media/i2c/ov5640.txt b/Documentation/devicetree/bindings/media/i2c/ov5640.txt
index 540b36c4b1f2..8e36da0d8406 100644
--- a/Documentation/devicetree/bindings/media/i2c/ov5640.txt
+++ b/Documentation/devicetree/bindings/media/i2c/ov5640.txt
@@ -1,4 +1,4 @@
-* Omnivision OV5640 MIPI CSI-2 sensor
+* Omnivision OV5640 MIPI CSI-2 / parallel sensor
Required Properties:
- compatible: should be "ovti,ov5640"
@@ -18,7 +18,25 @@ The device node must contain one 'port' child node for its digital output
video port, in accordance with the video interface bindings defined in
Documentation/devicetree/bindings/media/video-interfaces.txt.
-Example:
+OV5640 can be connected to a MIPI CSI-2 bus or a parallel bus endpoint.
+
+Endpoint node required properties for CSI-2 connection are:
+- remote-endpoint: a phandle to the bus receiver's endpoint node.
+- clock-lanes: should be set to <0> (clock lane on hardware lane 0)
+- data-lanes: should be set to <1> or <1 2> (one or two CSI-2 lanes supported)
+
+Endpoint node required properties for parallel connection are:
+- remote-endpoint: a phandle to the bus receiver's endpoint node.
+- bus-width: shall be set to <8> for 8 bits parallel bus
+ or <10> for 10 bits parallel bus
+- data-shift: shall be set to <2> for 8 bits parallel bus
+ (lines 9:2 are used) or <0> for 10 bits parallel bus
+- hsync-active: active state of the HSYNC signal, 0/1 for LOW/HIGH respectively.
+- vsync-active: active state of the VSYNC signal, 0/1 for LOW/HIGH respectively.
+- pclk-sample: sample data on rising (1) or falling (0) edge of the pixel clock
+ signal.
+
+Examples:
&i2c1 {
ov5640: camera@3c {
@@ -35,6 +53,7 @@ Example:
reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
port {
+ /* MIPI CSI-2 bus endpoint */
ov5640_to_mipi_csi2: endpoint {
remote-endpoint = <&mipi_csi2_from_ov5640>;
clock-lanes = <0>;
@@ -43,3 +62,26 @@ Example:
};
};
};
+
+&i2c1 {
+ ov5640: camera@3c {
+ compatible = "ovti,ov5640";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ov5640>;
+ reg = <0x3c>;
+ clocks = <&clk_ext_camera>;
+ clock-names = "xclk";
+
+ port {
+ /* Parallel bus endpoint */
+ ov5640_to_parallel: endpoint {
+ remote-endpoint = <&parallel_from_ov5640>;
+ bus-width = <8>;
+ data-shift = <2>; /* lines 9:2 are used */
+ hsync-active = <0>;
+ vsync-active = <0>;
+ pclk-sample = <1>;
+ };
+ };
+ };
+};
diff --git a/Documentation/devicetree/bindings/media/i2c/ov7740.txt b/Documentation/devicetree/bindings/media/i2c/ov7740.txt
new file mode 100644
index 000000000000..af781c3a5f0e
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ov7740.txt
@@ -0,0 +1,47 @@
+* Omnivision OV7740 CMOS image sensor
+
+The Omnivision OV7740 image sensor supports multiple output image
+size, such as VGA, and QVGA, CIF and any size smaller. It also
+supports the RAW RGB and YUV output formats.
+
+The common video interfaces bindings (see video-interfaces.txt) should
+be used to specify link to the image data receiver. The OV7740 device
+node should contain one 'port' child node with an 'endpoint' subnode.
+
+Required Properties:
+- compatible: "ovti,ov7740".
+- reg: I2C slave address of the sensor.
+- clocks: Reference to the xvclk input clock.
+- clock-names: "xvclk".
+
+Optional Properties:
+- reset-gpios: Rreference to the GPIO connected to the reset_b pin,
+ if any. Active low with pull-ip resistor.
+- powerdown-gpios: Reference to the GPIO connected to the pwdn pin,
+ if any. Active high with pull-down resistor.
+
+Endpoint node mandatory properties:
+- remote-endpoint: A phandle to the bus receiver's endpoint node.
+
+Example:
+
+ i2c1: i2c@fc028000 {
+ ov7740: camera@21 {
+ compatible = "ovti,ov7740";
+ reg = <0x21>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sensor_power &pinctrl_sensor_reset>;
+ clocks = <&isc>;
+ clock-names = "xvclk";
+ assigned-clocks = <&isc>;
+ assigned-clock-rates = <24000000>;
+ reset-gpios = <&pioA 43 GPIO_ACTIVE_LOW>;
+ powerdown-gpios = <&pioA 44 GPIO_ACTIVE_HIGH>;
+
+ port {
+ ov7740_0: endpoint {
+ remote-endpoint = <&isc_0>;
+ };
+ };
+ };
+ };
diff --git a/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt b/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
index 0b7b6a4d84ff..e80d5891b7ed 100644
--- a/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
+++ b/Documentation/devicetree/bindings/media/i2c/toshiba,et8ek8.txt
@@ -20,6 +20,13 @@ Mandatory properties
is in hardware standby mode when the signal is in the low state.
+Optional properties
+-------------------
+
+- flash-leds: See ../video-interfaces.txt
+- lens-focus: See ../video-interfaces.txt
+
+
Endpoint node mandatory properties
----------------------------------
diff --git a/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
new file mode 100644
index 000000000000..470237ed6fe5
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
@@ -0,0 +1,55 @@
+NVIDIA Tegra Video Decoder Engine
+
+Required properties:
+- compatible : Must contain one of the following values:
+ - "nvidia,tegra20-vde"
+ - "nvidia,tegra30-vde"
+ - "nvidia,tegra114-vde"
+ - "nvidia,tegra124-vde"
+ - "nvidia,tegra132-vde"
+- reg : Must contain an entry for each entry in reg-names.
+- reg-names : Must include the following entries:
+ - sxe
+ - bsev
+ - mbe
+ - ppe
+ - mce
+ - tfe
+ - ppb
+ - vdma
+ - frameid
+- iram : Must contain phandle to the mmio-sram device node that represents
+ IRAM region used by VDE.
+- interrupts : Must contain an entry for each entry in interrupt-names.
+- interrupt-names : Must include the following entries:
+ - sync-token
+ - bsev
+ - sxe
+- clocks : Must include the following entries:
+ - vde
+- resets : Must include the following entries:
+ - vde
+
+Example:
+
+video-codec@6001a000 {
+ compatible = "nvidia,tegra20-vde";
+ reg = <0x6001a000 0x1000 /* Syntax Engine */
+ 0x6001b000 0x1000 /* Video Bitstream Engine */
+ 0x6001c000 0x100 /* Macroblock Engine */
+ 0x6001c200 0x100 /* Post-processing Engine */
+ 0x6001c400 0x100 /* Motion Compensation Engine */
+ 0x6001c600 0x100 /* Transform Engine */
+ 0x6001c800 0x100 /* Pixel prediction block */
+ 0x6001ca00 0x100 /* Video DMA */
+ 0x6001d800 0x300 /* Video frame controls */>;
+ reg-names = "sxe", "bsev", "mbe", "ppe", "mce",
+ "tfe", "ppb", "vdma", "frameid";
+ iram = <&vde_pool>; /* IRAM region */
+ interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, /* Sync token interrupt */
+ <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, /* BSE-V interrupt */
+ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; /* SXE interrupt */
+ interrupt-names = "sync-token", "bsev", "sxe";
+ clocks = <&tegra_car TEGRA20_CLK_VDE>;
+ resets = <&tegra_car 61>;
+};
diff --git a/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt b/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
index 9dd86b3db937..439351ab2a79 100644
--- a/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
+++ b/Documentation/devicetree/bindings/media/xilinx/xlnx,v-tpg.txt
@@ -66,6 +66,6 @@ Example:
tpg1_out: endpoint {
remote-endpoint = <&switch_in0>;
};
- }:
+ };
};
};
diff --git a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt
index 4e4aee4439ea..979dc7b6cfe8 100644
--- a/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/axis,artpec6-pcie.txt
@@ -4,7 +4,10 @@ This PCIe host controller is based on the Synopsys DesignWare PCIe IP
and thus inherits all the common properties defined in designware-pcie.txt.
Required properties:
-- compatible: "axis,artpec6-pcie", "snps,dw-pcie"
+- compatible: "axis,artpec6-pcie", "snps,dw-pcie" for ARTPEC-6 in RC mode;
+ "axis,artpec6-pcie-ep", "snps,dw-pcie" for ARTPEC-6 in EP mode;
+ "axis,artpec7-pcie", "snps,dw-pcie" for ARTPEC-7 in RC mode;
+ "axis,artpec7-pcie-ep", "snps,dw-pcie" for ARTPEC-7 in EP mode;
- reg: base addresses and lengths of the PCIe controller (DBI),
the PHY controller, and configuration address space.
- reg-names: Must include the following entries:
diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt
new file mode 100644
index 000000000000..9a305237fa6e
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt
@@ -0,0 +1,22 @@
+* Cadence PCIe endpoint controller
+
+Required properties:
+- compatible: Should contain "cdns,cdns-pcie-ep" to identify the IP used.
+- reg: Should contain the controller register base address and AXI interface
+ region base address respectively.
+- reg-names: Must be "reg" and "mem" respectively.
+- cdns,max-outbound-regions: Set to maximum number of outbound regions
+
+Optional properties:
+- max-functions: Maximum number of functions that can be configured (default 1).
+
+Example:
+
+pcie@fc000000 {
+ compatible = "cdns,cdns-pcie-ep";
+ reg = <0x0 0xfc000000 0x0 0x01000000>,
+ <0x0 0x80000000 0x0 0x40000000>;
+ reg-names = "reg", "mem";
+ cdns,max-outbound-regions = <16>;
+ max-functions = /bits/ 8 <8>;
+};
diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt
new file mode 100644
index 000000000000..20a33f38f69d
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt
@@ -0,0 +1,60 @@
+* Cadence PCIe host controller
+
+This PCIe controller inherits the base properties defined in
+host-generic-pci.txt.
+
+Required properties:
+- compatible: Should contain "cdns,cdns-pcie-host" to identify the IP used.
+- reg: Should contain the controller register base address, PCIe configuration
+ window base address, and AXI interface region base address respectively.
+- reg-names: Must be "reg", "cfg" and "mem" respectively.
+- #address-cells: Set to <3>
+- #size-cells: Set to <2>
+- device_type: Set to "pci"
+- ranges: Ranges for the PCI memory and I/O regions
+- #interrupt-cells: Set to <1>
+- interrupt-map-mask and interrupt-map: Standard PCI properties to define the
+ mapping of the PCIe interface to interrupt numbers.
+
+Optional properties:
+- cdns,max-outbound-regions: Set to maximum number of outbound regions
+ (default 32)
+- cdns,no-bar-match-nbits: Set into the no BAR match register to configure the
+ number of least significant bits kept during inbound (PCIe -> AXI) address
+ translations (default 32)
+- vendor-id: The PCI vendor ID (16 bits, default is design dependent)
+- device-id: The PCI device ID (16 bits, default is design dependent)
+
+Example:
+
+pcie@fb000000 {
+ compatible = "cdns,cdns-pcie-host";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ bus-range = <0x0 0xff>;
+ linux,pci-domain = <0>;
+ cdns,max-outbound-regions = <16>;
+ cdns,no-bar-match-nbits = <32>;
+ vendor-id = /bits/ 16 <0x17cd>;
+ device-id = /bits/ 16 <0x0200>;
+
+ reg = <0x0 0xfb000000 0x0 0x01000000>,
+ <0x0 0x41000000 0x0 0x00001000>,
+ <0x0 0x40000000 0x0 0x04000000>;
+ reg-names = "reg", "cfg", "mem";
+
+ ranges = <0x02000000 0x0 0x42000000 0x0 0x42000000 0x0 0x1000000>,
+ <0x01000000 0x0 0x43000000 0x0 0x43000000 0x0 0x0010000>;
+
+ #interrupt-cells = <0x1>;
+
+ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0x0 0x0 14 0x1
+ 0x0 0x0 0x0 0x2 &gic 0x0 0x0 0x0 15 0x1
+ 0x0 0x0 0x0 0x3 &gic 0x0 0x0 0x0 16 0x1
+ 0x0 0x0 0x0 0x4 &gic 0x0 0x0 0x0 17 0x1>;
+
+ interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+
+ msi-parent = <&its_pci>;
+};
diff --git a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
index 34a11bfbfb60..651d957d1051 100644
--- a/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
@@ -6,9 +6,6 @@ and thus inherits all the common properties defined in designware-pcie.txt.
Required properties:
- compatible: "samsung,exynos5440-pcie"
- reg: base addresses and lengths of the PCIe controller,
- the PHY controller, additional register for the PHY controller.
- (Registers for the PHY controller are DEPRECATED.
- Use the PHY framework.)
- reg-names : First name should be set to "elbi".
And use the "config" instead of getting the configuration address space
from "ranges".
@@ -23,49 +20,8 @@ For other common properties, refer to
Example:
-SoC-specific DT Entry:
+SoC-specific DT Entry (with using PHY framework):
- pcie@290000 {
- compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
- reg = <0x290000 0x1000
- 0x270000 0x1000
- 0x271000 0x40>;
- interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
- clocks = <&clock 28>, <&clock 27>;
- clock-names = "pcie", "pcie_bus";
- #address-cells = <3>;
- #size-cells = <2>;
- device_type = "pci";
- ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000 /* configuration space */
- 0x81000000 0 0 0x40001000 0 0x00010000 /* downstream I/O */
- 0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
- num-lanes = <4>;
- };
-
- pcie@2a0000 {
- compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
- reg = <0x2a0000 0x1000
- 0x272000 0x1000
- 0x271040 0x40>;
- interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
- clocks = <&clock 29>, <&clock 27>;
- clock-names = "pcie", "pcie_bus";
- #address-cells = <3>;
- #size-cells = <2>;
- device_type = "pci";
- ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000 /* configuration space */
- 0x81000000 0 0 0x60001000 0 0x00010000 /* downstream I/O */
- 0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
- #interrupt-cells = <1>;
- interrupt-map-mask = <0 0 0 0>;
- interrupt-map = <0 0 0 0 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
- num-lanes = <4>;
- };
-
-With using PHY framework:
pcie_phy0: pcie-phy@270000 {
...
reg = <0x270000 0x1000>, <0x271000 0x40>;
@@ -74,13 +30,21 @@ With using PHY framework:
};
pcie@290000 {
- ...
+ compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
reg = <0x290000 0x1000>, <0x40000000 0x1000>;
reg-names = "elbi", "config";
+ clocks = <&clock 28>, <&clock 27>;
+ clock-names = "pcie", "pcie_bus";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
phys = <&pcie_phy0>;
ranges = <0x81000000 0 0 0x60001000 0 0x00010000
0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>;
- ...
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0 0 0 0>;
+ interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ num-lanes = <4>;
};
Board-specific DT Entry:
diff --git a/Documentation/devicetree/bindings/pwm/pwm-meson.txt b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
index 1ee81321c35e..1fa3f7182133 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-meson.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
@@ -5,6 +5,8 @@ Required properties:
- compatible: Shall contain "amlogic,meson8b-pwm"
or "amlogic,meson-gxbb-pwm"
or "amlogic,meson-gxbb-ao-pwm"
+ or "amlogic,meson-axg-ee-pwm"
+ or "amlogic,meson-axg-ao-pwm"
- #pwm-cells: Should be 3. See pwm.txt in this directory for a description of
the cells format.
diff --git a/Documentation/devicetree/bindings/thermal/armada-thermal.txt b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
index 24aacf8948c5..e0d013a2e66d 100644
--- a/Documentation/devicetree/bindings/thermal/armada-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/armada-thermal.txt
@@ -2,22 +2,35 @@
Required properties:
-- compatible: Should be set to one of the following:
- marvell,armada370-thermal
- marvell,armada375-thermal
- marvell,armada380-thermal
- marvell,armadaxp-thermal
+- compatible: Should be set to one of the following:
+ * marvell,armada370-thermal
+ * marvell,armada375-thermal
+ * marvell,armada380-thermal
+ * marvell,armadaxp-thermal
+ * marvell,armada-ap806-thermal
+ * marvell,armada-cp110-thermal
-- reg: Device's register space.
- Two entries are expected, see the examples below.
- The first one is required for the sensor register;
- the second one is required for the control register
- to be used for sensor initialization (a.k.a. calibration).
+- reg: Device's register space.
+ Two entries are expected, see the examples below. The first one points
+ to the status register (4B). The second one points to the control
+ registers (8B).
+ Note: The compatibles marvell,armada370-thermal,
+ marvell,armada380-thermal, and marvell,armadaxp-thermal must point to
+ "control MSB/control 1", with size of 4 (deprecated binding), or point
+ to "control LSB/control 0" with size of 8 (current binding). All other
+ compatibles must point to "control LSB/control 0" with size of 8.
-Example:
+Examples:
+ /* Legacy bindings */
thermal@d0018300 {
compatible = "marvell,armada370-thermal";
- reg = <0xd0018300 0x4
+ reg = <0xd0018300 0x4
0xd0018304 0x4>;
};
+
+ ap_thermal: thermal@6f8084 {
+ compatible = "marvell,armada-ap806-thermal";
+ reg = <0x6f808C 0x4>,
+ <0x6f8084 0x8>;
+ };
diff --git a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
index a8e52c8ccfcc..349e635f2d87 100644
--- a/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
+++ b/Documentation/devicetree/bindings/thermal/rcar-thermal.txt
@@ -6,6 +6,7 @@ Required properties:
"renesas,rcar-thermal" (without thermal-zone) as fallback.
Examples with soctypes are:
- "renesas,thermal-r8a73a4" (R-Mobile APE6)
+ - "renesas,thermal-r8a7743" (RZ/G1M)
- "renesas,thermal-r8a7779" (R-Car H1)
- "renesas,thermal-r8a7790" (R-Car H2)
- "renesas,thermal-r8a7791" (R-Car M2-W)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index b1fa64a1d4d0..ae850d6c0ad3 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -125,6 +125,7 @@ focaltech FocalTech Systems Co.,Ltd
friendlyarm Guangzhou FriendlyARM Computer Tech Co., Ltd
fsl Freescale Semiconductor
fujitsu Fujitsu Ltd.
+gcw Game Consoles Worldwide
ge General Electric Company
geekbuying GeekBuying
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
diff --git a/Documentation/devicetree/bindings/watchdog/cortina,gemini-watchdog.txt b/Documentation/devicetree/bindings/watchdog/cortina,gemini-watchdog.txt
deleted file mode 100644
index bc4b865d178b..000000000000
--- a/Documentation/devicetree/bindings/watchdog/cortina,gemini-watchdog.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Cortina Systems Gemini SoC Watchdog
-
-Required properties:
-- compatible : must be "cortina,gemini-watchdog"
-- reg : shall contain base register location and length
-- interrupts : shall contain the interrupt for the watchdog
-
-Optional properties:
-- timeout-sec : the default watchdog timeout in seconds.
-
-Example:
-
-watchdog@41000000 {
- compatible = "cortina,gemini-watchdog";
- reg = <0x41000000 0x1000>;
- interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
-};
diff --git a/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt b/Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.txt
index bc4b865d178b..9ecdb502e605 100644
--- a/Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt
+++ b/Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.txt
@@ -1,7 +1,12 @@
-Cortina Systems Gemini SoC Watchdog
+Faraday Technology FTWDT010 watchdog
+
+This is an IP part from Faraday Technology found in the Gemini
+SoCs and others.
Required properties:
-- compatible : must be "cortina,gemini-watchdog"
+- compatible : must be one of
+ "faraday,ftwdt010"
+ "cortina,gemini-watchdog", "faraday,ftwdt010"
- reg : shall contain base register location and length
- interrupts : shall contain the interrupt for the watchdog
@@ -11,7 +16,7 @@ Optional properties:
Example:
watchdog@41000000 {
- compatible = "cortina,gemini-watchdog";
+ compatible = "faraday,ftwdt010";
reg = <0x41000000 0x1000>;
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
};
diff --git a/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt b/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt
index 3c7a1cd13b10..cb44918f01a8 100644
--- a/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/ingenic,jz4740-wdt.txt
@@ -1,7 +1,7 @@
-Ingenic Watchdog Timer (WDT) Controller for JZ4740
+Ingenic Watchdog Timer (WDT) Controller for JZ4740 & JZ4780
Required properties:
-compatible: "ingenic,jz4740-watchdog"
+compatible: "ingenic,jz4740-watchdog" or "ingenic,jz4780-watchdog"
reg: Register address and length for watchdog registers
Example:
diff --git a/Documentation/devicetree/bindings/watchdog/realtek,rtd119x.txt b/Documentation/devicetree/bindings/watchdog/realtek,rtd119x.txt
new file mode 100644
index 000000000000..05653054bd5b
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/realtek,rtd119x.txt
@@ -0,0 +1,17 @@
+Realtek RTD1295 Watchdog
+========================
+
+Required properties:
+
+- compatible : Should be "realtek,rtd1295-watchdog"
+- reg : Specifies the physical base address and size of registers
+- clocks : Specifies one clock input
+
+
+Example:
+
+ watchdog@98007680 {
+ compatible = "realtek,rtd1295-watchdog";
+ reg = <0x98007680 0x100>;
+ clocks = <&osc27M>;
+ };
diff --git a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
index bf6d1ca58af7..74b2f03c1515 100644
--- a/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/renesas-wdt.txt
@@ -4,10 +4,11 @@ Required properties:
- compatible : Should be "renesas,<soctype>-wdt", and
"renesas,rcar-gen3-wdt" or "renesas,rza-wdt" as fallback.
Examples with soctypes are:
+ - "renesas,r7s72100-wdt" (RZ/A1)
- "renesas,r8a7795-wdt" (R-Car H3)
- "renesas,r8a7796-wdt" (R-Car M3-W)
+ - "renesas,r8a77970-wdt" (R-Car V3M)
- "renesas,r8a77995-wdt" (R-Car D3)
- - "renesas,r7s72100-wdt" (RZ/A1)
When compatible with the generic version, nodes must list the SoC-specific
version corresponding to the platform first, followed by the generic
diff --git a/Documentation/devicetree/bindings/watchdog/sprd-wdt.txt b/Documentation/devicetree/bindings/watchdog/sprd-wdt.txt
new file mode 100644
index 000000000000..aeaf3e0caf47
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/sprd-wdt.txt
@@ -0,0 +1,19 @@
+Spreadtrum SoCs Watchdog timer
+
+Required properties:
+- compatible : Should be "sprd,sp9860-wdt".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : Exactly one interrupt specifier.
+- timeout-sec : Contain the default watchdog timeout in seconds.
+- clock-names : Contain the input clock names.
+- clocks : Phandles to input clocks.
+
+Example:
+ watchdog: watchdog@40310000 {
+ compatible = "sprd,sp9860-wdt";
+ reg = <0 0x40310000 0 0x1000>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-sec = <12>;
+ clock-names = "enable", "rtc_enable";
+ clocks = <&clk_aon_apb_gates1 8>, <&clk_aon_apb_rtc_gates 9>;
+ };
diff --git a/Documentation/filesystems/overlayfs.txt b/Documentation/filesystems/overlayfs.txt
index e6a5f4912b6d..6ea1e64d1464 100644
--- a/Documentation/filesystems/overlayfs.txt
+++ b/Documentation/filesystems/overlayfs.txt
@@ -190,6 +190,20 @@ Mount options:
Redirects are not created and not followed (equivalent to "redirect_dir=off"
if "redirect_always_follow" feature is not enabled).
+When the NFS export feature is enabled, every copied up directory is
+indexed by the file handle of the lower inode and a file handle of the
+upper directory is stored in a "trusted.overlay.upper" extended attribute
+on the index entry. On lookup of a merged directory, if the upper
+directory does not match the file handle stores in the index, that is an
+indication that multiple upper directories may be redirected to the same
+lower directory. In that case, lookup returns an error and warns about
+a possible inconsistency.
+
+Because lower layer redirects cannot be verified with the index, enabling
+NFS export support on an overlay filesystem with no upper layer requires
+turning off redirect follow (e.g. "redirect_dir=nofollow").
+
+
Non-directories
---------------
@@ -281,9 +295,9 @@ filesystem, so both st_dev and st_ino of the file may change.
Any open files referring to this inode will access the old data.
-If a file with multiple hard links is copied up, then this will
-"break" the link. Changes will not be propagated to other names
-referring to the same inode.
+Unless "inode index" feature is enabled, if a file with multiple hard
+links is copied up, then this will "break" the link. Changes will not be
+propagated to other names referring to the same inode.
Unless "redirect_dir" feature is enabled, rename(2) on a lower or merged
directory will fail with EXDEV.
@@ -299,6 +313,92 @@ filesystem are not allowed. If the underlying filesystem is changed,
the behavior of the overlay is undefined, though it will not result in
a crash or deadlock.
+When the overlay NFS export feature is enabled, overlay filesystems
+behavior on offline changes of the underlying lower layer is different
+than the behavior when NFS export is disabled.
+
+On every copy_up, an NFS file handle of the lower inode, along with the
+UUID of the lower filesystem, are encoded and stored in an extended
+attribute "trusted.overlay.origin" on the upper inode.
+
+When the NFS export feature is enabled, a lookup of a merged directory,
+that found a lower directory at the lookup path or at the path pointed
+to by the "trusted.overlay.redirect" extended attribute, will verify
+that the found lower directory file handle and lower filesystem UUID
+match the origin file handle that was stored at copy_up time. If a
+found lower directory does not match the stored origin, that directory
+will not be merged with the upper directory.
+
+
+
+NFS export
+----------
+
+When the underlying filesystems supports NFS export and the "nfs_export"
+feature is enabled, an overlay filesystem may be exported to NFS.
+
+With the "nfs_export" feature, on copy_up of any lower object, an index
+entry is created under the index directory. The index entry name is the
+hexadecimal representation of the copy up origin file handle. For a
+non-directory object, the index entry is a hard link to the upper inode.
+For a directory object, the index entry has an extended attribute
+"trusted.overlay.upper" with an encoded file handle of the upper
+directory inode.
+
+When encoding a file handle from an overlay filesystem object, the
+following rules apply:
+
+1. For a non-upper object, encode a lower file handle from lower inode
+2. For an indexed object, encode a lower file handle from copy_up origin
+3. For a pure-upper object and for an existing non-indexed upper object,
+ encode an upper file handle from upper inode
+
+The encoded overlay file handle includes:
+ - Header including path type information (e.g. lower/upper)
+ - UUID of the underlying filesystem
+ - Underlying filesystem encoding of underlying inode
+
+This encoding format is identical to the encoding format file handles that
+are stored in extended attribute "trusted.overlay.origin".
+
+When decoding an overlay file handle, the following steps are followed:
+
+1. Find underlying layer by UUID and path type information.
+2. Decode the underlying filesystem file handle to underlying dentry.
+3. For a lower file handle, lookup the handle in index directory by name.
+4. If a whiteout is found in index, return ESTALE. This represents an
+ overlay object that was deleted after its file handle was encoded.
+5. For a non-directory, instantiate a disconnected overlay dentry from the
+ decoded underlying dentry, the path type and index inode, if found.
+6. For a directory, use the connected underlying decoded dentry, path type
+ and index, to lookup a connected overlay dentry.
+
+Decoding a non-directory file handle may return a disconnected dentry.
+copy_up of that disconnected dentry will create an upper index entry with
+no upper alias.
+
+When overlay filesystem has multiple lower layers, a middle layer
+directory may have a "redirect" to lower directory. Because middle layer
+"redirects" are not indexed, a lower file handle that was encoded from the
+"redirect" origin directory, cannot be used to find the middle or upper
+layer directory. Similarly, a lower file handle that was encoded from a
+descendant of the "redirect" origin directory, cannot be used to
+reconstruct a connected overlay path. To mitigate the cases of
+directories that cannot be decoded from a lower file handle, these
+directories are copied up on encode and encoded as an upper file handle.
+On an overlay filesystem with no upper layer this mitigation cannot be
+used NFS export in this setup requires turning off redirect follow (e.g.
+"redirect_dir=nofollow").
+
+The overlay filesystem does not support non-directory connectable file
+handles, so exporting with the 'subtree_check' exportfs configuration will
+cause failures to lookup files over NFS.
+
+When the NFS export feature is enabled, all directory index entries are
+verified on mount time to check that upper file handles are not stale.
+This verification may cause significant overhead in some cases.
+
+
Testsuite
---------
diff --git a/Documentation/infiniband/user_verbs.txt b/Documentation/infiniband/user_verbs.txt
index e5092d696da2..df049b9f5b6e 100644
--- a/Documentation/infiniband/user_verbs.txt
+++ b/Documentation/infiniband/user_verbs.txt
@@ -5,7 +5,7 @@ USERSPACE VERBS ACCESS
described in chapter 11 of the InfiniBand Architecture Specification.
To use the verbs, the libibverbs library, available from
- http://www.openfabrics.org/, is required. libibverbs contains a
+ https://github.com/linux-rdma/rdma-core, is required. libibverbs contains a
device-independent API for using the ib_uverbs interface.
libibverbs also requires appropriate device-dependent kernel and
userspace driver for your InfiniBand hardware. For example, to use
diff --git a/Documentation/media/dmx.h.rst.exceptions b/Documentation/media/dmx.h.rst.exceptions
index 629db384104a..63f55a9ae2b1 100644
--- a/Documentation/media/dmx.h.rst.exceptions
+++ b/Documentation/media/dmx.h.rst.exceptions
@@ -54,3 +54,5 @@ ignore symbol DMX_OUT_DECODER
ignore symbol DMX_OUT_TAP
ignore symbol DMX_OUT_TS_TAP
ignore symbol DMX_OUT_TSDEMUX_TAP
+
+replace ioctl DMX_DQBUF dmx_qbuf
diff --git a/Documentation/media/kapi/cec-core.rst b/Documentation/media/kapi/cec-core.rst
index d37e107f2fde..62b9a1448177 100644
--- a/Documentation/media/kapi/cec-core.rst
+++ b/Documentation/media/kapi/cec-core.rst
@@ -103,6 +103,7 @@ your driver:
/* Low-level callbacks */
int (*adap_enable)(struct cec_adapter *adap, bool enable);
int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
+ int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg);
@@ -144,6 +145,19 @@ called if the CEC_CAP_MONITOR_ALL capability is set. This callback is optional
Note that adap_monitor_all_enable must return 0 if enable is false.
+To enable/disable the 'monitor pin' mode:
+
+.. c:function::
+ int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
+
+If enabled, then the adapter should be put in a mode to also monitor CEC pin
+changes. Not all hardware supports this and this function is only called if
+the CEC_CAP_MONITOR_PIN capability is set. This callback is optional
+(some hardware may always be in 'monitor pin' mode).
+
+Note that adap_monitor_pin_enable must return 0 if enable is false.
+
+
To program a new logical address:
.. c:function::
diff --git a/Documentation/media/kapi/dtv-ca.rst b/Documentation/media/kapi/dtv-ca.rst
index a4dd700189b0..fded096b937c 100644
--- a/Documentation/media/kapi/dtv-ca.rst
+++ b/Documentation/media/kapi/dtv-ca.rst
@@ -1,4 +1,4 @@
Digital TV Conditional Access kABI
----------------------------------
-.. kernel-doc:: drivers/media/dvb-core/dvb_ca_en50221.h
+.. kernel-doc:: include/media/dvb_ca_en50221.h
diff --git a/Documentation/media/kapi/dtv-common.rst b/Documentation/media/kapi/dtv-common.rst
index 40cf1033b5e1..7a9574f03190 100644
--- a/Documentation/media/kapi/dtv-common.rst
+++ b/Documentation/media/kapi/dtv-common.rst
@@ -7,7 +7,7 @@ Math functions
Provide some commonly-used math functions, usually required in order to
estimate signal strength and signal to noise measurements in dB.
-.. kernel-doc:: drivers/media/dvb-core/dvb_math.h
+.. kernel-doc:: include/media/dvb_math.h
DVB devices
@@ -15,7 +15,7 @@ DVB devices
Those functions are responsible for handling the DVB device nodes.
-.. kernel-doc:: drivers/media/dvb-core/dvbdev.h
+.. kernel-doc:: include/media/dvbdev.h
Digital TV Ring buffer
~~~~~~~~~~~~~~~~~~~~~~
@@ -52,4 +52,9 @@ copy it from/to userspace.
Resetting the buffer counts as a read and write operation.
Two or more writers must be locked against each other.
-.. kernel-doc:: drivers/media/dvb-core/dvb_ringbuffer.h
+.. kernel-doc:: include/media/dvb_ringbuffer.h
+
+Digital TV VB2 handler
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. kernel-doc:: include/media/dvb_vb2.h
diff --git a/Documentation/media/kapi/dtv-demux.rst b/Documentation/media/kapi/dtv-demux.rst
index 7aa865a2b43f..24857133e4e8 100644
--- a/Documentation/media/kapi/dtv-demux.rst
+++ b/Documentation/media/kapi/dtv-demux.rst
@@ -8,7 +8,7 @@ The Kernel Digital TV Demux kABI defines a driver-internal interface for
registering low-level, hardware specific driver to a hardware independent
demux layer. It is only of interest for Digital TV device driver writers.
The header file for this kABI is named ``demux.h`` and located in
-``drivers/media/dvb-core``.
+``include/media``.
The demux kABI should be implemented for each demux in the system. It is
used to select the TS source of a demux and to manage the demux resources.
@@ -69,14 +69,14 @@ callbacks.
Digital TV Demux device registration functions and data structures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. kernel-doc:: drivers/media/dvb-core/dmxdev.h
+.. kernel-doc:: include/media/dmxdev.h
High-level Digital TV demux interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. kernel-doc:: drivers/media/dvb-core/dvb_demux.h
+.. kernel-doc:: include/media/dvb_demux.h
Driver-internal low-level hardware specific driver demux interface
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. kernel-doc:: drivers/media/dvb-core/demux.h
+.. kernel-doc:: include/media/demux.h
diff --git a/Documentation/media/kapi/dtv-frontend.rst b/Documentation/media/kapi/dtv-frontend.rst
index f1a2fdaab5ba..472650cdb100 100644
--- a/Documentation/media/kapi/dtv-frontend.rst
+++ b/Documentation/media/kapi/dtv-frontend.rst
@@ -8,7 +8,7 @@ The Digital TV Frontend kABI defines a driver-internal interface for
registering low-level, hardware specific driver to a hardware independent
frontend layer. It is only of interest for Digital TV device driver writers.
The header file for this API is named ``dvb_frontend.h`` and located in
-``drivers/media/dvb-core``.
+``include/media/``.
Demodulator driver
^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ The demodulator driver is responsible to talk with the decoding part of the
hardware. Such driver should implement :c:type:`dvb_frontend_ops`, with
tells what type of digital TV standards are supported, and points to a
series of functions that allow the DVB core to command the hardware via
-the code under ``drivers/media/dvb-core/dvb_frontend.c``.
+the code under ``include/media/dvb_frontend.c``.
A typical example of such struct in a driver ``foo`` is::
@@ -118,7 +118,7 @@ Satellite TV reception is::
.. |delta| unicode:: U+00394
-The ``drivers/media/dvb-core/dvb_frontend.c`` has a kernel thread with is
+The ``include/media/dvb_frontend.c`` has a kernel thread with is
responsible for tuning the device. It supports multiple algorithms to
detect a channel, as defined at enum :c:func:`dvbfe_algo`.
@@ -440,4 +440,4 @@ monotonic stats at the right time.
Digital TV Frontend functions and types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. kernel-doc:: drivers/media/dvb-core/dvb_frontend.h
+.. kernel-doc:: include/media/dvb_frontend.h
diff --git a/Documentation/media/kapi/dtv-net.rst b/Documentation/media/kapi/dtv-net.rst
index ced991b73d69..158c7cbd7600 100644
--- a/Documentation/media/kapi/dtv-net.rst
+++ b/Documentation/media/kapi/dtv-net.rst
@@ -1,4 +1,4 @@
Digital TV Network kABI
-----------------------
-.. kernel-doc:: drivers/media/dvb-core/dvb_net.h
+.. kernel-doc:: include/media/dvb_net.h
diff --git a/Documentation/media/kapi/rc-core.rst b/Documentation/media/kapi/rc-core.rst
index a45895886257..4759f020d6b2 100644
--- a/Documentation/media/kapi/rc-core.rst
+++ b/Documentation/media/kapi/rc-core.rst
@@ -4,11 +4,83 @@ Remote Controller devices
Remote Controller core
~~~~~~~~~~~~~~~~~~~~~~
-.. kernel-doc:: include/media/rc-core.h
+The remote controller core implements infrastructure to receive and send
+remote controller keyboard keystrokes and mouse events.
-.. kernel-doc:: include/media/rc-map.h
+Every time a key is pressed on a remote controller, a scan code is produced.
+Also, on most hardware, keeping a key pressed for more than a few dozens of
+milliseconds produce a repeat key event. That's somewhat similar to what
+a normal keyboard or mouse is handled internally on Linux\ [#f1]_. So, the
+remote controller core is implemented on the top of the linux input/evdev
+interface.
+
+.. [#f1]
+
+ The main difference is that, on keyboard events, the keyboard controller
+ produces one event for a key press and another one for key release. On
+ infrared-based remote controllers, there's no key release event. Instead,
+ an extra code is produced to indicate key repeats.
+
+However, most of the remote controllers use infrared (IR) to transmit signals.
+As there are several protocols used to modulate infrared signals, one
+important part of the core is dedicated to adjust the driver and the core
+system to support the infrared protocol used by the emitter.
+
+The infrared transmission is done by blinking a infrared emitter using a
+carrier. The carrier can be switched on or off by the IR transmitter
+hardware. When the carrier is switched on, it is called *PULSE*.
+When the carrier is switched off, it is called *SPACE*.
+
+In other words, a typical IR transmission can be viewed as a sequence of
+*PULSE* and *SPACE* events, each with a given duration.
+
+The carrier parameters (frequency, duty cycle) and the intervals for
+*PULSE* and *SPACE* events depend on the protocol.
+For example, the NEC protocol uses a carrier of 38kHz, and transmissions
+start with a 9ms *PULSE* and a 4.5ms SPACE. It then transmits 16 bits of
+scan code, being 8 bits for address (usually it is a fixed number for a
+given remote controller), followed by 8 bits of code. A bit "1" is modulated
+with 560µs *PULSE* followed by 1690µs *SPACE* and a bit "0" is modulated
+with 560µs *PULSE* followed by 560µs *SPACE*.
+
+At receiver, a simple low-pass filter can be used to convert the received
+signal in a sequence of *PULSE/SPACE* events, filtering out the carrier
+frequency. Due to that, the receiver doesn't care about the carrier's
+actual frequency parameters: all it has to do is to measure the amount
+of time it receives *PULSE/SPACE* events.
+So, a simple IR receiver hardware will just provide a sequence of timings
+for those events to the Kernel. The drivers for hardware with such kind of
+receivers are identified by ``RC_DRIVER_IR_RAW``, as defined by
+:c:type:`rc_driver_type`\ [#f2]_. Other hardware come with a
+microcontroller that decode the *PULSE/SPACE* sequence and return scan
+codes to the Kernel. Such kind of receivers are identified
+by ``RC_DRIVER_SCANCODE``.
-LIRC
-~~~~
+.. [#f2]
-.. kernel-doc:: include/media/lirc_dev.h
+ The RC core also supports devices that have just IR emitters,
+ without any receivers. Right now, all such devices work only in
+ raw TX mode. Such kind of hardware is identified as
+ ``RC_DRIVER_IR_RAW_TX``.
+
+When the RC core receives events produced by ``RC_DRIVER_IR_RAW`` IR
+receivers, it needs to decode the IR protocol, in order to obtain the
+corresponding scan code. The protocols supported by the RC core are
+defined at enum :c:type:`rc_proto`.
+
+When the RC code receives a scan code (either directly, by a driver
+of the type ``RC_DRIVER_SCANCODE``, or via its IR decoders), it needs
+to convert into a Linux input event code. This is done via a mapping
+table.
+
+The Kernel has support for mapping tables available on most media
+devices. It also supports loading a table in runtime, via some
+sysfs nodes. See the :ref:`RC userspace API <Remote_controllers_Intro>`
+for more details.
+
+Remote controller data structures and functions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. kernel-doc:: include/media/rc-core.h
+
+.. kernel-doc:: include/media/rc-map.h
diff --git a/Documentation/media/kapi/v4l2-dev.rst b/Documentation/media/kapi/v4l2-dev.rst
index b29aa616c267..7bb0505b60f1 100644
--- a/Documentation/media/kapi/v4l2-dev.rst
+++ b/Documentation/media/kapi/v4l2-dev.rst
@@ -196,11 +196,18 @@ device.
Which device is registered depends on the type argument. The following
types exist:
-- ``VFL_TYPE_GRABBER``: ``/dev/videoX`` for video input/output devices
-- ``VFL_TYPE_VBI``: ``/dev/vbiX`` for vertical blank data (i.e. closed captions, teletext)
-- ``VFL_TYPE_RADIO``: ``/dev/radioX`` for radio tuners
-- ``VFL_TYPE_SDR``: ``/dev/swradioX`` for Software Defined Radio tuners
-- ``VFL_TYPE_TOUCH``: ``/dev/v4l-touchX`` for touch sensors
+========================== ==================== ==============================
+:c:type:`vfl_devnode_type` Device name Usage
+========================== ==================== ==============================
+``VFL_TYPE_GRABBER`` ``/dev/videoX`` for video input/output devices
+``VFL_TYPE_VBI`` ``/dev/vbiX`` for vertical blank data (i.e.
+ closed captions, teletext)
+``VFL_TYPE_RADIO`` ``/dev/radioX`` for radio tuners
+``VFL_TYPE_SUBDEV`` ``/dev/v4l-subdevX`` for V4L2 subdevices
+``VFL_TYPE_SDR`` ``/dev/swradioX`` for Software Defined Radio
+ (SDR) tuners
+``VFL_TYPE_TOUCH`` ``/dev/v4l-touchX`` for touch sensors
+========================== ==================== ==============================
The last argument gives you a certain amount of control over the device
device node number used (i.e. the X in ``videoX``). Normally you will pass -1
diff --git a/Documentation/media/kapi/v4l2-event.rst b/Documentation/media/kapi/v4l2-event.rst
index 9938d21ef4d1..5c7e31224ddc 100644
--- a/Documentation/media/kapi/v4l2-event.rst
+++ b/Documentation/media/kapi/v4l2-event.rst
@@ -5,27 +5,68 @@ V4L2 events
The V4L2 events provide a generic way to pass events to user space.
The driver must use :c:type:`v4l2_fh` to be able to support V4L2 events.
-Events are defined by a type and an optional ID. The ID may refer to a V4L2
-object such as a control ID. If unused, then the ID is 0.
+Events are subscribed per-filehandle. An event specification consists of a
+``type`` and is optionally associated with an object identified through the
+``id`` field. If unused, then the ``id`` is 0. So an event is uniquely
+identified by the ``(type, id)`` tuple.
-When the user subscribes to an event the driver will allocate a number of
-kevent structs for that event. So every (type, ID) event tuple will have
-its own set of kevent structs. This guarantees that if a driver is generating
-lots of events of one type in a short time, then that will not overwrite
-events of another type.
+The :c:type:`v4l2_fh` struct has a list of subscribed events on its
+``subscribed`` field.
-But if you get more events of one type than the number of kevents that were
-reserved, then the oldest event will be dropped and the new one added.
+When the user subscribes to an event, a :c:type:`v4l2_subscribed_event`
+struct is added to :c:type:`v4l2_fh`\ ``.subscribed``, one for every
+subscribed event.
+
+Each :c:type:`v4l2_subscribed_event` struct ends with a
+:c:type:`v4l2_kevent` ringbuffer, with the size given by the caller
+of :c:func:`v4l2_event_subscribe`. This ringbuffer is used to store any events
+raised by the driver.
+
+So every ``(type, ID)`` event tuple will have its own
+:c:type:`v4l2_kevent` ringbuffer. This guarantees that if a driver is
+generating lots of events of one type in a short time, then that will
+not overwrite events of another type.
+
+But if you get more events of one type than the size of the
+:c:type:`v4l2_kevent` ringbuffer, then the oldest event will be dropped
+and the new one added.
+
+The :c:type:`v4l2_kevent` struct links into the ``available``
+list of the :c:type:`v4l2_fh` struct so :ref:`VIDIOC_DQEVENT` will
+know which event to dequeue first.
+
+Finally, if the event subscription is associated with a particular object
+such as a V4L2 control, then that object needs to know about that as well
+so that an event can be raised by that object. So the ``node`` field can
+be used to link the :c:type:`v4l2_subscribed_event` struct into a list of
+such objects.
+
+So to summarize:
+
+- struct :c:type:`v4l2_fh` has two lists: one of the ``subscribed`` events,
+ and one of the ``available`` events.
+
+- struct :c:type:`v4l2_subscribed_event` has a ringbuffer of raised
+ (pending) events of that particular type.
+
+- If struct :c:type:`v4l2_subscribed_event` is associated with a specific
+ object, then that object will have an internal list of
+ struct :c:type:`v4l2_subscribed_event` so it knows who subscribed an
+ event to that object.
Furthermore, the internal struct :c:type:`v4l2_subscribed_event` has
``merge()`` and ``replace()`` callbacks which drivers can set. These
callbacks are called when a new event is raised and there is no more room.
+
The ``replace()`` callback allows you to replace the payload of the old event
with that of the new event, merging any relevant data from the old payload
into the new payload that replaces it. It is called when this event type has
-only one kevent struct allocated. The ``merge()`` callback allows you to merge
-the oldest event payload into that of the second-oldest event payload. It is
-called when there are two or more kevent structs allocated.
+a ringbuffer with size is one, i.e. only one event can be stored in the
+ringbuffer.
+
+The ``merge()`` callback allows you to merge the oldest event payload into
+that of the second-oldest event payload. It is called when
+the ringbuffer has size is greater than one.
This way no status information is lost, just the intermediate steps leading
up to that state.
@@ -73,7 +114,7 @@ The ops argument allows the driver to specify a number of callbacks:
Callback Description
======== ==============================================================
add called when a new listener gets added (subscribing to the same
- event twice will only cause this callback to get called once)
+ event twice will only cause this callback to get called once)
del called when a listener stops listening
replace replace event 'old' with event 'new'.
merge merge event 'old' into event 'new'.
diff --git a/Documentation/media/lirc.h.rst.exceptions b/Documentation/media/lirc.h.rst.exceptions
index c130617a9986..c6e3a35d2c4e 100644
--- a/Documentation/media/lirc.h.rst.exceptions
+++ b/Documentation/media/lirc.h.rst.exceptions
@@ -28,6 +28,36 @@ ignore define LIRC_CAN_SEND_MASK
ignore define LIRC_CAN_REC_MASK
ignore define LIRC_CAN_SET_REC_DUTY_CYCLE
+# Obsolete ioctls
+
+ignore ioctl LIRC_GET_LENGTH
+
+# rc protocols
+
+ignore symbol RC_PROTO_UNKNOWN
+ignore symbol RC_PROTO_OTHER
+ignore symbol RC_PROTO_RC5
+ignore symbol RC_PROTO_RC5X_20
+ignore symbol RC_PROTO_RC5_SZ
+ignore symbol RC_PROTO_JVC
+ignore symbol RC_PROTO_SONY12
+ignore symbol RC_PROTO_SONY15
+ignore symbol RC_PROTO_SONY20
+ignore symbol RC_PROTO_NEC
+ignore symbol RC_PROTO_NECX
+ignore symbol RC_PROTO_NEC32
+ignore symbol RC_PROTO_SANYO
+ignore symbol RC_PROTO_MCIR2_KBD
+ignore symbol RC_PROTO_MCIR2_MSE
+ignore symbol RC_PROTO_RC6_0
+ignore symbol RC_PROTO_RC6_6A_20
+ignore symbol RC_PROTO_RC6_6A_24
+ignore symbol RC_PROTO_RC6_6A_32
+ignore symbol RC_PROTO_RC6_MCE
+ignore symbol RC_PROTO_SHARP
+ignore symbol RC_PROTO_XMP
+ignore symbol RC_PROTO_CEC
+
# Undocumented macros
ignore define PULSE_BIT
@@ -40,3 +70,4 @@ ignore define LIRC_VALUE_MASK
ignore define LIRC_MODE2_MASK
ignore define LIRC_MODE_RAW
+ignore define LIRC_MODE_LIRCCODE
diff --git a/Documentation/media/uapi/dvb/dmx-expbuf.rst b/Documentation/media/uapi/dvb/dmx-expbuf.rst
new file mode 100644
index 000000000000..2d96cfe891df
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-expbuf.rst
@@ -0,0 +1,88 @@
+.. _DMX_EXPBUF:
+
+****************
+ioctl DMX_EXPBUF
+****************
+
+Name
+====
+
+DMX_EXPBUF - Export a buffer as a DMABUF file descriptor.
+
+.. warning:: this API is still experimental
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, DMX_EXPBUF, struct dmx_exportbuffer *argp )
+ :name: DMX_EXPBUF
+
+
+Arguments
+=========
+
+``fd``
+ File descriptor returned by :ref:`open() <dmx_fopen>`.
+
+``argp``
+ Pointer to struct :c:type:`dmx_exportbuffer`.
+
+
+Description
+===========
+
+This ioctl is an extension to the memory mapping I/O method.
+It can be used to export a buffer as a DMABUF file at any time after
+buffers have been allocated with the :ref:`DMX_REQBUFS` ioctl.
+
+To export a buffer, applications fill struct :c:type:`dmx_exportbuffer`.
+Applications must set the ``index`` field. Valid index numbers
+range from zero to the number of buffers allocated with :ref:`DMX_REQBUFS`
+(struct :c:type:`dmx_requestbuffers` ``count``) minus one.
+Additional flags may be posted in the ``flags`` field. Refer to a manual
+for open() for details. Currently only O_CLOEXEC, O_RDONLY, O_WRONLY,
+and O_RDWR are supported.
+All other fields must be set to zero. In the
+case of multi-planar API, every plane is exported separately using
+multiple :ref:`DMX_EXPBUF` calls.
+
+After calling :ref:`DMX_EXPBUF` the ``fd`` field will be set by a
+driver, on success. This is a DMABUF file descriptor. The application may
+pass it to other DMABUF-aware devices. It is recommended to close a DMABUF
+file when it is no longer used to allow the associated memory to be reclaimed.
+
+
+Examples
+========
+
+
+.. code-block:: c
+
+ int buffer_export(int v4lfd, enum dmx_buf_type bt, int index, int *dmafd)
+ {
+ struct dmx_exportbuffer expbuf;
+
+ memset(&expbuf, 0, sizeof(expbuf));
+ expbuf.type = bt;
+ expbuf.index = index;
+ if (ioctl(v4lfd, DMX_EXPBUF, &expbuf) == -1) {
+ perror("DMX_EXPBUF");
+ return -1;
+ }
+
+ *dmafd = expbuf.fd;
+
+ return 0;
+ }
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+EINVAL
+ A queue is not in MMAP mode or DMABUF exporting is not supported or
+ ``flags`` or ``index`` fields are invalid.
diff --git a/Documentation/media/uapi/dvb/dmx-mmap.rst b/Documentation/media/uapi/dvb/dmx-mmap.rst
new file mode 100644
index 000000000000..15d107348b9f
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-mmap.rst
@@ -0,0 +1,116 @@
+.. _dmx-mmap:
+
+*****************
+Digital TV mmap()
+*****************
+
+Name
+====
+
+dmx-mmap - Map device memory into application address space
+
+.. warning:: this API is still experimental
+
+Synopsis
+========
+
+.. code-block:: c
+
+ #include <unistd.h>
+ #include <sys/mman.h>
+
+
+.. c:function:: void *mmap( void *start, size_t length, int prot, int flags, int fd, off_t offset )
+ :name: dmx-mmap
+
+Arguments
+=========
+
+``start``
+ Map the buffer to this address in the application's address space.
+ When the ``MAP_FIXED`` flag is specified, ``start`` must be a
+ multiple of the pagesize and mmap will fail when the specified
+ address cannot be used. Use of this option is discouraged;
+ applications should just specify a ``NULL`` pointer here.
+
+``length``
+ Length of the memory area to map. This must be a multiple of the
+ DVB packet length (188, on most drivers).
+
+``prot``
+ The ``prot`` argument describes the desired memory protection.
+ Regardless of the device type and the direction of data exchange it
+ should be set to ``PROT_READ`` | ``PROT_WRITE``, permitting read
+ and write access to image buffers. Drivers should support at least
+ this combination of flags.
+
+``flags``
+ The ``flags`` parameter specifies the type of the mapped object,
+ mapping options and whether modifications made to the mapped copy of
+ the page are private to the process or are to be shared with other
+ references.
+
+ ``MAP_FIXED`` requests that the driver selects no other address than
+ the one specified. If the specified address cannot be used,
+ :ref:`mmap() <dmx-mmap>` will fail. If ``MAP_FIXED`` is specified,
+ ``start`` must be a multiple of the pagesize. Use of this option is
+ discouraged.
+
+ One of the ``MAP_SHARED`` or ``MAP_PRIVATE`` flags must be set.
+ ``MAP_SHARED`` allows applications to share the mapped memory with
+ other (e. g. child-) processes.
+
+ .. note::
+
+ The Linux Digital TV applications should not set the
+ ``MAP_PRIVATE``, ``MAP_DENYWRITE``, ``MAP_EXECUTABLE`` or ``MAP_ANON``
+ flags.
+
+``fd``
+ File descriptor returned by :ref:`open() <dmx_fopen>`.
+
+``offset``
+ Offset of the buffer in device memory, as returned by
+ :ref:`DMX_QUERYBUF` ioctl.
+
+
+Description
+===========
+
+The :ref:`mmap() <dmx-mmap>` function asks to map ``length`` bytes starting at
+``offset`` in the memory of the device specified by ``fd`` into the
+application address space, preferably at address ``start``. This latter
+address is a hint only, and is usually specified as 0.
+
+Suitable length and offset parameters are queried with the
+:ref:`DMX_QUERYBUF` ioctl. Buffers must be allocated with the
+:ref:`DMX_REQBUFS` ioctl before they can be queried.
+
+To unmap buffers the :ref:`munmap() <dmx-munmap>` function is used.
+
+
+Return Value
+============
+
+On success :ref:`mmap() <dmx-mmap>` returns a pointer to the mapped buffer. On
+error ``MAP_FAILED`` (-1) is returned, and the ``errno`` variable is set
+appropriately. Possible error codes are:
+
+EBADF
+ ``fd`` is not a valid file descriptor.
+
+EACCES
+ ``fd`` is not open for reading and writing.
+
+EINVAL
+ The ``start`` or ``length`` or ``offset`` are not suitable. (E. g.
+ they are too large, or not aligned on a ``PAGESIZE`` boundary.)
+
+ The ``flags`` or ``prot`` value is not supported.
+
+ No buffers have been allocated with the
+ :ref:`DMX_REQBUFS` ioctl.
+
+ENOMEM
+ Not enough physical or virtual memory was available to complete the
+ request.
diff --git a/Documentation/media/uapi/dvb/dmx-munmap.rst b/Documentation/media/uapi/dvb/dmx-munmap.rst
new file mode 100644
index 000000000000..d77218732bb6
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-munmap.rst
@@ -0,0 +1,54 @@
+.. _dmx-munmap:
+
+************
+DVB munmap()
+************
+
+Name
+====
+
+dmx-munmap - Unmap device memory
+
+.. warning:: This API is still experimental.
+
+
+Synopsis
+========
+
+.. code-block:: c
+
+ #include <unistd.h>
+ #include <sys/mman.h>
+
+
+.. c:function:: int munmap( void *start, size_t length )
+ :name: dmx-munmap
+
+Arguments
+=========
+
+``start``
+ Address of the mapped buffer as returned by the
+ :ref:`mmap() <dmx-mmap>` function.
+
+``length``
+ Length of the mapped buffer. This must be the same value as given to
+ :ref:`mmap() <dmx-mmap>`.
+
+
+Description
+===========
+
+Unmaps a previously with the :ref:`mmap() <dmx-mmap>` function mapped
+buffer and frees it, if possible.
+
+
+Return Value
+============
+
+On success :ref:`munmap() <dmx-munmap>` returns 0, on failure -1 and the
+``errno`` variable is set appropriately:
+
+EINVAL
+ The ``start`` or ``length`` is incorrect, or no buffers have been
+ mapped yet.
diff --git a/Documentation/media/uapi/dvb/dmx-qbuf.rst b/Documentation/media/uapi/dvb/dmx-qbuf.rst
new file mode 100644
index 000000000000..b48c4931658e
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-qbuf.rst
@@ -0,0 +1,83 @@
+.. _DMX_QBUF:
+
+*************************
+ioctl DMX_QBUF, DMX_DQBUF
+*************************
+
+Name
+====
+
+DMX_QBUF - DMX_DQBUF - Exchange a buffer with the driver
+
+.. warning:: this API is still experimental
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, DMX_QBUF, struct dmx_buffer *argp )
+ :name: DMX_QBUF
+
+.. c:function:: int ioctl( int fd, DMX_DQBUF, struct dmx_buffer *argp )
+ :name: DMX_DQBUF
+
+
+Arguments
+=========
+
+``fd``
+ File descriptor returned by :ref:`open() <dmx_fopen>`.
+
+``argp``
+ Pointer to struct :c:type:`dmx_buffer`.
+
+
+Description
+===========
+
+Applications call the ``DMX_QBUF`` ioctl to enqueue an empty
+(capturing) or filled (output) buffer in the driver's incoming queue.
+The semantics depend on the selected I/O method.
+
+To enqueue a buffer applications set the ``index`` field. Valid index
+numbers range from zero to the number of buffers allocated with
+:ref:`DMX_REQBUFS` (struct :c:type:`dmx_requestbuffers` ``count``) minus
+one. The contents of the struct :c:type:`dmx_buffer` returned
+by a :ref:`DMX_QUERYBUF` ioctl will do as well.
+
+When ``DMX_QBUF`` is called with a pointer to this structure, it locks the
+memory pages of the buffer in physical memory, so they cannot be swapped
+out to disk. Buffers remain locked until dequeued, until the
+the device is closed.
+
+Applications call the ``DMX_DQBUF`` ioctl to dequeue a filled
+(capturing) buffer from the driver's outgoing queue. They just set the ``reserved`` field array to zero. When ``DMX_DQBUF`` is called with a
+pointer to this structure, the driver fills the remaining fields or
+returns an error code.
+
+By default ``DMX_DQBUF`` blocks when no buffer is in the outgoing
+queue. When the ``O_NONBLOCK`` flag was given to the
+:ref:`open() <dmx_fopen>` function, ``DMX_DQBUF`` returns
+immediately with an ``EAGAIN`` error code when no buffer is available.
+
+The struct :c:type:`dmx_buffer` structure is specified in
+:ref:`buffer`.
+
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+EAGAIN
+ Non-blocking I/O has been selected using ``O_NONBLOCK`` and no
+ buffer was in the outgoing queue.
+
+EINVAL
+ The ``index`` is out of bounds, or no buffers have been allocated yet.
+
+EIO
+ ``DMX_DQBUF`` failed due to an internal error. Can also indicate
+ temporary problems like signal loss or CRC errors.
diff --git a/Documentation/media/uapi/dvb/dmx-querybuf.rst b/Documentation/media/uapi/dvb/dmx-querybuf.rst
new file mode 100644
index 000000000000..89481e24bb86
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-querybuf.rst
@@ -0,0 +1,63 @@
+.. _DMX_QUERYBUF:
+
+******************
+ioctl DMX_QUERYBUF
+******************
+
+Name
+====
+
+DMX_QUERYBUF - Query the status of a buffer
+
+.. warning:: this API is still experimental
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, DMX_QUERYBUF, struct dvb_buffer *argp )
+ :name: DMX_QUERYBUF
+
+
+Arguments
+=========
+
+``fd``
+ File descriptor returned by :ref:`open() <dmx_fopen>`.
+
+``argp``
+ Pointer to struct :c:type:`dvb_buffer`.
+
+
+Description
+===========
+
+This ioctl is part of the mmap streaming I/O method. It can
+be used to query the status of a buffer at any time after buffers have
+been allocated with the :ref:`DMX_REQBUFS` ioctl.
+
+Applications set the ``index`` field. Valid index numbers range from zero
+to the number of buffers allocated with :ref:`DMX_REQBUFS`
+(struct :c:type:`dvb_requestbuffers` ``count``) minus one.
+
+After calling :ref:`DMX_QUERYBUF` with a pointer to this structure,
+drivers return an error code or fill the rest of the structure.
+
+On success, the ``offset`` will contain the offset of the buffer from the
+start of the device memory, the ``length`` field its size, and the
+``bytesused`` the number of bytes occupied by data in the buffer (payload).
+
+Return Value
+============
+
+On success 0 is returned, the ``offset`` will contain the offset of the
+buffer from the start of the device memory, the ``length`` field its size,
+and the ``bytesused`` the number of bytes occupied by data in the buffer
+(payload).
+
+On error it returns -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+EINVAL
+ The ``index`` is out of bounds.
diff --git a/Documentation/media/uapi/dvb/dmx-reqbufs.rst b/Documentation/media/uapi/dvb/dmx-reqbufs.rst
new file mode 100644
index 000000000000..14b80d60bf35
--- /dev/null
+++ b/Documentation/media/uapi/dvb/dmx-reqbufs.rst
@@ -0,0 +1,74 @@
+.. _DMX_REQBUFS:
+
+*****************
+ioctl DMX_REQBUFS
+*****************
+
+Name
+====
+
+DMX_REQBUFS - Initiate Memory Mapping and/or DMA buffer I/O
+
+.. warning:: this API is still experimental
+
+
+Synopsis
+========
+
+.. c:function:: int ioctl( int fd, DMX_REQBUFS, struct dmx_requestbuffers *argp )
+ :name: DMX_REQBUFS
+
+
+Arguments
+=========
+
+``fd``
+ File descriptor returned by :ref:`open() <dmx_fopen>`.
+
+``argp``
+ Pointer to struct :c:type:`dmx_requestbuffers`.
+
+Description
+===========
+
+This ioctl is used to initiate a memory mapped or DMABUF based demux I/O.
+
+Memory mapped buffers are located in device memory and must be allocated
+with this ioctl before they can be mapped into the application's address
+space. User buffers are allocated by applications themselves, and this
+ioctl is merely used to switch the driver into user pointer I/O mode and
+to setup some internal structures. Similarly, DMABUF buffers are
+allocated by applications through a device driver, and this ioctl only
+configures the driver into DMABUF I/O mode without performing any direct
+allocation.
+
+To allocate device buffers applications initialize all fields of the
+struct :c:type:`dmx_requestbuffers` structure. They set the ``count`` field
+to the desired number of buffers, and ``size`` to the size of each
+buffer.
+
+When the ioctl is called with a pointer to this structure, the driver will
+attempt to allocate the requested number of buffers and it stores the actual
+number allocated in the ``count`` field. The ``count`` can be smaller than the number requested, even zero, when the driver runs out of free memory. A larger
+number is also possible when the driver requires more buffers to
+function correctly. The actual allocated buffer size can is returned
+at ``size``, and can be smaller than what's requested.
+
+When this I/O method is not supported, the ioctl returns an ``EOPNOTSUPP``
+error code.
+
+Applications can call :ref:`DMX_REQBUFS` again to change the number of
+buffers, however this cannot succeed when any buffers are still mapped.
+A ``count`` value of zero frees all buffers, after aborting or finishing
+any DMA in progress.
+
+
+Return Value
+============
+
+On success 0 is returned, on error -1 and the ``errno`` variable is set
+appropriately. The generic error codes are described at the
+:ref:`Generic Error Codes <gen-errors>` chapter.
+
+EOPNOTSUPP
+ The the requested I/O method is not supported.
diff --git a/Documentation/media/uapi/dvb/dmx_fcalls.rst b/Documentation/media/uapi/dvb/dmx_fcalls.rst
index a17289143220..4c391cf2554f 100644
--- a/Documentation/media/uapi/dvb/dmx_fcalls.rst
+++ b/Documentation/media/uapi/dvb/dmx_fcalls.rst
@@ -13,6 +13,8 @@ Demux Function Calls
dmx-fclose
dmx-fread
dmx-fwrite
+ dmx-mmap
+ dmx-munmap
dmx-start
dmx-stop
dmx-set-filter
@@ -22,3 +24,7 @@ Demux Function Calls
dmx-get-pes-pids
dmx-add-pid
dmx-remove-pid
+ dmx-reqbufs
+ dmx-querybuf
+ dmx-expbuf
+ dmx-qbuf
diff --git a/Documentation/media/uapi/dvb/fe_property_parameters.rst b/Documentation/media/uapi/dvb/fe_property_parameters.rst
index 6eef507fea50..3524dcae4604 100644
--- a/Documentation/media/uapi/dvb/fe_property_parameters.rst
+++ b/Documentation/media/uapi/dvb/fe_property_parameters.rst
@@ -987,3 +987,21 @@ Possible values: 0, 1, LNA_AUTO
1, LNA on
use the special macro LNA_AUTO to set LNA auto
+
+
+.. _DTV-SCRAMBLING-SEQUENCE-INDEX:
+
+DTV_SCRAMBLING_SEQUENCE_INDEX
+=============================
+
+Used on DVB-S2.
+
+This 18 bit field, when present, carries the index of the DVB-S2 physical
+layer scrambling sequence as defined in clause 5.5.4 of EN 302 307.
+There is no explicit signalling method to convey scrambling sequence index
+to the receiver. If S2 satellite delivery system descriptor is available
+it can be used to read the scrambling sequence index (EN 300 468 table 41).
+
+By default, gold scrambling sequence index 0 is used.
+
+The valid scrambling sequence index range is from 0 to 262142.
diff --git a/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst b/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst
index 1f40399c68ff..2929e6999a7a 100644
--- a/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst
+++ b/Documentation/media/uapi/dvb/frontend-property-satellite-systems.rst
@@ -60,6 +60,8 @@ following parameters:
- :ref:`DTV_STREAM_ID <DTV-STREAM-ID>`
+- :ref:`DTV_SCRAMBLING_SEQUENCE_INDEX <DTV-SCRAMBLING-SEQUENCE-INDEX>`
+
In addition, the :ref:`DTV QoS statistics <frontend-stat-properties>`
are also valid.
diff --git a/Documentation/media/uapi/rc/lirc-dev-intro.rst b/Documentation/media/uapi/rc/lirc-dev-intro.rst
index d1936eeb9ce0..3a74fec66d69 100644
--- a/Documentation/media/uapi/rc/lirc-dev-intro.rst
+++ b/Documentation/media/uapi/rc/lirc-dev-intro.rst
@@ -6,11 +6,12 @@
Introduction
************
-The LIRC device interface is a bi-directional interface for transporting
-raw IR data between userspace and kernelspace. Fundamentally, it is just
-a chardev (/dev/lircX, for X = 0, 1, 2, ...), with a number of standard
-struct file_operations defined on it. With respect to transporting raw
-IR data to and fro, the essential fops are read, write and ioctl.
+LIRC stands for Linux Infrared Remote Control. The LIRC device interface is
+a bi-directional interface for transporting raw IR and decoded scancodes
+data between userspace and kernelspace. Fundamentally, it is just a chardev
+(/dev/lircX, for X = 0, 1, 2, ...), with a number of standard struct
+file_operations defined on it. With respect to transporting raw IR and
+decoded scancodes to and fro, the essential fops are read, write and ioctl.
Example dmesg output upon a driver registering w/LIRC:
@@ -18,7 +19,7 @@ Example dmesg output upon a driver registering w/LIRC:
$ dmesg |grep lirc_dev
lirc_dev: IR Remote Control driver registered, major 248
- rc rc0: lirc_dev: driver ir-lirc-codec (mceusb) registered at minor = 0
+ rc rc0: lirc_dev: driver mceusb registered at minor = 0
What you should see for a chardev:
@@ -36,6 +37,43 @@ LIRC modes
LIRC supports some modes of receiving and sending IR codes, as shown
on the following table.
+.. _lirc-mode-scancode:
+.. _lirc-scancode-flag-toggle:
+.. _lirc-scancode-flag-repeat:
+
+``LIRC_MODE_SCANCODE``
+
+ This mode is for both sending and receiving IR.
+
+ For transmitting (aka sending), create a ``struct lirc_scancode`` with
+ the desired scancode set in the ``scancode`` member, :c:type:`rc_proto`
+ set the IR protocol, and all other members set to 0. Write this struct to
+ the lirc device.
+
+ For receiving, you read ``struct lirc_scancode`` from the lirc device,
+ with ``scancode`` set to the received scancode and the IR protocol
+ :c:type:`rc_proto`. If the scancode maps to a valid key code, this is set
+ in the ``keycode`` field, else it is set to ``KEY_RESERVED``.
+
+ The ``flags`` can have ``LIRC_SCANCODE_FLAG_TOGGLE`` set if the toggle
+ bit is set in protocols that support it (e.g. rc-5 and rc-6), or
+ ``LIRC_SCANCODE_FLAG_REPEAT`` for when a repeat is received for protocols
+ that support it (e.g. nec).
+
+ In the Sanyo and NEC protocol, if you hold a button on remote, rather than
+ repeating the entire scancode, the remote sends a shorter message with
+ no scancode, which just means button is held, a "repeat". When this is
+ received, the ``LIRC_SCANCODE_FLAG_REPEAT`` is set and the scancode and
+ keycode is repeated.
+
+ With nec, there is no way to distinguish "button hold" from "repeatedly
+ pressing the same button". The rc-5 and rc-6 protocols have a toggle bit.
+ When a button is released and pressed again, the toggle bit is inverted.
+ If the toggle bit is set, the ``LIRC_SCANCODE_FLAG_TOGGLE`` is set.
+
+ The ``timestamp`` field is filled with the time nanoseconds
+ (in ``CLOCK_MONOTONIC``) when the scancode was decoded.
+
.. _lirc-mode-mode2:
``LIRC_MODE_MODE2``
@@ -72,21 +110,6 @@ on the following table.
this packet will be sent, with the number of microseconds with
no IR.
-.. _lirc-mode-lirccode:
-
-``LIRC_MODE_LIRCCODE``
-
- This mode can be used for IR receive and send.
-
- The IR signal is decoded internally by the receiver, or encoded by the
- transmitter. The LIRC interface represents the scancode as byte string,
- which might not be a u32, it can be any length. The value is entirely
- driver dependent. This mode is used by some older lirc drivers.
-
- The length of each code depends on the driver, which can be retrieved
- with :ref:`lirc_get_length`. This length is used both
- for transmitting and receiving IR.
-
.. _lirc-mode-pulse:
``LIRC_MODE_PULSE``
@@ -99,3 +122,13 @@ on the following table.
of entries.
This mode is used only for IR send.
+
+
+**************************
+Remote Controller protocol
+**************************
+
+An enum :c:type:`rc_proto` in the :ref:`lirc_header` lists all the
+supported IR protocols:
+
+.. kernel-doc:: include/uapi/linux/lirc.h
diff --git a/Documentation/media/uapi/rc/lirc-func.rst b/Documentation/media/uapi/rc/lirc-func.rst
index 9b5a772ec96c..ddb4620de294 100644
--- a/Documentation/media/uapi/rc/lirc-func.rst
+++ b/Documentation/media/uapi/rc/lirc-func.rst
@@ -18,7 +18,6 @@ LIRC Function Reference
lirc-set-send-duty-cycle
lirc-get-timeout
lirc-set-rec-timeout
- lirc-get-length
lirc-set-rec-carrier
lirc-set-rec-carrier-range
lirc-set-send-carrier
diff --git a/Documentation/media/uapi/rc/lirc-get-features.rst b/Documentation/media/uapi/rc/lirc-get-features.rst
index 64f89a4f9d9c..889a8807037b 100644
--- a/Documentation/media/uapi/rc/lirc-get-features.rst
+++ b/Documentation/media/uapi/rc/lirc-get-features.rst
@@ -55,15 +55,24 @@ LIRC features
``LIRC_CAN_REC_MODE2``
- The driver is capable of receiving using
- :ref:`LIRC_MODE_MODE2 <lirc-mode-MODE2>`.
+ This is raw IR driver for receiving. This means that
+ :ref:`LIRC_MODE_MODE2 <lirc-mode-MODE2>` is used. This also implies
+ that :ref:`LIRC_MODE_SCANCODE <lirc-mode-SCANCODE>` is also supported,
+ as long as the kernel is recent enough. Use the
+ :ref:`lirc_set_rec_mode` to switch modes.
.. _LIRC-CAN-REC-LIRCCODE:
``LIRC_CAN_REC_LIRCCODE``
- The driver is capable of receiving using
- :ref:`LIRC_MODE_LIRCCODE <lirc-mode-LIRCCODE>`.
+ Unused. Kept just to avoid breaking uAPI.
+
+.. _LIRC-CAN-REC-SCANCODE:
+
+``LIRC_CAN_REC_SCANCODE``
+
+ This is a scancode driver for receiving. This means that
+ :ref:`LIRC_MODE_SCANCODE <lirc-mode-SCANCODE>` is used.
.. _LIRC-CAN-SET-SEND-CARRIER:
@@ -157,7 +166,10 @@ LIRC features
``LIRC_CAN_SEND_PULSE``
The driver supports sending (also called as IR blasting or IR TX) using
- :ref:`LIRC_MODE_PULSE <lirc-mode-pulse>`.
+ :ref:`LIRC_MODE_PULSE <lirc-mode-pulse>`. This implies that
+ :ref:`LIRC_MODE_SCANCODE <lirc-mode-SCANCODE>` is also supported for
+ transmit, as long as the kernel is recent enough. Use the
+ :ref:`lirc_set_send_mode` to switch modes.
.. _LIRC-CAN-SEND-MODE2:
@@ -170,8 +182,7 @@ LIRC features
``LIRC_CAN_SEND_LIRCCODE``
- The driver supports sending (also called as IR blasting or IR TX) using
- :ref:`LIRC_MODE_LIRCCODE <lirc-mode-LIRCCODE>`.
+ Unused. Kept just to avoid breaking uAPI.
Return Value
diff --git a/Documentation/media/uapi/rc/lirc-get-length.rst b/Documentation/media/uapi/rc/lirc-get-length.rst
deleted file mode 100644
index 3990af5de0e9..000000000000
--- a/Documentation/media/uapi/rc/lirc-get-length.rst
+++ /dev/null
@@ -1,44 +0,0 @@
-.. -*- coding: utf-8; mode: rst -*-
-
-.. _lirc_get_length:
-
-*********************
-ioctl LIRC_GET_LENGTH
-*********************
-
-Name
-====
-
-LIRC_GET_LENGTH - Retrieves the code length in bits.
-
-Synopsis
-========
-
-.. c:function:: int ioctl( int fd, LIRC_GET_LENGTH, __u32 *length )
- :name: LIRC_GET_LENGTH
-
-Arguments
-=========
-
-``fd``
- File descriptor returned by open().
-
-``length``
- length, in bits
-
-
-Description
-===========
-
-Retrieves the code length in bits (only for
-:ref:`LIRC_MODE_LIRCCODE <lirc-mode-lirccode>`).
-Reads on the device must be done in blocks matching the bit count.
-The bit could should be rounded up so that it matches full bytes.
-
-
-Return Value
-============
-
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
diff --git a/Documentation/media/uapi/rc/lirc-get-rec-mode.rst b/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
index a4eb6c0a26e9..2722118484fa 100644
--- a/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
+++ b/Documentation/media/uapi/rc/lirc-get-rec-mode.rst
@@ -10,15 +10,15 @@ ioctls LIRC_GET_REC_MODE and LIRC_SET_REC_MODE
Name
====
-LIRC_GET_REC_MODE/LIRC_SET_REC_MODE - Get/set supported receive modes.
+LIRC_GET_REC_MODE/LIRC_SET_REC_MODE - Get/set current receive mode.
Synopsis
========
-.. c:function:: int ioctl( int fd, LIRC_GET_REC_MODE, __u32 rx_modes)
+.. c:function:: int ioctl( int fd, LIRC_GET_REC_MODE, __u32 *mode)
:name: LIRC_GET_REC_MODE
-.. c:function:: int ioctl( int fd, LIRC_SET_REC_MODE, __u32 rx_modes)
+.. c:function:: int ioctl( int fd, LIRC_SET_REC_MODE, __u32 *mode)
:name: LIRC_SET_REC_MODE
Arguments
@@ -27,20 +27,41 @@ Arguments
``fd``
File descriptor returned by open().
-``rx_modes``
- Bitmask with the supported transmit modes.
+``mode``
+ Mode used for receive.
Description
===========
-Get/set supported receive modes. Only :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`
-and :ref:`LIRC_MODE_LIRCCODE <lirc-mode-lirccode>` are supported for IR
-receive. Use :ref:`lirc_get_features` to find out which modes the driver
-supports.
+Get and set the current receive mode. Only
+:ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>` and
+:ref:`LIRC_MODE_SCANCODE <lirc-mode-scancode>` are supported.
+Use :ref:`lirc_get_features` to find out which modes the driver supports.
Return Value
============
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+
+ - .. row 1
+
+ - ``ENODEV``
+
+ - Device not available.
+
+ - .. row 2
+
+ - ``ENOTTY``
+
+ - Device does not support receiving.
+
+ - .. row 3
+
+ - ``EINVAL``
+
+ - Invalid mode or invalid mode for this device.
diff --git a/Documentation/media/uapi/rc/lirc-get-send-mode.rst b/Documentation/media/uapi/rc/lirc-get-send-mode.rst
index a169b234290e..c44e61a79ad1 100644
--- a/Documentation/media/uapi/rc/lirc-get-send-mode.rst
+++ b/Documentation/media/uapi/rc/lirc-get-send-mode.rst
@@ -10,15 +10,15 @@ ioctls LIRC_GET_SEND_MODE and LIRC_SET_SEND_MODE
Name
====
-LIRC_GET_SEND_MODE/LIRC_SET_SEND_MODE - Get/set supported transmit mode.
+LIRC_GET_SEND_MODE/LIRC_SET_SEND_MODE - Get/set current transmit mode.
Synopsis
========
-.. c:function:: int ioctl( int fd, LIRC_GET_SEND_MODE, __u32 *tx_modes )
+.. c:function:: int ioctl( int fd, LIRC_GET_SEND_MODE, __u32 *mode )
:name: LIRC_GET_SEND_MODE
-.. c:function:: int ioctl( int fd, LIRC_SET_SEND_MODE, __u32 *tx_modes )
+.. c:function:: int ioctl( int fd, LIRC_SET_SEND_MODE, __u32 *mode )
:name: LIRC_SET_SEND_MODE
Arguments
@@ -27,8 +27,8 @@ Arguments
``fd``
File descriptor returned by open().
-``tx_modes``
- Bitmask with the supported transmit modes.
+``mode``
+ The mode used for transmitting.
Description
@@ -37,13 +37,35 @@ Description
Get/set current transmit mode.
Only :ref:`LIRC_MODE_PULSE <lirc-mode-pulse>` and
-:ref:`LIRC_MODE_LIRCCODE <lirc-mode-lirccode>` is supported by for IR send,
+:ref:`LIRC_MODE_SCANCODE <lirc-mode-scancode>` are supported by for IR send,
depending on the driver. Use :ref:`lirc_get_features` to find out which
modes the driver supports.
Return Value
============
-On success 0 is returned, on error -1 and the ``errno`` variable is set
-appropriately. The generic error codes are described at the
-:ref:`Generic Error Codes <gen-errors>` chapter.
+
+.. tabularcolumns:: |p{2.5cm}|p{15.0cm}|
+
+.. flat-table::
+ :header-rows: 0
+ :stub-columns: 0
+
+
+ - .. row 1
+
+ - ``ENODEV``
+
+ - Device not available.
+
+ - .. row 2
+
+ - ``ENOTTY``
+
+ - Device does not support transmitting.
+
+ - .. row 3
+
+ - ``EINVAL``
+
+ - Invalid mode or invalid mode for this device.
diff --git a/Documentation/media/uapi/rc/lirc-read.rst b/Documentation/media/uapi/rc/lirc-read.rst
index ff14a69104e5..c024aaffb8ad 100644
--- a/Documentation/media/uapi/rc/lirc-read.rst
+++ b/Documentation/media/uapi/rc/lirc-read.rst
@@ -45,13 +45,20 @@ descriptor ``fd`` into the buffer starting at ``buf``. If ``count`` is zero,
is greater than ``SSIZE_MAX``, the result is unspecified.
The exact format of the data depends on what :ref:`lirc_modes` a driver
-uses. Use :ref:`lirc_get_features` to get the supported mode.
+uses. Use :ref:`lirc_get_features` to get the supported mode, and use
+:ref:`lirc_set_rec_mode` set the current active mode.
-The generally preferred mode for receive is
-:ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>`,
-in which packets containing an int value describing an IR signal are
+The mode :ref:`LIRC_MODE_MODE2 <lirc-mode-mode2>` is for raw IR,
+in which packets containing an unsigned int value describing an IR signal are
read from the chardev.
+Alternatively, :ref:`LIRC_MODE_SCANCODE <lirc-mode-scancode>` can be available,
+in this mode scancodes which are either decoded by software decoders, or
+by hardware decoders. The :c:type:`rc_proto` member is set to the
+protocol used for transmission, and ``scancode`` to the decoded scancode,
+and the ``keycode`` set to the keycode or ``KEY_RESERVED``.
+
+
Return Value
============
diff --git a/Documentation/media/uapi/rc/lirc-write.rst b/Documentation/media/uapi/rc/lirc-write.rst
index 2aad0fef4a5b..d4566b0a2015 100644
--- a/Documentation/media/uapi/rc/lirc-write.rst
+++ b/Documentation/media/uapi/rc/lirc-write.rst
@@ -42,21 +42,32 @@ Description
referenced by the file descriptor ``fd`` from the buffer starting at
``buf``.
-The exact format of the data depends on what mode a driver uses, use
-:ref:`lirc_get_features` to get the supported mode.
+The exact format of the data depends on what mode a driver is in, use
+:ref:`lirc_get_features` to get the supported modes and use
+:ref:`lirc_set_send_mode` set the mode.
When in :ref:`LIRC_MODE_PULSE <lirc-mode-PULSE>` mode, the data written to
the chardev is a pulse/space sequence of integer values. Pulses and spaces
are only marked implicitly by their position. The data must start and end
with a pulse, therefore, the data must always include an uneven number of
-samples. The write function must block until the data has been transmitted
+samples. The write function blocks until the data has been transmitted
by the hardware. If more data is provided than the hardware can send, the
driver returns ``EINVAL``.
+When in :ref:`LIRC_MODE_SCANCODE <lirc-mode-scancode>` mode, one
+``struct lirc_scancode`` must be written to the chardev at a time, else
+``EINVAL`` is returned. Set the desired scancode in the ``scancode`` member,
+and the protocol in the :c:type:`rc_proto`: member. All other members must be
+set to 0, else ``EINVAL`` is returned. If there is no protocol encoder
+for the protocol or the scancode is not valid for the specified protocol,
+``EINVAL`` is returned. The write function blocks until the scancode
+is transmitted by the hardware.
+
+
Return Value
============
-On success, the number of bytes read is returned. It is not an error if
+On success, the number of bytes written is returned. It is not an error if
this number is smaller than the number of bytes requested, or the amount
of data required for one frame. On error, -1 is returned, and the ``errno``
variable is set appropriately. The generic error codes are described at the
diff --git a/Documentation/media/uapi/v4l/meta-formats.rst b/Documentation/media/uapi/v4l/meta-formats.rst
index 01e24e3df571..0c4e1ecf5879 100644
--- a/Documentation/media/uapi/v4l/meta-formats.rst
+++ b/Documentation/media/uapi/v4l/meta-formats.rst
@@ -12,5 +12,6 @@ These formats are used for the :ref:`metadata` interface only.
.. toctree::
:maxdepth: 1
+ pixfmt-meta-uvc
pixfmt-meta-vsp1-hgo
pixfmt-meta-vsp1-hgt
diff --git a/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst b/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst
new file mode 100644
index 000000000000..b5165dc090c2
--- /dev/null
+++ b/Documentation/media/uapi/v4l/pixfmt-meta-uvc.rst
@@ -0,0 +1,51 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _v4l2-meta-fmt-uvc:
+
+*******************************
+V4L2_META_FMT_UVC ('UVCH')
+*******************************
+
+UVC Payload Header Data
+
+
+Description
+===========
+
+This format describes standard UVC metadata, extracted from UVC packet headers
+and provided by the UVC driver through metadata video nodes. That data includes
+exact copies of the standard part of UVC Payload Header contents and auxiliary
+timing information, required for precise interpretation of timestamps, contained
+in those headers. See section "2.4.3.3 Video and Still Image Payload Headers" of
+the "UVC 1.5 Class specification" for details.
+
+Each UVC payload header can be between 2 and 12 bytes large. Buffers can
+contain multiple headers, if multiple such headers have been transmitted by the
+camera for the respective frame. However, the driver may drop headers when the
+buffer is full, when they contain no useful information (e.g. those without the
+SCR field or with that field identical to the previous header), or generally to
+perform rate limiting when the device sends a large number of headers.
+
+Each individual block contains the following fields:
+
+.. flat-table:: UVC Metadata Block
+ :widths: 1 4
+ :header-rows: 1
+ :stub-columns: 0
+
+ * - Field
+ - Description
+ * - __u64 ts;
+ - system timestamp in host byte order, measured by the driver upon
+ reception of the payload
+ * - __u16 sof;
+ - USB Frame Number in host byte order, also obtained by the driver as
+ close as possible to the above timestamp to enable correlation between
+ them
+ * - :cspan:`1` *The rest is an exact copy of the UVC payload header:*
+ * - __u8 length;
+ - length of the rest of the block, including this field
+ * - __u8 flags;
+ - Flags, indicating presence of other standard UVC fields
+ * - __u8 buf[];
+ - The rest of the header, possibly including UVC PTS and SCR fields
diff --git a/Documentation/media/uapi/v4l/pixfmt-rgb.rst b/Documentation/media/uapi/v4l/pixfmt-rgb.rst
index 4cc27195dc79..cf2ef7df9616 100644
--- a/Documentation/media/uapi/v4l/pixfmt-rgb.rst
+++ b/Documentation/media/uapi/v4l/pixfmt-rgb.rst
@@ -16,6 +16,7 @@ RGB Formats
pixfmt-srggb10p
pixfmt-srggb10alaw8
pixfmt-srggb10dpcm8
+ pixfmt-srggb10-ipu3
pixfmt-srggb12
pixfmt-srggb12p
pixfmt-srggb16
diff --git a/Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst b/Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst
new file mode 100644
index 000000000000..99cde5077519
--- /dev/null
+++ b/Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst
@@ -0,0 +1,335 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+.. _v4l2-pix-fmt-ipu3-sbggr10:
+.. _v4l2-pix-fmt-ipu3-sgbrg10:
+.. _v4l2-pix-fmt-ipu3-sgrbg10:
+.. _v4l2-pix-fmt-ipu3-srggb10:
+
+**********************************************************************************************************************************************
+V4L2_PIX_FMT_IPU3_SBGGR10 ('ip3b'), V4L2_PIX_FMT_IPU3_SGBRG10 ('ip3g'), V4L2_PIX_FMT_IPU3_SGRBG10 ('ip3G'), V4L2_PIX_FMT_IPU3_SRGGB10 ('ip3r')
+**********************************************************************************************************************************************
+
+10-bit Bayer formats
+
+Description
+===========
+
+These four pixel formats are used by Intel IPU3 driver, they are raw
+sRGB / Bayer formats with 10 bits per sample with every 25 pixels packed
+to 32 bytes leaving 6 most significant bits padding in the last byte.
+The format is little endian.
+
+In other respects this format is similar to :ref:`V4L2-PIX-FMT-SRGGB10`.
+Below is an example of a small image in V4L2_PIX_FMT_IPU3_SBGGR10 format.
+
+**Byte Order.**
+Each cell is one byte.
+
+.. tabularcolumns:: |p{0.8cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}|p{4.0cm}|
+
+.. flat-table::
+
+ * - start + 0:
+ - B\ :sub:`0000low`
+ - G\ :sub:`0001low`\ (bits 7--2)
+
+ B\ :sub:`0000high`\ (bits 1--0)
+ - B\ :sub:`0002low`\ (bits 7--4)
+
+ G\ :sub:`0001high`\ (bits 3--0)
+ - G\ :sub:`0003low`\ (bits 7--6)
+
+ B\ :sub:`0002high`\ (bits 5--0)
+ * - start + 4:
+ - G\ :sub:`0003high`
+ - B\ :sub:`0004low`
+ - G\ :sub:`0005low`\ (bits 7--2)
+
+ B\ :sub:`0004high`\ (bits 1--0)
+ - B\ :sub:`0006low`\ (bits 7--4)
+
+ G\ :sub:`0005high`\ (bits 3--0)
+ * - start + 8:
+ - G\ :sub:`0007low`\ (bits 7--6)
+
+ B\ :sub:`0006high`\ (bits 5--0)
+ - G\ :sub:`0007high`
+ - B\ :sub:`0008low`
+ - G\ :sub:`0009low`\ (bits 7--2)
+
+ B\ :sub:`0008high`\ (bits 1--0)
+ * - start + 12:
+ - B\ :sub:`0010low`\ (bits 7--4)
+
+ G\ :sub:`0009high`\ (bits 3--0)
+ - G\ :sub:`0011low`\ (bits 7--6)
+
+ B\ :sub:`0010high`\ (bits 5--0)
+ - G\ :sub:`0011high`
+ - B\ :sub:`0012low`
+ * - start + 16:
+ - G\ :sub:`0013low`\ (bits 7--2)
+
+ B\ :sub:`0012high`\ (bits 1--0)
+ - B\ :sub:`0014low`\ (bits 7--4)
+
+ G\ :sub:`0013high`\ (bits 3--0)
+ - G\ :sub:`0015low`\ (bits 7--6)
+
+ B\ :sub:`0014high`\ (bits 5--0)
+ - G\ :sub:`0015high`
+ * - start + 20
+ - B\ :sub:`0016low`
+ - G\ :sub:`0017low`\ (bits 7--2)
+
+ B\ :sub:`0016high`\ (bits 1--0)
+ - B\ :sub:`0018low`\ (bits 7--4)
+
+ G\ :sub:`0017high`\ (bits 3--0)
+ - G\ :sub:`0019low`\ (bits 7--6)
+
+ B\ :sub:`0018high`\ (bits 5--0)
+ * - start + 24:
+ - G\ :sub:`0019high`
+ - B\ :sub:`0020low`
+ - G\ :sub:`0021low`\ (bits 7--2)
+
+ B\ :sub:`0020high`\ (bits 1--0)
+ - B\ :sub:`0022low`\ (bits 7--4)
+
+ G\ :sub:`0021high`\ (bits 3--0)
+ * - start + 28:
+ - G\ :sub:`0023low`\ (bits 7--6)
+
+ B\ :sub:`0022high`\ (bits 5--0)
+ - G\ :sub:`0023high`
+ - B\ :sub:`0024low`
+ - B\ :sub:`0024high`\ (bits 1--0)
+ * - start + 32:
+ - G\ :sub:`0100low`
+ - R\ :sub:`0101low`\ (bits 7--2)
+
+ G\ :sub:`0100high`\ (bits 1--0)
+ - G\ :sub:`0102low`\ (bits 7--4)
+
+ R\ :sub:`0101high`\ (bits 3--0)
+ - R\ :sub:`0103low`\ (bits 7--6)
+
+ G\ :sub:`0102high`\ (bits 5--0)
+ * - start + 36:
+ - R\ :sub:`0103high`
+ - G\ :sub:`0104low`
+ - R\ :sub:`0105low`\ (bits 7--2)
+
+ G\ :sub:`0104high`\ (bits 1--0)
+ - G\ :sub:`0106low`\ (bits 7--4)
+
+ R\ :sub:`0105high`\ (bits 3--0)
+ * - start + 40:
+ - R\ :sub:`0107low`\ (bits 7--6)
+
+ G\ :sub:`0106high`\ (bits 5--0)
+ - R\ :sub:`0107high`
+ - G\ :sub:`0108low`
+ - R\ :sub:`0109low`\ (bits 7--2)
+
+ G\ :sub:`0108high`\ (bits 1--0)
+ * - start + 44:
+ - G\ :sub:`0110low`\ (bits 7--4)
+
+ R\ :sub:`0109high`\ (bits 3--0)
+ - R\ :sub:`0111low`\ (bits 7--6)
+
+ G\ :sub:`0110high`\ (bits 5--0)
+ - R\ :sub:`0111high`
+ - G\ :sub:`0112low`
+ * - start + 48:
+ - R\ :sub:`0113low`\ (bits 7--2)
+
+ G\ :sub:`0112high`\ (bits 1--0)
+ - G\ :sub:`0114low`\ (bits 7--4)
+
+ R\ :sub:`0113high`\ (bits 3--0)
+ - R\ :sub:`0115low`\ (bits 7--6)
+
+ G\ :sub:`0114high`\ (bits 5--0)
+ - R\ :sub:`0115high`
+ * - start + 52:
+ - G\ :sub:`0116low`
+ - R\ :sub:`0117low`\ (bits 7--2)
+
+ G\ :sub:`0116high`\ (bits 1--0)
+ - G\ :sub:`0118low`\ (bits 7--4)
+
+ R\ :sub:`0117high`\ (bits 3--0)
+ - R\ :sub:`0119low`\ (bits 7--6)
+
+ G\ :sub:`0118high`\ (bits 5--0)
+ * - start + 56:
+ - R\ :sub:`0119high`
+ - G\ :sub:`0120low`
+ - R\ :sub:`0121low`\ (bits 7--2)
+
+ G\ :sub:`0120high`\ (bits 1--0)
+ - G\ :sub:`0122low`\ (bits 7--4)
+
+ R\ :sub:`0121high`\ (bits 3--0)
+ * - start + 60:
+ - R\ :sub:`0123low`\ (bits 7--6)
+
+ G\ :sub:`0122high`\ (bits 5--0)
+ - R\ :sub:`0123high`
+ - G\ :sub:`0124low`
+ - G\ :sub:`0124high`\ (bits 1--0)
+ * - start + 64:
+ - B\ :sub:`0200low`
+ - G\ :sub:`0201low`\ (bits 7--2)
+
+ B\ :sub:`0200high`\ (bits 1--0)
+ - B\ :sub:`0202low`\ (bits 7--4)
+
+ G\ :sub:`0201high`\ (bits 3--0)
+ - G\ :sub:`0203low`\ (bits 7--6)
+
+ B\ :sub:`0202high`\ (bits 5--0)
+ * - start + 68:
+ - G\ :sub:`0203high`
+ - B\ :sub:`0204low`
+ - G\ :sub:`0205low`\ (bits 7--2)
+
+ B\ :sub:`0204high`\ (bits 1--0)
+ - B\ :sub:`0206low`\ (bits 7--4)
+
+ G\ :sub:`0205high`\ (bits 3--0)
+ * - start + 72:
+ - G\ :sub:`0207low`\ (bits 7--6)
+
+ B\ :sub:`0206high`\ (bits 5--0)
+ - G\ :sub:`0207high`
+ - B\ :sub:`0208low`
+ - G\ :sub:`0209low`\ (bits 7--2)
+
+ B\ :sub:`0208high`\ (bits 1--0)
+ * - start + 76:
+ - B\ :sub:`0210low`\ (bits 7--4)
+
+ G\ :sub:`0209high`\ (bits 3--0)
+ - G\ :sub:`0211low`\ (bits 7--6)
+
+ B\ :sub:`0210high`\ (bits 5--0)
+ - G\ :sub:`0211high`
+ - B\ :sub:`0212low`
+ * - start + 80:
+ - G\ :sub:`0213low`\ (bits 7--2)
+
+ B\ :sub:`0212high`\ (bits 1--0)
+ - B\ :sub:`0214low`\ (bits 7--4)
+
+ G\ :sub:`0213high`\ (bits 3--0)
+ - G\ :sub:`0215low`\ (bits 7--6)
+
+ B\ :sub:`0214high`\ (bits 5--0)
+ - G\ :sub:`0215high`
+ * - start + 84:
+ - B\ :sub:`0216low`
+ - G\ :sub:`0217low`\ (bits 7--2)
+
+ B\ :sub:`0216high`\ (bits 1--0)
+ - B\ :sub:`0218low`\ (bits 7--4)
+
+ G\ :sub:`0217high`\ (bits 3--0)
+ - G\ :sub:`0219low`\ (bits 7--6)
+
+ B\ :sub:`0218high`\ (bits 5--0)
+ * - start + 88:
+ - G\ :sub:`0219high`
+ - B\ :sub:`0220low`
+ - G\ :sub:`0221low`\ (bits 7--2)
+
+ B\ :sub:`0220high`\ (bits 1--0)
+ - B\ :sub:`0222low`\ (bits 7--4)
+
+ G\ :sub:`0221high`\ (bits 3--0)
+ * - start + 92:
+ - G\ :sub:`0223low`\ (bits 7--6)
+
+ B\ :sub:`0222high`\ (bits 5--0)
+ - G\ :sub:`0223high`
+ - B\ :sub:`0224low`
+ - B\ :sub:`0224high`\ (bits 1--0)
+ * - start + 96:
+ - G\ :sub:`0300low`
+ - R\ :sub:`0301low`\ (bits 7--2)
+
+ G\ :sub:`0300high`\ (bits 1--0)
+ - G\ :sub:`0302low`\ (bits 7--4)
+
+ R\ :sub:`0301high`\ (bits 3--0)
+ - R\ :sub:`0303low`\ (bits 7--6)
+
+ G\ :sub:`0302high`\ (bits 5--0)
+ * - start + 100:
+ - R\ :sub:`0303high`
+ - G\ :sub:`0304low`
+ - R\ :sub:`0305low`\ (bits 7--2)
+
+ G\ :sub:`0304high`\ (bits 1--0)
+ - G\ :sub:`0306low`\ (bits 7--4)
+
+ R\ :sub:`0305high`\ (bits 3--0)
+ * - start + 104:
+ - R\ :sub:`0307low`\ (bits 7--6)
+
+ G\ :sub:`0306high`\ (bits 5--0)
+ - R\ :sub:`0307high`
+ - G\ :sub:`0308low`
+ - R\ :sub:`0309low`\ (bits 7--2)
+
+ G\ :sub:`0308high`\ (bits 1--0)
+ * - start + 108:
+ - G\ :sub:`0310low`\ (bits 7--4)
+
+ R\ :sub:`0309high`\ (bits 3--0)
+ - R\ :sub:`0311low`\ (bits 7--6)
+
+ G\ :sub:`0310high`\ (bits 5--0)
+ - R\ :sub:`0311high`
+ - G\ :sub:`0312low`
+ * - start + 112:
+ - R\ :sub:`0313low`\ (bits 7--2)
+
+ G\ :sub:`0312high`\ (bits 1--0)
+ - G\ :sub:`0314low`\ (bits 7--4)
+
+ R\ :sub:`0313high`\ (bits 3--0)
+ - R\ :sub:`0315low`\ (bits 7--6)
+
+ G\ :sub:`0314high`\ (bits 5--0)
+ - R\ :sub:`0315high`
+ * - start + 116:
+ - G\ :sub:`0316low`
+ - R\ :sub:`0317low`\ (bits 7--2)
+
+ G\ :sub:`0316high`\ (bits 1--0)
+ - G\ :sub:`0318low`\ (bits 7--4)
+
+ R\ :sub:`0317high`\ (bits 3--0)
+ - R\ :sub:`0319low`\ (bits 7--6)
+
+ G\ :sub:`0318high`\ (bits 5--0)
+ * - start + 120:
+ - R\ :sub:`0319high`
+ - G\ :sub:`0320low`
+ - R\ :sub:`0321low`\ (bits 7--2)
+
+ G\ :sub:`0320high`\ (bits 1--0)
+ - G\ :sub:`0322low`\ (bits 7--4)
+
+ R\ :sub:`0321high`\ (bits 3--0)
+ * - start + 124:
+ - R\ :sub:`0323low`\ (bits 7--6)
+
+ G\ :sub:`0322high`\ (bits 5--0)
+ - R\ :sub:`0323high`
+ - G\ :sub:`0324low`
+ - G\ :sub:`0324high`\ (bits 1--0)
diff --git a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst
index 2696380626d4..1a034e825161 100644
--- a/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst
+++ b/Documentation/media/uapi/v4l/vidioc-g-dv-timings.rst
@@ -267,7 +267,7 @@ EBUSY
will also be cleared.
* - ``V4L2_DV_FL_HALF_LINE``
- Specific to interlaced formats: if set, then the vertical
- frontporch of field 1 (aka the odd field) is really one half-line
+ backporch of field 1 (aka the odd field) is really one half-line
longer and the vertical backporch of field 2 (aka the even field)
is really one half-line shorter, so each field has exactly the
same number of half-lines. Whether half-lines can be detected or
diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README
index 52844a58cc8a..ff675a1b1422 100644
--- a/Documentation/mips/AU1xxx_IDE.README
+++ b/Documentation/mips/AU1xxx_IDE.README
@@ -56,8 +56,6 @@ Following extra configs variables are introduced:
CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA - enable the PIO+DBDMA mode
CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - enable the MWDMA mode
- CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - set Burstable FIFO in DBDMA
- controller
SUPPORTED IDE MODES
@@ -82,11 +80,9 @@ CONFIG_IDE_GENERIC=y
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_BLK_DEV_GENERIC=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_BLK_DEV_IDE_AU1XXX=y
CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y
CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_AUTO=y
Also define 'IDE_AU1XXX_BURSTMODE' in 'drivers/ide/mips/au1xxx-ide.c' to enable
the burst support on DBDMA controller.
@@ -94,16 +90,13 @@ the burst support on DBDMA controller.
If the used system need the USB support enable the following kernel configs for
high IDE to USB throughput.
-CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDE_GENERIC=y
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_BLK_DEV_GENERIC=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_BLK_DEV_IDE_AU1XXX=y
CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA=y
CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_AUTO=y
Also undefine 'IDE_AU1XXX_BURSTMODE' in 'drivers/ide/mips/au1xxx-ide.c' to
disable the burst support on DBDMA controller.
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 3f2c40d8e6aa..a553d4e4a0fb 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -508,7 +508,7 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
min: Minimal size of receive buffer used by TCP sockets.
It is guaranteed to each TCP socket, even under moderate memory
pressure.
- Default: 1 page
+ Default: 4K
default: initial size of receive buffer used by TCP sockets.
This value overrides net.core.rmem_default used by other protocols.
@@ -667,7 +667,7 @@ tcp_window_scaling - BOOLEAN
tcp_wmem - vector of 3 INTEGERs: min, default, max
min: Amount of memory reserved for send buffers for TCP sockets.
Each TCP socket has rights to use it due to fact of its birth.
- Default: 1 page
+ Default: 4K
default: initial size of send buffer used by TCP sockets. This
value overrides net.core.wmem_default used by other protocols.
diff --git a/Documentation/process/index.rst b/Documentation/process/index.rst
index a430f6eee756..1c9fe657ed01 100644
--- a/Documentation/process/index.rst
+++ b/Documentation/process/index.rst
@@ -24,6 +24,7 @@ Below are the essential guides that every developer should read.
development-process
submitting-patches
coding-style
+ maintainer-pgp-guide
email-clients
kernel-enforcement-statement
kernel-driver-statement
diff --git a/Documentation/process/kernel-docs.rst b/Documentation/process/kernel-docs.rst
index b8cac85a4001..3fb28de556e4 100644
--- a/Documentation/process/kernel-docs.rst
+++ b/Documentation/process/kernel-docs.rst
@@ -58,7 +58,7 @@ On-line docs
* Title: **Linux Kernel Mailing List Glossary**
:Author: various
- :URL: http://kernelnewbies.org/glossary/
+ :URL: https://kernelnewbies.org/KernelGlossary
:Date: rolling version
:Keywords: glossary, terms, linux-kernel.
:Description: From the introduction: "This glossary is intended as
diff --git a/Documentation/process/maintainer-pgp-guide.rst b/Documentation/process/maintainer-pgp-guide.rst
new file mode 100644
index 000000000000..b453561a7148
--- /dev/null
+++ b/Documentation/process/maintainer-pgp-guide.rst
@@ -0,0 +1,929 @@
+.. _pgpguide:
+
+===========================
+Kernel Maintainer PGP guide
+===========================
+
+:Author: Konstantin Ryabitsev <konstantin@linuxfoundation.org>
+
+This document is aimed at Linux kernel developers, and especially at
+subsystem maintainers. It contains a subset of information discussed in
+the more general "`Protecting Code Integrity`_" guide published by the
+Linux Foundation. Please read that document for more in-depth discussion
+on some of the topics mentioned in this guide.
+
+.. _`Protecting Code Integrity`: https://github.com/lfit/itpol/blob/master/protecting-code-integrity.md
+
+The role of PGP in Linux Kernel development
+===========================================
+
+PGP helps ensure the integrity of the code that is produced by the Linux
+kernel development community and, to a lesser degree, establish trusted
+communication channels between developers via PGP-signed email exchange.
+
+The Linux kernel source code is available in two main formats:
+
+- Distributed source repositories (git)
+- Periodic release snapshots (tarballs)
+
+Both git repositories and tarballs carry PGP signatures of the kernel
+developers who create official kernel releases. These signatures offer a
+cryptographic guarantee that downloadable versions made available via
+kernel.org or any other mirrors are identical to what these developers
+have on their workstations. To this end:
+
+- git repositories provide PGP signatures on all tags
+- tarballs provide detached PGP signatures with all downloads
+
+.. _devs_not_infra:
+
+Trusting the developers, not infrastructure
+-------------------------------------------
+
+Ever since the 2011 compromise of core kernel.org systems, the main
+operating principle of the Kernel Archives project has been to assume
+that any part of the infrastructure can be compromised at any time. For
+this reason, the administrators have taken deliberate steps to emphasize
+that trust must always be placed with developers and never with the code
+hosting infrastructure, regardless of how good the security practices
+for the latter may be.
+
+The above guiding principle is the reason why this guide is needed. We
+want to make sure that by placing trust into developers we do not simply
+shift the blame for potential future security incidents to someone else.
+The goal is to provide a set of guidelines developers can use to create
+a secure working environment and safeguard the PGP keys used to
+establish the integrity of the Linux kernel itself.
+
+.. _pgp_tools:
+
+PGP tools
+=========
+
+Use GnuPG v2
+------------
+
+Your distro should already have GnuPG installed by default, you just
+need to verify that you are using version 2.x and not the legacy 1.4
+release -- many distributions still package both, with the default
+``gpg`` command invoking GnuPG v.1. To check, run::
+
+ $ gpg --version | head -n1
+
+If you see ``gpg (GnuPG) 1.4.x``, then you are using GnuPG v.1. Try the
+``gpg2`` command (if you don't have it, you may need to install the
+gnupg2 package)::
+
+ $ gpg2 --version | head -n1
+
+If you see ``gpg (GnuPG) 2.x.x``, then you are good to go. This guide
+will assume you have the version 2.2 of GnuPG (or later). If you are
+using version 2.0 of GnuPG, then some of the commands in this guide will
+not work, and you should consider installing the latest 2.2 version of
+GnuPG. Versions of gnupg-2.1.11 and later should be compatible for the
+purposes of this guide as well.
+
+If you have both ``gpg`` and ``gpg2`` commands, you should make sure you
+are always using GnuPG v2, not the legacy version. You can enforce this
+by setting the appropriate alias::
+
+ $ alias gpg=gpg2
+
+You can put that in your ``.bashrc`` to make sure it's always the case.
+
+Configure gpg-agent options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The GnuPG agent is a helper tool that will start automatically whenever
+you use the ``gpg`` command and run in the background with the purpose
+of caching the private key passphrase. There are two options you should
+know in order to tweak when the passphrase should be expired from cache:
+
+- ``default-cache-ttl`` (seconds): If you use the same key again before
+ the time-to-live expires, the countdown will reset for another period.
+ The default is 600 (10 minutes).
+- ``max-cache-ttl`` (seconds): Regardless of how recently you've used
+ the key since initial passphrase entry, if the maximum time-to-live
+ countdown expires, you'll have to enter the passphrase again. The
+ default is 30 minutes.
+
+If you find either of these defaults too short (or too long), you can
+edit your ``~/.gnupg/gpg-agent.conf`` file to set your own values::
+
+ # set to 30 minutes for regular ttl, and 2 hours for max ttl
+ default-cache-ttl 1800
+ max-cache-ttl 7200
+
+.. note::
+
+ It is no longer necessary to start gpg-agent manually at the
+ beginning of your shell session. You may want to check your rc files
+ to remove anything you had in place for older versions of GnuPG, as
+ it may not be doing the right thing any more.
+
+Set up a refresh cronjob
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+You will need to regularly refresh your keyring in order to get the
+latest changes on other people's public keys, which is best done with a
+daily cronjob::
+
+ @daily /usr/bin/gpg2 --refresh >/dev/null 2>&1
+
+Check the full path to your ``gpg`` or ``gpg2`` command and use the
+``gpg2`` command if regular ``gpg`` for you is the legacy GnuPG v.1.
+
+.. _master_key:
+
+Protect your master PGP key
+===========================
+
+This guide assumes that you already have a PGP key that you use for Linux
+kernel development purposes. If you do not yet have one, please see the
+"`Protecting Code Integrity`_" document mentioned earlier for guidance
+on how to create a new one.
+
+You should also make a new key if your current one is weaker than 2048 bits
+(RSA).
+
+Master key vs. Subkeys
+----------------------
+
+Subkeys are fully independent PGP keypairs that are tied to the "master"
+key using certifying key signatures (certificates). It is important to
+understand the following:
+
+1. There are no technical differences between the "master key" and "subkeys."
+2. At creation time, we assign functional limitations to each key by
+ giving it specific capabilities.
+3. A PGP key can have 4 capabilities:
+
+ - **[S]** key can be used for signing
+ - **[E]** key can be used for encryption
+ - **[A]** key can be used for authentication
+ - **[C]** key can be used for certifying other keys
+
+4. A single key may have multiple capabilities.
+5. A subkey is fully independent from the master key. A message
+ encrypted to a subkey cannot be decrypted with the master key. If you
+ lose your private subkey, it cannot be recreated from the master key
+ in any way.
+
+The key carrying the **[C]** (certify) capability is considered the
+"master" key because it is the only key that can be used to indicate
+relationship with other keys. Only the **[C]** key can be used to:
+
+- add or revoke other keys (subkeys) with S/E/A capabilities
+- add, change or revoke identities (uids) associated with the key
+- add or change the expiration date on itself or any subkey
+- sign other people's keys for web of trust purposes
+
+By default, GnuPG creates the following when generating new keys:
+
+- A master key carrying both Certify and Sign capabilities (**[SC]**)
+- A separate subkey with the Encryption capability (**[E]**)
+
+If you used the default parameters when generating your key, then that
+is what you will have. You can verify by running ``gpg --list-secret-keys``,
+for example::
+
+ sec rsa2048 2018-01-23 [SC] [expires: 2020-01-23]
+ 000000000000000000000000AAAABBBBCCCCDDDD
+ uid [ultimate] Alice Dev <adev@kernel.org>
+ ssb rsa2048 2018-01-23 [E] [expires: 2020-01-23]
+
+Any key carrying the **[C]** capability is your master key, regardless
+of any other capabilities it may have assigned to it.
+
+The long line under the ``sec`` entry is your key fingerprint --
+whenever you see ``[fpr]`` in the examples below, that 40-character
+string is what it refers to.
+
+Ensure your passphrase is strong
+--------------------------------
+
+GnuPG uses passphrases to encrypt your private keys before storing them on
+disk. This way, even if your ``.gnupg`` directory is leaked or stolen in
+its entirety, the attackers cannot use your private keys without first
+obtaining the passphrase to decrypt them.
+
+It is absolutely essential that your private keys are protected by a
+strong passphrase. To set it or change it, use::
+
+ $ gpg --change-passphrase [fpr]
+
+Create a separate Signing subkey
+--------------------------------
+
+Our goal is to protect your master key by moving it to offline media, so
+if you only have a combined **[SC]** key, then you should create a separate
+signing subkey::
+
+ $ gpg --quick-add-key [fpr] ed25519 sign
+
+Remember to tell the keyservers about this change, so others can pull down
+your new subkey::
+
+ $ gpg --send-key [fpr]
+
+.. note:: ECC support in GnuPG
+
+ GnuPG 2.1 and later has full support for Elliptic Curve
+ Cryptography, with ability to combine ECC subkeys with traditional
+ RSA master keys. The main upside of ECC cryptography is that it is
+ much faster computationally and creates much smaller signatures when
+ compared byte for byte with 2048+ bit RSA keys. Unless you plan on
+ using a smartcard device that does not support ECC operations, we
+ recommend that you create an ECC signing subkey for your kernel
+ work.
+
+ If for some reason you prefer to stay with RSA subkeys, just replace
+ "ed25519" with "rsa2048" in the above command.
+
+
+Back up your master key for disaster recovery
+---------------------------------------------
+
+The more signatures you have on your PGP key from other developers, the
+more reasons you have to create a backup version that lives on something
+other than digital media, for disaster recovery reasons.
+
+The best way to create a printable hardcopy of your private key is by
+using the ``paperkey`` software written for this very purpose. See ``man
+paperkey`` for more details on the output format and its benefits over
+other solutions. Paperkey should already be packaged for most
+distributions.
+
+Run the following command to create a hardcopy backup of your private
+key::
+
+ $ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt
+
+Print out that file (or pipe the output straight to lpr), then take a
+pen and write your passphrase on the margin of the paper. **This is
+strongly recommended** because the key printout is still encrypted with
+that passphrase, and if you ever change it you will not remember what it
+used to be when you had created the backup -- *guaranteed*.
+
+Put the resulting printout and the hand-written passphrase into an envelope
+and store in a secure and well-protected place, preferably away from your
+home, such as your bank vault.
+
+.. note::
+
+ Your printer is probably no longer a simple dumb device connected to
+ your parallel port, but since the output is still encrypted with
+ your passphrase, printing out even to "cloud-integrated" modern
+ printers should remain a relatively safe operation. One option is to
+ change the passphrase on your master key immediately after you are
+ done with paperkey.
+
+Back up your whole GnuPG directory
+----------------------------------
+
+.. warning::
+
+ **!!!Do not skip this step!!!**
+
+It is important to have a readily available backup of your PGP keys
+should you need to recover them. This is different from the
+disaster-level preparedness we did with ``paperkey``. You will also rely
+on these external copies whenever you need to use your Certify key --
+such as when making changes to your own key or signing other people's
+keys after conferences and summits.
+
+Start by getting a small USB "thumb" drive (preferably two!) that you
+will use for backup purposes. You will need to encrypt them using LUKS
+-- refer to your distro's documentation on how to accomplish this.
+
+For the encryption passphrase, you can use the same one as on your
+master key.
+
+Once the encryption process is over, re-insert the USB drive and make
+sure it gets properly mounted. Copy your entire ``.gnupg`` directory
+over to the encrypted storage::
+
+ $ cp -a ~/.gnupg /media/disk/foo/gnupg-backup
+
+You should now test to make sure everything still works::
+
+ $ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr]
+
+If you don't get any errors, then you should be good to go. Unmount the
+USB drive, distinctly label it so you don't blow it away next time you
+need to use a random USB drive, and put in a safe place -- but not too
+far away, because you'll need to use it every now and again for things
+like editing identities, adding or revoking subkeys, or signing other
+people's keys.
+
+Remove the master key from your homedir
+----------------------------------------
+
+The files in our home directory are not as well protected as we like to
+think. They can be leaked or stolen via many different means:
+
+- by accident when making quick homedir copies to set up a new workstation
+- by systems administrator negligence or malice
+- via poorly secured backups
+- via malware in desktop apps (browsers, pdf viewers, etc)
+- via coercion when crossing international borders
+
+Protecting your key with a good passphrase greatly helps reduce the risk
+of any of the above, but passphrases can be discovered via keyloggers,
+shoulder-surfing, or any number of other means. For this reason, the
+recommended setup is to remove your master key from your home directory
+and store it on offline storage.
+
+.. warning::
+
+ Please see the previous section and make sure you have backed up
+ your GnuPG directory in its entirety. What we are about to do will
+ render your key useless if you do not have a usable backup!
+
+First, identify the keygrip of your master key::
+
+ $ gpg --with-keygrip --list-key [fpr]
+
+The output will be something like this::
+
+ pub rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
+ 000000000000000000000000AAAABBBBCCCCDDDD
+ Keygrip = 1111000000000000000000000000000000000000
+ uid [ultimate] Alice Dev <adev@kernel.org>
+ sub rsa2048 2018-01-24 [E] [expires: 2020-01-24]
+ Keygrip = 2222000000000000000000000000000000000000
+ sub ed25519 2018-01-24 [S]
+ Keygrip = 3333000000000000000000000000000000000000
+
+Find the keygrip entry that is beneath the ``pub`` line (right under the
+master key fingerprint). This will correspond directly to a file in your
+``~/.gnupg`` directory::
+
+ $ cd ~/.gnupg/private-keys-v1.d
+ $ ls
+ 1111000000000000000000000000000000000000.key
+ 2222000000000000000000000000000000000000.key
+ 3333000000000000000000000000000000000000.key
+
+All you have to do is simply remove the .key file that corresponds to
+the master keygrip::
+
+ $ cd ~/.gnupg/private-keys-v1.d
+ $ rm 1111000000000000000000000000000000000000.key
+
+Now, if you issue the ``--list-secret-keys`` command, it will show that
+the master key is missing (the ``#`` indicates it is not available)::
+
+ $ gpg --list-secret-keys
+ sec# rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
+ 000000000000000000000000AAAABBBBCCCCDDDD
+ uid [ultimate] Alice Dev <adev@kernel.org>
+ ssb rsa2048 2018-01-24 [E] [expires: 2020-01-24]
+ ssb ed25519 2018-01-24 [S]
+
+You should also remove any ``secring.gpg`` files in the ``~/.gnupg``
+directory, which are left over from earlier versions of GnuPG.
+
+If you don't have the "private-keys-v1.d" directory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you do not have a ``~/.gnupg/private-keys-v1.d`` directory, then your
+secret keys are still stored in the legacy ``secring.gpg`` file used by
+GnuPG v1. Making any changes to your key, such as changing the
+passphrase or adding a subkey, should automatically convert the old
+``secring.gpg`` format to use ``private-keys-v1.d`` instead.
+
+Once you get that done, make sure to delete the obsolete ``secring.gpg``
+file, which still contains your private keys.
+
+.. _smartcards:
+
+Move the subkeys to a dedicated crypto device
+=============================================
+
+Even though the master key is now safe from being leaked or stolen, the
+subkeys are still in your home directory. Anyone who manages to get
+their hands on those will be able to decrypt your communication or fake
+your signatures (if they know the passphrase). Furthermore, each time a
+GnuPG operation is performed, the keys are loaded into system memory and
+can be stolen from there by sufficiently advanced malware (think
+Meltdown and Spectre).
+
+The best way to completely protect your keys is to move them to a
+specialized hardware device that is capable of smartcard operations.
+
+The benefits of smartcards
+--------------------------
+
+A smartcard contains a cryptographic chip that is capable of storing
+private keys and performing crypto operations directly on the card
+itself. Because the key contents never leave the smartcard, the
+operating system of the computer into which you plug in the hardware
+device is not able to retrieve the private keys themselves. This is very
+different from the encrypted USB storage device we used earlier for
+backup purposes -- while that USB device is plugged in and mounted, the
+operating system is able to access the private key contents.
+
+Using external encrypted USB media is not a substitute to having a
+smartcard-capable device.
+
+Available smartcard devices
+---------------------------
+
+Unless all your laptops and workstations have smartcard readers, the
+easiest is to get a specialized USB device that implements smartcard
+functionality. There are several options available:
+
+- `Nitrokey Start`_: Open hardware and Free Software, based on FSI
+ Japan's `Gnuk`_. Offers support for ECC keys, but fewest security
+ features (such as resistance to tampering or some side-channel
+ attacks).
+- `Nitrokey Pro`_: Similar to the Nitrokey Start, but more
+ tamper-resistant and offers more security features, but no ECC
+ support.
+- `Yubikey 4`_: proprietary hardware and software, but cheaper than
+ Nitrokey Pro and comes available in the USB-C form that is more useful
+ with newer laptops. Offers additional security features such as FIDO
+ U2F, but no ECC.
+
+`LWN has a good review`_ of some of the above models, as well as several
+others. If you want to use ECC keys, your best bet among commercially
+available devices is the Nitrokey Start.
+
+.. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6
+.. _`Nitrokey Pro`: https://shop.nitrokey.com/shop/product/nitrokey-pro-3
+.. _`Yubikey 4`: https://www.yubico.com/product/yubikey-4-series/
+.. _Gnuk: http://www.fsij.org/doc-gnuk/
+.. _`LWN has a good review`: https://lwn.net/Articles/736231/
+
+Configure your smartcard device
+-------------------------------
+
+Your smartcard device should Just Work (TM) the moment you plug it into
+any modern Linux workstation. You can verify it by running::
+
+ $ gpg --card-status
+
+If you see full smartcard details, then you are good to go.
+Unfortunately, troubleshooting all possible reasons why things may not
+be working for you is way beyond the scope of this guide. If you are
+having trouble getting the card to work with GnuPG, please seek help via
+usual support channels.
+
+To configure your smartcard, you will need to use the GnuPG menu system, as
+there are no convenient command-line switches::
+
+ $ gpg --card-edit
+ [...omitted...]
+ gpg/card> admin
+ Admin commands are allowed
+ gpg/card> passwd
+
+You should set the user PIN (1), Admin PIN (3), and the Reset Code (4).
+Please make sure to record and store these in a safe place -- especially
+the Admin PIN and the Reset Code (which allows you to completely wipe
+the smartcard). You so rarely need to use the Admin PIN, that you will
+inevitably forget what it is if you do not record it.
+
+Getting back to the main card menu, you can also set other values (such
+as name, sex, login data, etc), but it's not necessary and will
+additionally leak information about your smartcard should you lose it.
+
+.. note::
+
+ Despite having the name "PIN", neither the user PIN nor the admin
+ PIN on the card need to be numbers.
+
+Move the subkeys to your smartcard
+----------------------------------
+
+Exit the card menu (using "q") and save all changes. Next, let's move
+your subkeys onto the smartcard. You will need both your PGP key
+passphrase and the admin PIN of the card for most operations::
+
+ $ gpg --edit-key [fpr]
+
+ Secret subkeys are available.
+
+ pub rsa2048/AAAABBBBCCCCDDDD
+ created: 2018-01-23 expires: 2020-01-23 usage: SC
+ trust: ultimate validity: ultimate
+ ssb rsa2048/1111222233334444
+ created: 2018-01-23 expires: never usage: E
+ ssb ed25519/5555666677778888
+ created: 2017-12-07 expires: never usage: S
+ [ultimate] (1). Alice Dev <adev@kernel.org>
+
+ gpg>
+
+Using ``--edit-key`` puts us into the menu mode again, and you will
+notice that the key listing is a little different. From here on, all
+commands are done from inside this menu mode, as indicated by ``gpg>``.
+
+First, let's select the key we'll be putting onto the card -- you do
+this by typing ``key 1`` (it's the first one in the listing, the **[E]**
+subkey)::
+
+ gpg> key 1
+
+In the output, you should now see ``ssb*`` on the **[E]** key. The ``*``
+indicates which key is currently "selected." It works as a *toggle*,
+meaning that if you type ``key 1`` again, the ``*`` will disappear and
+the key will not be selected any more.
+
+Now, let's move that key onto the smartcard::
+
+ gpg> keytocard
+ Please select where to store the key:
+ (2) Encryption key
+ Your selection? 2
+
+Since it's our **[E]** key, it makes sense to put it into the Encryption
+slot. When you submit your selection, you will be prompted first for
+your PGP key passphrase, and then for the admin PIN. If the command
+returns without an error, your key has been moved.
+
+**Important**: Now type ``key 1`` again to unselect the first key, and
+``key 2`` to select the **[S]** key::
+
+ gpg> key 1
+ gpg> key 2
+ gpg> keytocard
+ Please select where to store the key:
+ (1) Signature key
+ (3) Authentication key
+ Your selection? 1
+
+You can use the **[S]** key both for Signature and Authentication, but
+we want to make sure it's in the Signature slot, so choose (1). Once
+again, if your command returns without an error, then the operation was
+successful::
+
+ gpg> q
+ Save changes? (y/N) y
+
+Saving the changes will delete the keys you moved to the card from your
+home directory (but it's okay, because we have them in our backups
+should we need to do this again for a replacement smartcard).
+
+Verifying that the keys were moved
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you perform ``--list-secret-keys`` now, you will see a subtle
+difference in the output::
+
+ $ gpg --list-secret-keys
+ sec# rsa2048 2018-01-24 [SC] [expires: 2020-01-24]
+ 000000000000000000000000AAAABBBBCCCCDDDD
+ uid [ultimate] Alice Dev <adev@kernel.org>
+ ssb> rsa2048 2018-01-24 [E] [expires: 2020-01-24]
+ ssb> ed25519 2018-01-24 [S]
+
+The ``>`` in the ``ssb>`` output indicates that the subkey is only
+available on the smartcard. If you go back into your secret keys
+directory and look at the contents there, you will notice that the
+``.key`` files there have been replaced with stubs::
+
+ $ cd ~/.gnupg/private-keys-v1.d
+ $ strings *.key | grep 'private-key'
+
+The output should contain ``shadowed-private-key`` to indicate that
+these files are only stubs and the actual content is on the smartcard.
+
+Verifying that the smartcard is functioning
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To verify that the smartcard is working as intended, you can create a
+signature::
+
+ $ echo "Hello world" | gpg --clearsign > /tmp/test.asc
+ $ gpg --verify /tmp/test.asc
+
+This should ask for your smartcard PIN on your first command, and then
+show "Good signature" after you run ``gpg --verify``.
+
+Congratulations, you have successfully made it extremely difficult to
+steal your digital developer identity!
+
+Other common GnuPG operations
+-----------------------------
+
+Here is a quick reference for some common operations you'll need to do
+with your PGP key.
+
+Mounting your master key offline storage
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You will need your master key for any of the operations below, so you
+will first need to mount your backup offline storage and tell GnuPG to
+use it::
+
+ $ export GNUPGHOME=/media/disk/foo/gnupg-backup
+ $ gpg --list-secret-keys
+
+You want to make sure that you see ``sec`` and not ``sec#`` in the
+output (the ``#`` means the key is not available and you're still using
+your regular home directory location).
+
+Extending key expiration date
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The master key has the default expiration date of 2 years from the date
+of creation. This is done both for security reasons and to make obsolete
+keys eventually disappear from keyservers.
+
+To extend the expiration on your key by a year from current date, just
+run::
+
+ $ gpg --quick-set-expire [fpr] 1y
+
+You can also use a specific date if that is easier to remember (e.g.
+your birthday, January 1st, or Canada Day)::
+
+ $ gpg --quick-set-expire [fpr] 2020-07-01
+
+Remember to send the updated key back to keyservers::
+
+ $ gpg --send-key [fpr]
+
+Updating your work directory after any changes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+After you make any changes to your key using the offline storage, you will
+want to import these changes back into your regular working directory::
+
+ $ gpg --export | gpg --homedir ~/.gnupg --import
+ $ unset GNUPGHOME
+
+
+Using PGP with Git
+==================
+
+One of the core features of Git is its decentralized nature -- once a
+repository is cloned to your system, you have full history of the
+project, including all of its tags, commits and branches. However, with
+hundreds of cloned repositories floating around, how does anyone verify
+that their copy of linux.git has not been tampered with by a malicious
+third party?
+
+Or what happens if a backdoor is discovered in the code and the "Author"
+line in the commit says it was done by you, while you're pretty sure you
+had `nothing to do with it`_?
+
+To address both of these issues, Git introduced PGP integration. Signed
+tags prove the repository integrity by assuring that its contents are
+exactly the same as on the workstation of the developer who created the
+tag, while signed commits make it nearly impossible for someone to
+impersonate you without having access to your PGP keys.
+
+.. _`nothing to do with it`: https://github.com/jayphelps/git-blame-someone-else
+
+Configure git to use your PGP key
+---------------------------------
+
+If you only have one secret key in your keyring, then you don't really
+need to do anything extra, as it becomes your default key. However, if
+you happen to have multiple secret keys, you can tell git which key
+should be used (``[fpr]`` is the fingerprint of your key)::
+
+ $ git config --global user.signingKey [fpr]
+
+**IMPORTANT**: If you have a distinct ``gpg2`` command, then you should
+tell git to always use it instead of the legacy ``gpg`` from version 1::
+
+ $ git config --global gpg.program gpg2
+
+How to work with signed tags
+----------------------------
+
+To create a signed tag, simply pass the ``-s`` switch to the tag
+command::
+
+ $ git tag -s [tagname]
+
+Our recommendation is to always sign git tags, as this allows other
+developers to ensure that the git repository they are pulling from has
+not been maliciously altered.
+
+How to verify signed tags
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To verify a signed tag, simply use the ``verify-tag`` command::
+
+ $ git verify-tag [tagname]
+
+If you are pulling a tag from another fork of the project repository,
+git should automatically verify the signature at the tip you're pulling
+and show you the results during the merge operation::
+
+ $ git pull [url] tags/sometag
+
+The merge message will contain something like this::
+
+ Merge tag 'sometag' of [url]
+
+ [Tag message]
+
+ # gpg: Signature made [...]
+ # gpg: Good signature from [...]
+
+If you are verifying someone else's git tag, then you will need to
+import their PGP key. Please refer to the
+":ref:`verify_identities`" section below.
+
+Configure git to always sign annotated tags
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Chances are, if you're creating an annotated tag, you'll want to sign
+it. To force git to always sign annotated tags, you can set a global
+configuration option::
+
+ $ git config --global tag.forceSignAnnotated true
+
+How to work with signed commits
+-------------------------------
+
+It is easy to create signed commits, but it is much more difficult to
+use them in Linux kernel development, since it relies on patches sent to
+the mailing list, and this workflow does not preserve PGP commit
+signatures. Furthermore, when rebasing your repository to match
+upstream, even your own PGP commit signatures will end up discarded. For
+this reason, most kernel developers don't bother signing their commits
+and will ignore signed commits in any external repositories that they
+rely upon in their work.
+
+However, if you have your working git tree publicly available at some
+git hosting service (kernel.org, infradead.org, ozlabs.org, or others),
+then the recommendation is that you sign all your git commits even if
+upstream developers do not directly benefit from this practice.
+
+We recommend this for the following reasons:
+
+1. Should there ever be a need to perform code forensics or track code
+ provenance, even externally maintained trees carrying PGP commit
+ signatures will be valuable for such purposes.
+2. If you ever need to re-clone your local repository (for example,
+ after a disk failure), this lets you easily verify the repository
+ integrity before resuming your work.
+3. If someone needs to cherry-pick your commits, this allows them to
+ quickly verify their integrity before applying them.
+
+Creating signed commits
+~~~~~~~~~~~~~~~~~~~~~~~
+
+To create a signed commit, you just need to pass the ``-S`` flag to the
+``git commit`` command (it's capital ``-S`` due to collision with
+another flag)::
+
+ $ git commit -S
+
+Configure git to always sign commits
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can tell git to always sign commits::
+
+ git config --global commit.gpgSign true
+
+.. note::
+
+ Make sure you configure ``gpg-agent`` before you turn this on.
+
+.. _verify_identities:
+
+How to verify kernel developer identities
+=========================================
+
+Signing tags and commits is easy, but how does one go about verifying
+that the key used to sign something belongs to the actual kernel
+developer and not to a malicious imposter?
+
+Configure auto-key-retrieval using WKD and DANE
+-----------------------------------------------
+
+If you are not already someone with an extensive collection of other
+developers' public keys, then you can jumpstart your keyring by relying
+on key auto-discovery and auto-retrieval. GnuPG can piggyback on other
+delegated trust technologies, namely DNSSEC and TLS, to get you going if
+the prospect of starting your own Web of Trust from scratch is too
+daunting.
+
+Add the following to your ``~/.gnupg/gpg.conf``::
+
+ auto-key-locate wkd,dane,local
+ auto-key-retrieve
+
+DNS-Based Authentication of Named Entities ("DANE") is a method for
+publishing public keys in DNS and securing them using DNSSEC signed
+zones. Web Key Directory ("WKD") is the alternative method that uses
+https lookups for the same purpose. When using either DANE or WKD for
+looking up public keys, GnuPG will validate DNSSEC or TLS certificates,
+respectively, before adding auto-retrieved public keys to your local
+keyring.
+
+Kernel.org publishes the WKD for all developers who have kernel.org
+accounts. Once you have the above changes in your ``gpg.conf``, you can
+auto-retrieve the keys for Linus Torvalds and Greg Kroah-Hartman (if you
+don't already have them)::
+
+ $ gpg --locate-keys torvalds@kernel.org gregkh@kernel.org
+
+If you have a kernel.org account, then you should `add the kernel.org
+UID to your key`_ to make WKD more useful to other kernel developers.
+
+.. _`add the kernel.org UID to your key`: https://korg.wiki.kernel.org/userdoc/mail#adding_a_kernelorg_uid_to_your_pgp_key
+
+Web of Trust (WOT) vs. Trust on First Use (TOFU)
+------------------------------------------------
+
+PGP incorporates a trust delegation mechanism known as the "Web of
+Trust." At its core, this is an attempt to replace the need for
+centralized Certification Authorities of the HTTPS/TLS world. Instead of
+various software makers dictating who should be your trusted certifying
+entity, PGP leaves this responsibility to each user.
+
+Unfortunately, very few people understand how the Web of Trust works.
+While it remains an important aspect of the OpenPGP specification,
+recent versions of GnuPG (2.2 and above) have implemented an alternative
+mechanism called "Trust on First Use" (TOFU). You can think of TOFU as
+"the SSH-like approach to trust." With SSH, the first time you connect
+to a remote system, its key fingerprint is recorded and remembered. If
+the key changes in the future, the SSH client will alert you and refuse
+to connect, forcing you to make a decision on whether you choose to
+trust the changed key or not. Similarly, the first time you import
+someone's PGP key, it is assumed to be valid. If at any point in the
+future GnuPG comes across another key with the same identity, both the
+previously imported key and the new key will be marked as invalid and
+you will need to manually figure out which one to keep.
+
+We recommend that you use the combined TOFU+PGP trust model (which is
+the new default in GnuPG v2). To set it, add (or modify) the
+``trust-model`` setting in ``~/.gnupg/gpg.conf``::
+
+ trust-model tofu+pgp
+
+How to use keyservers (more) safely
+-----------------------------------
+
+If you get a "No public key" error when trying to validate someone's
+tag, then you should attempt to lookup that key using a keyserver. It is
+important to keep in mind that there is absolutely no guarantee that the
+key you retrieve from PGP keyservers belongs to the actual person --
+that much is by design. You are supposed to use the Web of Trust to
+establish key validity.
+
+How to properly maintain the Web of Trust is beyond the scope of this
+document, simply because doing it properly requires both effort and
+dedication that tends to be beyond the caring threshold of most human
+beings. Here are some shortcuts that will help you reduce the risk of
+importing a malicious key.
+
+First, let's say you've tried to run ``git verify-tag`` but it returned
+an error saying the key is not found::
+
+ $ git verify-tag sunxi-fixes-for-4.15-2
+ gpg: Signature made Sun 07 Jan 2018 10:51:55 PM EST
+ gpg: using RSA key DA73759BF8619E484E5A3B47389A54219C0F2430
+ gpg: issuer "wens@...org"
+ gpg: Can't check signature: No public key
+
+Let's query the keyserver for more info about that key fingerprint (the
+fingerprint probably belongs to a subkey, so we can't use it directly
+without finding out the ID of the master key it is associated with)::
+
+ $ gpg --search DA73759BF8619E484E5A3B47389A54219C0F2430
+ gpg: data source: hkp://keys.gnupg.net
+ (1) Chen-Yu Tsai <wens@...org>
+ 4096 bit RSA key C94035C21B4F2AEB, created: 2017-03-14, expires: 2019-03-15
+ Keys 1-1 of 1 for "DA73759BF8619E484E5A3B47389A54219C0F2430". Enter number(s), N)ext, or Q)uit > q
+
+Locate the ID of the master key in the output, in our example
+``C94035C21B4F2AEB``. Now display the key of Linus Torvalds that you
+have on your keyring::
+
+ $ gpg --list-key torvalds@kernel.org
+ pub rsa2048 2011-09-20 [SC]
+ ABAF11C65A2970B130ABE3C479BE3E4300411886
+ uid [ unknown] Linus Torvalds <torvalds@kernel.org>
+ sub rsa2048 2011-09-20 [E]
+
+Next, open the `PGP pathfinder`_. In the "From" field, paste the key
+fingerprint of Linus Torvalds from the output above. In the "To" field,
+paste they key-id you found via ``gpg --search`` of the unknown key, and
+check the results:
+
+- `Finding paths to Linus`_
+
+If you get a few decent trust paths, then it's a pretty good indication
+that it is a valid key. You can add it to your keyring from the
+keyserver now::
+
+ $ gpg --recv-key C94035C21B4F2AEB
+
+This process is not perfect, and you are obviously trusting the
+administrators of the PGP Pathfinder service to not be malicious (in
+fact, this goes against :ref:`devs_not_infra`). However, if you
+do not carefully maintain your own web of trust, then it is a marked
+improvement over blindly trusting keyservers.
+
+.. _`PGP pathfinder`: https://pgp.cs.uu.nl/
+.. _`Finding paths to Linus`: https://pgp.cs.uu.nl/paths/79BE3E4300411886/to/C94035C21B4F2AEB.html
diff --git a/Documentation/sysctl/user.txt b/Documentation/sysctl/user.txt
index 1291c498f78f..a5882865836e 100644
--- a/Documentation/sysctl/user.txt
+++ b/Documentation/sysctl/user.txt
@@ -3,7 +3,7 @@ Documentation for /proc/sys/user/* kernel version 4.9.0
==============================================================
-This file contains the documetation for the sysctl files in
+This file contains the documentation for the sysctl files in
/proc/sys/user.
The files in this directory can be used to override the default
diff --git a/Documentation/watchdog/watchdog-parameters.txt b/Documentation/watchdog/watchdog-parameters.txt
index 6f9d7b418917..beea975980f6 100644
--- a/Documentation/watchdog/watchdog-parameters.txt
+++ b/Documentation/watchdog/watchdog-parameters.txt
@@ -40,11 +40,6 @@ margin: Watchdog margin in seconds (default=60)
nowayout: Disable watchdog shutdown on close
(default=kernel config parameter)
-------------------------------------------------
-at32ap700x_wdt:
-timeout: Timeout value. Limited to be 1 or 2 seconds. (default=2)
-nowayout: Watchdog cannot be stopped once started
- (default=kernel config parameter)
--------------------------------------------------
at91rm9200_wdt:
wdt_time: Watchdog time in seconds. (default=5)
nowayout: Watchdog cannot be stopped once started
@@ -162,11 +157,6 @@ testmode: Watchdog test mode (1 = no reboot), default=0
nowayout: Watchdog cannot be stopped once started
(default=kernel config parameter)
-------------------------------------------------
-ixp2000_wdt:
-heartbeat: Watchdog heartbeat in seconds (default 60s)
-nowayout: Watchdog cannot be stopped once started
- (default=kernel config parameter)
--------------------------------------------------
ixp4xx_wdt:
heartbeat: Watchdog heartbeat in seconds (default 60s)
nowayout: Watchdog cannot be stopped once started
@@ -381,19 +371,6 @@ timeout: Watchdog timeout in seconds. 1 <= timeout <= 255, default=60.
nowayout: Watchdog cannot be stopped once started
(default=kernel config parameter)
-------------------------------------------------
-w83697hf_wdt:
-wdt_io: w83697hf/hg WDT io port (default 0x2e, 0 = autodetect)
-timeout: Watchdog timeout in seconds. 1<= timeout <=255 (default=60)
-nowayout: Watchdog cannot be stopped once started
- (default=kernel config parameter)
-early_disable: Watchdog gets disabled at boot time (default=1)
--------------------------------------------------
-w83697ug_wdt:
-wdt_io: w83697ug/uf WDT io port (default 0x2e)
-timeout: Watchdog timeout in seconds. 1<= timeout <=255 (default=60)
-nowayout: Watchdog cannot be stopped once started
- (default=kernel config parameter)
--------------------------------------------------
w83877f_wdt:
timeout: Watchdog timeout in seconds. (1<=timeout<=3600, default=30)
nowayout: Watchdog cannot be stopped once started
diff --git a/MAINTAINERS b/MAINTAINERS
index b59a8cdfbe66..cf4258338587 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -903,7 +903,6 @@ L: devel@driverdev.osuosl.org
S: Supported
F: drivers/staging/android/ion
F: drivers/staging/android/uapi/ion.h
-F: drivers/staging/android/uapi/ion_test.h
AOA (Apple Onboard Audio) ALSA DRIVER
M: Johannes Berg <johannes@sipsolutions.net>
@@ -1308,7 +1307,6 @@ M: Russell King <linux@armlinux.org.uk>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
T: git git://git.armlinux.org.uk/~rmk/linux-arm.git clkdev
-F: arch/arm/include/asm/clkdev.h
F: drivers/clk/clkdev.c
ARM/COMPULAB CM-X270/EM-X270 and CM-X300 MACHINE SUPPORT
@@ -1360,7 +1358,7 @@ F: Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
F: Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt
F: Documentation/devicetree/bindings/rtc/faraday,ftrtc010.txt
F: arch/arm/mach-gemini/
-F: drivers/net/ethernet/cortina/gemini/*
+F: drivers/net/ethernet/cortina/
F: drivers/pinctrl/pinctrl-gemini.c
F: drivers/rtc/rtc-ftrtc010.c
@@ -1737,9 +1735,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: linux-oxnas@lists.tuxfamily.org (moderated for non-subscribers)
S: Maintained
F: arch/arm/mach-oxnas/
-F: arch/arm/boot/dts/ox8*.dtsi
-F: arch/arm/boot/dts/wd-mbwe.dts
-F: arch/arm/boot/dts/cloudengines-pogoplug-series-3.dts
+F: arch/arm/boot/dts/ox8*.dts*
N: oxnas
ARM/PALM TREO SUPPORT
@@ -1747,8 +1743,7 @@ M: Tomas Cech <sleep_walker@suse.com>
L: linux-arm-kernel@lists.infradead.org
W: http://hackndev.com
S: Maintained
-F: arch/arm/mach-pxa/include/mach/palmtreo.h
-F: arch/arm/mach-pxa/palmtreo.c
+F: arch/arm/mach-pxa/palmtreo.*
ARM/PALMTX,PALMT5,PALMLD,PALMTE2,PALMTC SUPPORT
M: Marek Vasut <marek.vasut@gmail.com>
@@ -1757,12 +1752,10 @@ W: http://hackndev.com
S: Maintained
F: arch/arm/mach-pxa/include/mach/palmtx.h
F: arch/arm/mach-pxa/palmtx.c
-F: arch/arm/mach-pxa/include/mach/palmt5.h
-F: arch/arm/mach-pxa/palmt5.c
+F: arch/arm/mach-pxa/palmt5.*
F: arch/arm/mach-pxa/include/mach/palmld.h
F: arch/arm/mach-pxa/palmld.c
-F: arch/arm/mach-pxa/include/mach/palmte2.h
-F: arch/arm/mach-pxa/palmte2.c
+F: arch/arm/mach-pxa/palmte2.*
F: arch/arm/mach-pxa/include/mach/palmtc.h
F: arch/arm/mach-pxa/palmtc.c
@@ -1771,8 +1764,7 @@ M: Sergey Lapin <slapin@ossfans.org>
L: linux-arm-kernel@lists.infradead.org
W: http://hackndev.com
S: Maintained
-F: arch/arm/mach-pxa/include/mach/palmz72.h
-F: arch/arm/mach-pxa/palmz72.c
+F: arch/arm/mach-pxa/palmz72.*
ARM/PLEB SUPPORT
M: Peter Chubb <pleb@gelato.unsw.edu.au>
@@ -1801,7 +1793,6 @@ F: drivers/clk/qcom/
F: drivers/dma/qcom/
F: drivers/soc/qcom/
F: drivers/spi/spi-qup.c
-F: drivers/tty/serial/msm_serial.h
F: drivers/tty/serial/msm_serial.c
F: drivers/*/pm8???-*
F: drivers/mfd/ssbi.c
@@ -2228,14 +2219,6 @@ L: linux-leds@vger.kernel.org
S: Maintained
F: drivers/leds/leds-as3645a.c
-AS3645A LED FLASH CONTROLLER DRIVER
-M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-L: linux-media@vger.kernel.org
-T: git git://linuxtv.org/media_tree.git
-S: Maintained
-F: drivers/media/i2c/as3645a.c
-F: include/media/i2c/as3645a.h
-
ASAHI KASEI AK8974 DRIVER
M: Linus Walleij <linus.walleij@linaro.org>
L: linux-iio@vger.kernel.org
@@ -3575,7 +3558,7 @@ F: drivers/media/platform/coda/
COMMON CLK FRAMEWORK
M: Michael Turquette <mturquette@baylibre.com>
-M: Stephen Boyd <sboyd@codeaurora.org>
+M: Stephen Boyd <sboyd@kernel.org>
L: linux-clk@vger.kernel.org
Q: http://patchwork.kernel.org/project/linux-clk/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
@@ -6009,6 +5992,12 @@ L: linux-input@vger.kernel.org
S: Maintained
F: drivers/input/touchscreen/goodix.c
+GPD POCKET FAN DRIVER
+M: Hans de Goede <hdegoede@redhat.com>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: drivers/platform/x86/gpd-pocket-fan.c
+
GPIO ACPI SUPPORT
M: Mika Westerberg <mika.westerberg@linux.intel.com>
M: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
@@ -6946,7 +6935,7 @@ INFINIBAND SUBSYSTEM
M: Doug Ledford <dledford@redhat.com>
M: Jason Gunthorpe <jgg@mellanox.com>
L: linux-rdma@vger.kernel.org
-W: http://www.openfabrics.org/
+W: https://github.com/linux-rdma/rdma-core
Q: http://patchwork.kernel.org/project/linux-rdma/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma.git
S: Supported
@@ -7136,6 +7125,14 @@ R: Dan Williams <dan.j.williams@intel.com>
S: Odd fixes
F: drivers/dma/iop-adma.c
+INTEL IPU3 CSI-2 CIO2 DRIVER
+M: Yong Zhi <yong.zhi@intel.com>
+M: Sakari Ailus <sakari.ailus@linux.intel.com>
+L: linux-media@vger.kernel.org
+S: Maintained
+F: drivers/media/pci/intel/ipu3/
+F: Documentation/media/uapi/v4l/pixfmt-srggb10-ipu3.rst
+
INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
M: Krzysztof Halasa <khalasa@piap.pl>
S: Maintained
@@ -8749,6 +8746,15 @@ T: git git://linuxtv.org/media_tree.git
S: Maintained
F: drivers/media/dvb-frontends/stv6111*
+MEDIA DRIVERS FOR NVIDIA TEGRA - VDE
+M: Dmitry Osipenko <digetx@gmail.com>
+L: linux-media@vger.kernel.org
+L: linux-tegra@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: Documentation/devicetree/bindings/media/nvidia,tegra-vde.txt
+F: drivers/staging/media/tegra-vde/
+
MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
M: Mauro Carvalho Chehab <mchehab@s-opensource.com>
M: Mauro Carvalho Chehab <mchehab@kernel.org>
@@ -8930,12 +8936,13 @@ W: http://www.mellanox.com
Q: http://patchwork.ozlabs.org/project/netdev/list/
F: drivers/net/ethernet/mellanox/mlxfw/
-MELLANOX MLX CPLD HOTPLUG DRIVER
+MELLANOX HARDWARE PLATFORM SUPPORT
+M: Andy Shevchenko <andy@infradead.org>
+M: Darren Hart <dvhart@infradead.org>
M: Vadim Pasternak <vadimp@mellanox.com>
L: platform-driver-x86@vger.kernel.org
S: Supported
-F: drivers/platform/x86/mlxcpld-hotplug.c
-F: include/linux/platform_data/mlxcpld-hotplug.h
+F: drivers/platform/mellanox/
MELLANOX MLX4 core VPI driver
M: Tariq Toukan <tariqt@mellanox.com>
@@ -9009,6 +9016,7 @@ L: linux-kernel@vger.kernel.org
S: Supported
F: kernel/sched/membarrier.c
F: include/uapi/linux/membarrier.h
+F: arch/powerpc/include/asm/membarrier.h
MEMORY MANAGEMENT
L: linux-mm@kvack.org
@@ -9180,6 +9188,7 @@ S: Supported
F: Documentation/devicetree/bindings/mips/
F: Documentation/mips/
F: arch/mips/
+F: drivers/platform/mips/
MIPS BOSTON DEVELOPMENT BOARD
M: Paul Burton <paul.burton@mips.com>
@@ -9207,6 +9216,25 @@ F: arch/mips/include/asm/mach-loongson32/
F: drivers/*/*loongson1*
F: drivers/*/*/*loongson1*
+MIPS/LOONGSON2 ARCHITECTURE
+M: Jiaxun Yang <jiaxun.yang@flygoat.com>
+L: linux-mips@linux-mips.org
+S: Maintained
+F: arch/mips/loongson64/*{2e/2f}*
+F: arch/mips/include/asm/mach-loongson64/
+F: drivers/*/*loongson2*
+F: drivers/*/*/*loongson2*
+
+MIPS/LOONGSON3 ARCHITECTURE
+M: Huacai Chen <chenhc@lemote.com>
+L: linux-mips@linux-mips.org
+S: Maintained
+F: arch/mips/loongson64/
+F: arch/mips/include/asm/mach-loongson64/
+F: drivers/platform/mips/cpu_hwmon.c
+F: drivers/*/*loongson3*
+F: drivers/*/*/*loongson3*
+
MIPS RINT INSTRUCTION EMULATION
M: Aleksandar Markovic <aleksandar.markovic@mips.com>
L: linux-mips@linux-mips.org
@@ -9252,7 +9280,6 @@ F: drivers/media/dvb-frontends/mn88473*
MODULE SUPPORT
M: Jessica Yu <jeyu@kernel.org>
-M: Rusty Russell <rusty@rustcorp.com.au>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git modules-next
S: Maintained
F: include/linux/module.h
@@ -10165,6 +10192,14 @@ S: Maintained
F: drivers/media/i2c/ov7670.c
F: Documentation/devicetree/bindings/media/i2c/ov7670.txt
+OMNIVISION OV7740 SENSOR DRIVER
+M: Wenyou Yang <wenyou.yang@microchip.com>
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/i2c/ov7740.c
+F: Documentation/devicetree/bindings/media/i2c/ov7740.txt
+
ONENAND FLASH DRIVER
M: Kyungmin Park <kyungmin.park@samsung.com>
L: linux-mtd@lists.infradead.org
@@ -10259,7 +10294,7 @@ F: include/uapi/linux/openvswitch.h
OPERATING PERFORMANCE POINTS (OPP)
M: Viresh Kumar <vireshk@kernel.org>
M: Nishanth Menon <nm@ti.com>
-M: Stephen Boyd <sboyd@codeaurora.org>
+M: Stephen Boyd <sboyd@kernel.org>
L: linux-pm@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git
@@ -10394,7 +10429,6 @@ F: Documentation/parport*.txt
PARAVIRT_OPS INTERFACE
M: Juergen Gross <jgross@suse.com>
M: Alok Kataria <akataria@vmware.com>
-M: Rusty Russell <rusty@rustcorp.com.au>
L: virtualization@lists.linux-foundation.org
S: Supported
F: Documentation/virtual/paravirt_ops.txt
@@ -10513,6 +10547,13 @@ S: Maintained
F: Documentation/devicetree/bindings/pci/pci-armada8k.txt
F: drivers/pci/dwc/pcie-armada8k.c
+PCI DRIVER FOR CADENCE PCIE IP
+M: Alan Douglas <adouglas@cadence.com>
+L: linux-pci@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/pci/cdns,*.txt
+F: drivers/pci/cadence/pcie-cadence*
+
PCI DRIVER FOR FREESCALE LAYERSCAPE
M: Minghuan Lian <minghuan.Lian@freescale.com>
M: Mingkai Hu <mingkai.hu@freescale.com>
@@ -10663,8 +10704,12 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git
S: Supported
F: Documentation/devicetree/bindings/pci/
F: Documentation/PCI/
+F: drivers/acpi/pci*
F: drivers/pci/
+F: include/asm-generic/pci*
F: include/linux/pci*
+F: include/uapi/linux/pci*
+F: lib/pci*
F: arch/x86/pci/
F: arch/x86/kernel/quirks.c
@@ -11559,6 +11604,13 @@ S: Maintained
F: Documentation/blockdev/ramdisk.txt
F: drivers/block/brd.c
+RANCHU VIRTUAL BOARD FOR MIPS
+M: Miodrag Dinic <miodrag.dinic@mips.com>
+L: linux-mips@linux-mips.org
+S: Supported
+F: arch/mips/generic/board-ranchu.c
+F: arch/mips/configs/generic/board-ranchu.config
+
RANDOM NUMBER DRIVER
M: "Theodore Ts'o" <tytso@mit.edu>
S: Maintained
@@ -12460,6 +12512,14 @@ T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/tuners/si2157*
+SI2165 MEDIA DRIVER
+M: Matthias Schwarzott <zzam@gentoo.org>
+L: linux-media@vger.kernel.org
+W: https://linuxtv.org
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+S: Maintained
+F: drivers/media/dvb-frontends/si2165*
+
SI2168 MEDIA DRIVER
M: Antti Palosaari <crope@iki.fi>
L: linux-media@vger.kernel.org
@@ -12976,7 +13036,7 @@ F: Documentation/networking/spider_net.txt
F: drivers/net/ethernet/toshiba/spider_net*
SPMI SUBSYSTEM
-R: Stephen Boyd <sboyd@codeaurora.org>
+R: Stephen Boyd <sboyd@kernel.org>
L: linux-arm-msm@vger.kernel.org
F: Documentation/devicetree/bindings/spmi/
F: drivers/spmi/
@@ -13037,12 +13097,6 @@ S: Odd Fixes
F: Documentation/devicetree/bindings/staging/iio/
F: drivers/staging/iio/
-STAGING - LIRC (LINUX INFRARED REMOTE CONTROL) DRIVERS
-M: Jarod Wilson <jarod@wilsonet.com>
-W: http://www.lirc.org/
-S: Odd Fixes
-F: drivers/staging/media/lirc/
-
STAGING - LUSTRE PARALLEL FILESYSTEM
M: Oleg Drokin <oleg.drokin@intel.com>
M: Andreas Dilger <andreas.dilger@intel.com>
@@ -13289,7 +13343,6 @@ F: include/linux/platform_data/dma-dw.h
F: drivers/dma/dw/
SYNOPSYS DESIGNWARE ENTERPRISE ETHERNET DRIVER
-M: Jie Deng <jiedeng@synopsys.com>
M: Jose Abreu <Jose.Abreu@synopsys.com>
L: netdev@vger.kernel.org
S: Supported
@@ -13429,6 +13482,15 @@ T: git git://linuxtv.org/anttip/media_tree.git
S: Maintained
F: drivers/media/tuners/tda18218*
+TDA18250 MEDIA DRIVER
+M: Olli Salonen <olli.salonen@iki.fi>
+L: linux-media@vger.kernel.org
+W: https://linuxtv.org
+Q: http://patchwork.linuxtv.org/project/linux-media/list/
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/tuners/tda18250*
+
TDA18271 MEDIA DRIVER
M: Michael Krufky <mkrufky@linuxtv.org>
L: linux-media@vger.kernel.org
@@ -13859,7 +13921,7 @@ F: include/linux/usb/tilegx.h
TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
M: John Stultz <john.stultz@linaro.org>
M: Thomas Gleixner <tglx@linutronix.de>
-R: Stephen Boyd <sboyd@codeaurora.org>
+R: Stephen Boyd <sboyd@kernel.org>
L: linux-kernel@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
S: Supported
@@ -14927,8 +14989,8 @@ S: Maintained
F: drivers/input/tablet/wacom_serial4.c
WATCHDOG DEVICE DRIVERS
-M: Wim Van Sebroeck <wim@iguana.be>
-R: Guenter Roeck <linux@roeck-us.net>
+M: Wim Van Sebroeck <wim@linux-watchdog.org>
+M: Guenter Roeck <linux@roeck-us.net>
L: linux-watchdog@vger.kernel.org
W: http://www.linux-watchdog.org/
T: git git://www.linux-watchdog.org/linux-watchdog.git
@@ -15095,7 +15157,7 @@ X86 PLATFORM DRIVERS
M: Darren Hart <dvhart@infradead.org>
M: Andy Shevchenko <andy@infradead.org>
L: platform-driver-x86@vger.kernel.org
-T: git git://git.infradead.org/users/dvhart/linux-platform-drivers-x86.git
+T: git git://git.infradead.org/linux-platform-drivers-x86.git
S: Maintained
F: drivers/platform/x86/
F: drivers/platform/olpc/
diff --git a/Makefile b/Makefile
index 11aff0f9e105..d192dd826cce 100644
--- a/Makefile
+++ b/Makefile
@@ -434,7 +434,8 @@ export MAKE LEX YACC AWK GENKSYMS INSTALLKERNEL PERL PYTHON UTS_MACHINE
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
-export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_KASAN CFLAGS_UBSAN
+export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE CFLAGS_UBSAN
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
@@ -679,6 +680,10 @@ endif
# This selects the stack protector compiler flag. Testing it is delayed
# until after .config has been reprocessed, in the prepare-compiler-check
# target.
+ifdef CONFIG_CC_STACKPROTECTOR_AUTO
+ stackp-flag := $(call cc-option,-fstack-protector-strong,$(call cc-option,-fstack-protector))
+ stackp-name := AUTO
+else
ifdef CONFIG_CC_STACKPROTECTOR_REGULAR
stackp-flag := -fstack-protector
stackp-name := REGULAR
@@ -687,16 +692,40 @@ ifdef CONFIG_CC_STACKPROTECTOR_STRONG
stackp-flag := -fstack-protector-strong
stackp-name := STRONG
else
+ # If either there is no stack protector for this architecture or
+ # CONFIG_CC_STACKPROTECTOR_NONE is selected, we're done, and $(stackp-name)
+ # is empty, skipping all remaining stack protector tests.
+ #
# Force off for distro compilers that enable stack protector by default.
- stackp-flag := $(call cc-option, -fno-stack-protector)
+ KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
+endif
endif
endif
# Find arch-specific stack protector compiler sanity-checking script.
-ifdef CONFIG_CC_STACKPROTECTOR
+ifdef stackp-name
+ifneq ($(stackp-flag),)
stackp-path := $(srctree)/scripts/gcc-$(SRCARCH)_$(BITS)-has-stack-protector.sh
stackp-check := $(wildcard $(stackp-path))
+ # If the wildcard test matches a test script, run it to check functionality.
+ ifdef stackp-check
+ ifneq ($(shell $(CONFIG_SHELL) $(stackp-check) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
+ stackp-broken := y
+ endif
+ endif
+ ifndef stackp-broken
+ # If the stack protector is functional, enable code that depends on it.
+ KBUILD_CPPFLAGS += -DCONFIG_CC_STACKPROTECTOR
+ # Either we've already detected the flag (for AUTO) or we'll fail the
+ # build in the prepare-compiler-check rule (for specific flag).
+ KBUILD_CFLAGS += $(stackp-flag)
+ else
+ # We have to make sure stack protector is unconditionally disabled if
+ # the compiler is broken (in case we're going to continue the build in
+ # AUTO mode).
+ KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
+ endif
+endif
endif
-KBUILD_CFLAGS += $(stackp-flag)
ifeq ($(cc-name),clang)
KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
@@ -1091,14 +1120,25 @@ PHONY += prepare-compiler-check
prepare-compiler-check: FORCE
# Make sure compiler supports requested stack protector flag.
ifdef stackp-name
+ # Warn about CONFIG_CC_STACKPROTECTOR_AUTO having found no option.
+ ifeq ($(stackp-flag),)
+ @echo CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
+ Compiler does not support any known stack-protector >&2
+ else
+ # Fail if specifically requested stack protector is missing.
ifeq ($(call cc-option, $(stackp-flag)),)
@echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
$(stackp-flag) not supported by compiler >&2 && exit 1
endif
+ endif
endif
-# Make sure compiler does not have buggy stack-protector support.
-ifdef stackp-check
- ifneq ($(shell $(CONFIG_SHELL) $(stackp-check) $(CC) $(KBUILD_CPPFLAGS) $(biarch)),y)
+# Make sure compiler does not have buggy stack-protector support. If a
+# specific stack-protector was requested, fail the build, otherwise warn.
+ifdef stackp-broken
+ ifeq ($(stackp-name),AUTO)
+ @echo CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
+ $(stackp-flag) available but compiler is broken: disabling >&2
+ else
@echo Cannot use CONFIG_CC_STACKPROTECTOR_$(stackp-name): \
$(stackp-flag) available but compiler is broken >&2 && exit 1
endif
diff --git a/arch/Kconfig b/arch/Kconfig
index 467dfa35bf96..76c0b54443b1 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -538,16 +538,10 @@ config HAVE_CC_STACKPROTECTOR
- its compiler supports the -fstack-protector option
- it has implemented a stack canary (e.g. __stack_chk_guard)
-config CC_STACKPROTECTOR
- def_bool n
- help
- Set when a stack-protector mode is enabled, so that the build
- can enable kernel-side support for the GCC feature.
-
choice
prompt "Stack Protector buffer overflow detection"
depends on HAVE_CC_STACKPROTECTOR
- default CC_STACKPROTECTOR_NONE
+ default CC_STACKPROTECTOR_AUTO
help
This option turns on the "stack-protector" GCC feature. This
feature puts, at the beginning of functions, a canary value on
@@ -564,7 +558,6 @@ config CC_STACKPROTECTOR_NONE
config CC_STACKPROTECTOR_REGULAR
bool "Regular"
- select CC_STACKPROTECTOR
help
Functions will have the stack-protector canary logic added if they
have an 8-byte or larger character array on the stack.
@@ -578,7 +571,6 @@ config CC_STACKPROTECTOR_REGULAR
config CC_STACKPROTECTOR_STRONG
bool "Strong"
- select CC_STACKPROTECTOR
help
Functions will have the stack-protector canary logic added in any
of the following conditions:
@@ -596,6 +588,12 @@ config CC_STACKPROTECTOR_STRONG
about 20% of all kernel functions, which increases the kernel code
size by about 2%.
+config CC_STACKPROTECTOR_AUTO
+ bool "Automatic"
+ help
+ If the compiler supports it, the best available stack-protector
+ option will be chosen.
+
endchoice
config THIN_ARCHIVES
diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c
index 8e9a41966881..5476279329a6 100644
--- a/arch/alpha/kernel/console.c
+++ b/arch/alpha/kernel/console.c
@@ -21,6 +21,7 @@
struct pci_controller *pci_vga_hose;
static struct resource alpha_vga = {
.name = "alpha-vga+",
+ .flags = IORESOURCE_IO,
.start = 0x3C0,
.end = 0x3DF
};
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 72c765a3b354..ab930581fc7a 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -780,6 +780,8 @@
reset-gpio = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */
+ lens-focus = <&ad5820>;
+
port {
csi_cam1: endpoint {
bus-type = <3>; /* CCP2 */
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index ce5ee762ed66..4cab9bb823fb 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -338,6 +338,7 @@ static inline int find_next_bit_le(const void *p, int size, int offset)
#endif
+#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/le.h>
/*
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 960d9dc4f380..1f0de808d111 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -10,10 +10,7 @@ extern unsigned long pcibios_min_io;
extern unsigned long pcibios_min_mem;
#define PCIBIOS_MIN_MEM pcibios_min_mem
-static inline int pcibios_assign_all_busses(void)
-{
- return pci_has_flag(PCI_REASSIGN_ALL_RSRC);
-}
+#define pcibios_assign_all_busses() pci_has_flag(PCI_REASSIGN_ALL_BUS)
#ifdef CONFIG_PCI_DOMAINS
static inline int pci_proc_domain(struct pci_bus *bus)
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 0cd0aefb3a8f..ed46ca69813d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -527,7 +527,7 @@ void pci_common_init_dev(struct device *parent, struct hw_pci *hw)
struct pci_sys_data *sys;
LIST_HEAD(head);
- pci_add_flags(PCI_REASSIGN_ALL_RSRC);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
if (hw->preinit)
hw->preinit();
pcibios_init_hw(parent, hw, &head);
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 9b49867154bf..6b32dc527edc 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -10,7 +10,6 @@ menuconfig ARCH_MVEBU
select ZONE_DMA if ARM_LPAE
select GPIOLIB
select PCI_QUIRKS if PCI
- select OF_ADDRESS_PCI
if ARCH_MVEBU
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 53612879fe56..7381eeb7ef8e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -16,6 +16,7 @@ config ARM64
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_GIGANTIC_PAGE if (MEMORY_ISOLATION && COMPACTION) || CMA
select ARCH_HAS_KCOV
+ select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_SET_MEMORY
select ARCH_HAS_SG_CHAIN
select ARCH_HAS_STRICT_KERNEL_RWX
diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h
index e266f80e45b7..8758bb008436 100644
--- a/arch/arm64/include/asm/kasan.h
+++ b/arch/arm64/include/asm/kasan.h
@@ -12,7 +12,8 @@
/*
* KASAN_SHADOW_START: beginning of the kernel virtual addresses.
- * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/8 of kernel virtual addresses.
+ * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/N of kernel virtual addresses,
+ * where N = (1 << KASAN_SHADOW_SCALE_SHIFT).
*/
#define KASAN_SHADOW_START (VA_START)
#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
@@ -20,14 +21,16 @@
/*
* This value is used to map an address to the corresponding shadow
* address by the following formula:
- * shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;
+ * shadow_addr = (address >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET
*
- * (1 << 61) shadow addresses - [KASAN_SHADOW_OFFSET,KASAN_SHADOW_END]
- * cover all 64-bits of virtual addresses. So KASAN_SHADOW_OFFSET
- * should satisfy the following equation:
- * KASAN_SHADOW_OFFSET = KASAN_SHADOW_END - (1ULL << 61)
+ * (1 << (64 - KASAN_SHADOW_SCALE_SHIFT)) shadow addresses that lie in range
+ * [KASAN_SHADOW_OFFSET, KASAN_SHADOW_END) cover all 64-bits of virtual
+ * addresses. So KASAN_SHADOW_OFFSET should satisfy the following equation:
+ * KASAN_SHADOW_OFFSET = KASAN_SHADOW_END -
+ * (1ULL << (64 - KASAN_SHADOW_SCALE_SHIFT))
*/
-#define KASAN_SHADOW_OFFSET (KASAN_SHADOW_END - (1ULL << (64 - 3)))
+#define KASAN_SHADOW_OFFSET (KASAN_SHADOW_END - (1ULL << \
+ (64 - KASAN_SHADOW_SCALE_SHIFT)))
void kasan_init(void);
void kasan_copy_shadow(pgd_t *pgdir);
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index d4bae7d6e0d8..50fa96a49792 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -85,7 +85,8 @@
* stack size when KASAN is in use.
*/
#ifdef CONFIG_KASAN
-#define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - 3))
+#define KASAN_SHADOW_SCALE_SHIFT 3
+#define KASAN_SHADOW_SIZE (UL(1) << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT))
#define KASAN_THREAD_SHIFT 1
#else
#define KASAN_SHADOW_SIZE (0)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index b34e717d7597..cccd2788e631 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -324,6 +324,10 @@ alternative_else_nop_endif
ldp x28, x29, [sp, #16 * 14]
ldr lr, [sp, #S_LR]
add sp, sp, #S_FRAME_SIZE // restore sp
+ /*
+ * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on eret context synchronization
+ * when returning from IPI handler, and when returning to user-space.
+ */
.if \el == 0
alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 3affca3dd96a..75b220ba73a3 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -925,9 +925,8 @@ static void __armv8pmu_probe_pmu(void *info)
pmceid[0] = read_sysreg(pmceid0_el0);
pmceid[1] = read_sysreg(pmceid1_el0);
- bitmap_from_u32array(cpu_pmu->pmceid_bitmap,
- ARMV8_PMUV3_MAX_COMMON_EVENTS, pmceid,
- ARRAY_SIZE(pmceid));
+ bitmap_from_arr32(cpu_pmu->pmceid_bitmap,
+ pmceid, ARMV8_PMUV3_MAX_COMMON_EVENTS);
}
static int armv8pmu_probe_pmu(struct arm_pmu *cpu_pmu)
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c
index acba49fb5aac..6e02e6fb4c7b 100644
--- a/arch/arm64/mm/kasan_init.c
+++ b/arch/arm64/mm/kasan_init.c
@@ -135,7 +135,8 @@ static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
/* The early shadow maps everything to a single page of zeroes */
asmlinkage void __init kasan_early_init(void)
{
- BUILD_BUG_ON(KASAN_SHADOW_OFFSET != KASAN_SHADOW_END - (1UL << 61));
+ BUILD_BUG_ON(KASAN_SHADOW_OFFSET !=
+ KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT)));
BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE,
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index b44992ec9643..4e369dfb83b1 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -685,12 +685,14 @@ int kern_addr_valid(unsigned long addr)
}
#ifdef CONFIG_SPARSEMEM_VMEMMAP
#if !ARM64_SWAPPER_USES_SECTION_MAPS
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+ struct vmem_altmap *altmap)
{
return vmemmap_populate_basepages(start, end, node);
}
#else /* !ARM64_SWAPPER_USES_SECTION_MAPS */
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+ struct vmem_altmap *altmap)
{
unsigned long addr = start;
unsigned long next;
@@ -725,7 +727,8 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
return 0;
}
#endif /* CONFIG_ARM64_64K_PAGES */
-void vmemmap_free(unsigned long start, unsigned long end)
+void vmemmap_free(unsigned long start, unsigned long end,
+ struct vmem_altmap *altmap)
{
}
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index c44f002e8f6b..858602494096 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2610,17 +2610,10 @@ pfm_get_task(pfm_context_t *ctx, pid_t pid, struct task_struct **task)
if (pid < 2) return -EPERM;
if (pid != task_pid_vnr(current)) {
-
- read_lock(&tasklist_lock);
-
- p = find_task_by_vpid(pid);
-
/* make sure task cannot go away while we operate on it */
- if (p) get_task_struct(p);
-
- read_unlock(&tasklist_lock);
-
- if (p == NULL) return -ESRCH;
+ p = find_get_task_by_vpid(pid);
+ if (!p)
+ return -ESRCH;
}
ret = pfm_task_incompatible(ctx, p);
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index ac46f0d60b66..7d9bd20319ff 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -754,12 +754,14 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat)
#endif
#ifdef CONFIG_SPARSEMEM_VMEMMAP
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+ struct vmem_altmap *altmap)
{
return vmemmap_populate_basepages(start, end, node);
}
-void vmemmap_free(unsigned long start, unsigned long end)
+void vmemmap_free(unsigned long start, unsigned long end,
+ struct vmem_altmap *altmap)
{
}
#endif
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 7af4e05bb61e..18278b448530 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -501,7 +501,7 @@ virtual_memmap_init(u64 start, u64 end, void *arg)
if (map_start < map_end)
memmap_init_zone((unsigned long)(map_end - map_start),
args->nid, args->zone, page_to_pfn(map_start),
- MEMMAP_EARLY);
+ MEMMAP_EARLY, NULL);
return 0;
}
@@ -509,9 +509,10 @@ void __meminit
memmap_init (unsigned long size, int nid, unsigned long zone,
unsigned long start_pfn)
{
- if (!vmem_map)
- memmap_init_zone(size, nid, zone, start_pfn, MEMMAP_EARLY);
- else {
+ if (!vmem_map) {
+ memmap_init_zone(size, nid, zone, start_pfn, MEMMAP_EARLY,
+ NULL);
+ } else {
struct page *start;
struct memmap_init_callback_data args;
@@ -647,13 +648,14 @@ mem_init (void)
}
#ifdef CONFIG_MEMORY_HOTPLUG
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+ bool want_memblock)
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
int ret;
- ret = __add_pages(nid, start_pfn, nr_pages, want_memblock);
+ ret = __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
if (ret)
printk("%s: Problem encountered in __add_pages() as ret=%d\n",
__func__, ret);
@@ -662,7 +664,7 @@ int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
}
#ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
+int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
@@ -670,7 +672,7 @@ int arch_remove_memory(u64 start, u64 size)
int ret;
zone = page_zone(pfn_to_page(start_pfn));
- ret = __remove_pages(zone, start_pfn, nr_pages);
+ ret = __remove_pages(zone, start_pfn, nr_pages, altmap);
if (ret)
pr_warn("%s: Problem encountered in __remove_pages() as"
" ret=%d\n", __func__, ret);
diff --git a/arch/m68k/include/asm/bitops.h b/arch/m68k/include/asm/bitops.h
index dda58cfe8c22..93b47b1f6fb4 100644
--- a/arch/m68k/include/asm/bitops.h
+++ b/arch/m68k/include/asm/bitops.h
@@ -311,7 +311,6 @@ static inline int bfchg_mem_test_and_change_bit(int nr,
* functions.
*/
#if defined(CONFIG_CPU_HAS_NO_BITFIELDS)
-#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ffz.h>
#else
@@ -441,6 +440,8 @@ static inline unsigned long ffz(unsigned long word)
#endif
+#include <asm-generic/bitops/find.h>
+
#ifdef __KERNEL__
#if defined(CONFIG_CPU_HAS_NO_BITFIELDS)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ab98569994f0..449397c60b56 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -7,8 +7,6 @@ config MIPS
select ARCH_DISCARD_MEMBLOCK
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
- select ARCH_MIGHT_HAVE_PC_PARPORT
- select ARCH_MIGHT_HAVE_PC_SERIO
select ARCH_SUPPORTS_UPROBES
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_CMPXCHG_LOCKREF if 64BIT
@@ -119,12 +117,12 @@ config MIPS_GENERIC
select SYS_SUPPORTS_MULTITHREADING
select SYS_SUPPORTS_RELOCATABLE
select SYS_SUPPORTS_SMARTMIPS
- select USB_EHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
- select USB_EHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
- select USB_OHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
- select USB_OHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
- select USB_UHCI_BIG_ENDIAN_DESC if BIG_ENDIAN
- select USB_UHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN
+ select USB_EHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+ select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+ select USB_OHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+ select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+ select USB_UHCI_BIG_ENDIAN_DESC if CPU_BIG_ENDIAN
+ select USB_UHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
select USE_OF
help
Select this to build a kernel which aims to support multiple boards,
@@ -253,6 +251,7 @@ config BCM47XX
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_MIPS16
+ select SYS_SUPPORTS_ZBOOT
select SYS_HAS_EARLY_PRINTK
select USE_GENERIC_EARLY_PRINTK_8250
select GPIOLIB
@@ -341,6 +340,8 @@ config MACH_DECSTATION
config MACH_JAZZ
bool "Jazz family of machines"
+ select ARCH_MIGHT_HAVE_PC_PARPORT
+ select ARCH_MIGHT_HAVE_PC_SERIO
select FW_ARC
select FW_ARC32
select ARCH_MAY_HAVE_PC_FDC
@@ -476,6 +477,8 @@ config MACH_PISTACHIO
config MIPS_MALTA
bool "MIPS Malta board"
select ARCH_MAY_HAVE_PC_FDC
+ select ARCH_MIGHT_HAVE_PC_PARPORT
+ select ARCH_MIGHT_HAVE_PC_SERIO
select BOOT_ELF32
select BOOT_RAW
select BUILTIN_DTB
@@ -613,6 +616,7 @@ config SGI_IP22
bool "SGI IP22 (Indy/Indigo2)"
select FW_ARC
select FW_ARC32
+ select ARCH_MIGHT_HAVE_PC_SERIO
select BOOT_ELF32
select CEVT_R4K
select CSRC_R4K
@@ -675,6 +679,7 @@ config SGI_IP28
bool "SGI IP28 (Indigo2 R10k)"
select FW_ARC
select FW_ARC64
+ select ARCH_MIGHT_HAVE_PC_SERIO
select BOOT_ELF64
select CEVT_R4K
select CSRC_R4K
@@ -824,6 +829,8 @@ config SNI_RM
select FW_ARC32 if CPU_LITTLE_ENDIAN
select FW_SNIPROM if CPU_BIG_ENDIAN
select ARCH_MAY_HAVE_PC_FDC
+ select ARCH_MIGHT_HAVE_PC_PARPORT
+ select ARCH_MIGHT_HAVE_PC_SERIO
select BOOT_ELF32
select CEVT_R4K
select CSRC_R4K
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 9f6a26d72f9f..d1ca839c3981 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -216,6 +216,12 @@ cflags-$(toolchain-msa) += -DTOOLCHAIN_SUPPORTS_MSA
endif
toolchain-virt := $(call cc-option-yn,$(mips-cflags) -mvirt)
cflags-$(toolchain-virt) += -DTOOLCHAIN_SUPPORTS_VIRT
+# For -mmicromips, use -Wa,-fatal-warnings to catch unsupported -mxpa which
+# only warns
+xpa-cflags-y := $(mips-cflags)
+xpa-cflags-$(micromips-ase) += -mmicromips -Wa$(comma)-fatal-warnings
+toolchain-xpa := $(call cc-option-yn,$(xpa-cflags-y) -mxpa)
+cflags-$(toolchain-xpa) += -DTOOLCHAIN_SUPPORTS_XPA
#
# Firmware support
@@ -228,7 +234,7 @@ libs-y += arch/mips/fw/lib/
#
# Kernel compression
#
-ifdef SYS_SUPPORTS_ZBOOT
+ifdef CONFIG_SYS_SUPPORTS_ZBOOT
COMPRESSION_FNAME = vmlinuz
else
COMPRESSION_FNAME = vmlinux
diff --git a/arch/mips/bcm47xx/Platform b/arch/mips/bcm47xx/Platform
index 874b7ca4cd11..70783b75fd9d 100644
--- a/arch/mips/bcm47xx/Platform
+++ b/arch/mips/bcm47xx/Platform
@@ -5,3 +5,4 @@ platform-$(CONFIG_BCM47XX) += bcm47xx/
cflags-$(CONFIG_BCM47XX) += \
-I$(srctree)/arch/mips/include/asm/mach-bcm47xx
load-$(CONFIG_BCM47XX) := 0xffffffff80001000
+zload-$(CONFIG_BCM47XX) += 0xffffffff80400000
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index c675eece389a..adce180f3ee4 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -133,4 +133,8 @@ vmlinuz.srec: vmlinuz
uzImage.bin: vmlinuz.bin FORCE
$(call if_changed,uimage,none)
-clean-files := $(objtree)/vmlinuz $(objtree)/vmlinuz.{32,ecoff,bin,srec}
+clean-files += $(objtree)/vmlinuz
+clean-files += $(objtree)/vmlinuz.32
+clean-files += $(objtree)/vmlinuz.ecoff
+clean-files += $(objtree)/vmlinuz.bin
+clean-files += $(objtree)/vmlinuz.srec
diff --git a/arch/mips/boot/dts/ingenic/Makefile b/arch/mips/boot/dts/ingenic/Makefile
index 6a31759839b4..5b1361a89e02 100644
--- a/arch/mips/boot/dts/ingenic/Makefile
+++ b/arch/mips/boot/dts/ingenic/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_JZ4740_QI_LB60) += qi_lb60.dtb
+dtb-$(CONFIG_JZ4770_GCW0) += gcw0.dtb
dtb-$(CONFIG_JZ4780_CI20) += ci20.dtb
obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
diff --git a/arch/mips/boot/dts/ingenic/gcw0.dts b/arch/mips/boot/dts/ingenic/gcw0.dts
new file mode 100644
index 000000000000..35f0291e8d38
--- /dev/null
+++ b/arch/mips/boot/dts/ingenic/gcw0.dts
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "jz4770.dtsi"
+
+/ {
+ compatible = "gcw,zero", "ingenic,jz4770";
+ model = "GCW Zero";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ };
+
+ chosen {
+ stdout-path = "serial2:57600n8";
+ };
+
+ board {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ otg_phy: otg-phy {
+ compatible = "usb-nop-xceiv";
+ clocks = <&cgu JZ4770_CLK_OTG_PHY>;
+ clock-names = "main_clk";
+ };
+ };
+};
+
+&ext {
+ clock-frequency = <12000000>;
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&cgu {
+ /* Put high-speed peripherals under PLL1, such that we can change the
+ * PLL0 frequency on demand without having to suspend peripherals.
+ * We use a rate of 432 MHz, which is the least common multiple of
+ * 27 MHz (required by TV encoder) and 48 MHz (required by USB host).
+ */
+ assigned-clocks =
+ <&cgu JZ4770_CLK_PLL1>,
+ <&cgu JZ4770_CLK_UHC>;
+ assigned-clock-parents =
+ <0>,
+ <&cgu JZ4770_CLK_PLL1>;
+ assigned-clock-rates =
+ <432000000>;
+};
+
+&uhc {
+ /* The WiFi module is connected to the UHC. */
+ status = "okay";
+};
diff --git a/arch/mips/boot/dts/ingenic/jz4770.dtsi b/arch/mips/boot/dts/ingenic/jz4770.dtsi
new file mode 100644
index 000000000000..7c2804f3f5f1
--- /dev/null
+++ b/arch/mips/boot/dts/ingenic/jz4770.dtsi
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dt-bindings/clock/jz4770-cgu.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "ingenic,jz4770";
+
+ cpuintc: interrupt-controller {
+ #address-cells = <0>;
+ #interrupt-cells = <1>;
+ interrupt-controller;
+ compatible = "mti,cpu-interrupt-controller";
+ };
+
+ intc: interrupt-controller@10001000 {
+ compatible = "ingenic,jz4770-intc";
+ reg = <0x10001000 0x40>;
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ interrupt-parent = <&cpuintc>;
+ interrupts = <2>;
+ };
+
+ ext: ext {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ };
+
+ osc32k: osc32k {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+
+ cgu: jz4770-cgu@10000000 {
+ compatible = "ingenic,jz4770-cgu";
+ reg = <0x10000000 0x100>;
+
+ clocks = <&ext>, <&osc32k>;
+ clock-names = "ext", "osc32k";
+
+ #clock-cells = <1>;
+ };
+
+ pinctrl: pin-controller@10010000 {
+ compatible = "ingenic,jz4770-pinctrl";
+ reg = <0x10010000 0x600>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ gpa: gpio@0 {
+ compatible = "ingenic,jz4770-gpio";
+ reg = <0>;
+
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 0 32>;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <17>;
+ };
+
+ gpb: gpio@1 {
+ compatible = "ingenic,jz4770-gpio";
+ reg = <1>;
+
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 32 32>;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <16>;
+ };
+
+ gpc: gpio@2 {
+ compatible = "ingenic,jz4770-gpio";
+ reg = <2>;
+
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 64 32>;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <15>;
+ };
+
+ gpd: gpio@3 {
+ compatible = "ingenic,jz4770-gpio";
+ reg = <3>;
+
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 96 32>;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <14>;
+ };
+
+ gpe: gpio@4 {
+ compatible = "ingenic,jz4770-gpio";
+ reg = <4>;
+
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 128 32>;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <13>;
+ };
+
+ gpf: gpio@5 {
+ compatible = "ingenic,jz4770-gpio";
+ reg = <5>;
+
+ gpio-controller;
+ gpio-ranges = <&pinctrl 0 160 32>;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <12>;
+ };
+ };
+
+ uart0: serial@10030000 {
+ compatible = "ingenic,jz4770-uart";
+ reg = <0x10030000 0x100>;
+
+ clocks = <&ext>, <&cgu JZ4770_CLK_UART0>;
+ clock-names = "baud", "module";
+
+ interrupt-parent = <&intc>;
+ interrupts = <5>;
+
+ status = "disabled";
+ };
+
+ uart1: serial@10031000 {
+ compatible = "ingenic,jz4770-uart";
+ reg = <0x10031000 0x100>;
+
+ clocks = <&ext>, <&cgu JZ4770_CLK_UART1>;
+ clock-names = "baud", "module";
+
+ interrupt-parent = <&intc>;
+ interrupts = <4>;
+
+ status = "disabled";
+ };
+
+ uart2: serial@10032000 {
+ compatible = "ingenic,jz4770-uart";
+ reg = <0x10032000 0x100>;
+
+ clocks = <&ext>, <&cgu JZ4770_CLK_UART2>;
+ clock-names = "baud", "module";
+
+ interrupt-parent = <&intc>;
+ interrupts = <3>;
+
+ status = "disabled";
+ };
+
+ uart3: serial@10033000 {
+ compatible = "ingenic,jz4770-uart";
+ reg = <0x10033000 0x100>;
+
+ clocks = <&ext>, <&cgu JZ4770_CLK_UART3>;
+ clock-names = "baud", "module";
+
+ interrupt-parent = <&intc>;
+ interrupts = <2>;
+
+ status = "disabled";
+ };
+
+ uhc: uhc@13430000 {
+ compatible = "generic-ohci";
+ reg = <0x13430000 0x1000>;
+
+ clocks = <&cgu JZ4770_CLK_UHC>, <&cgu JZ4770_CLK_UHC_PHY>;
+ assigned-clocks = <&cgu JZ4770_CLK_UHC>;
+ assigned-clock-rates = <48000000>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <20>;
+
+ status = "disabled";
+ };
+};
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index a55009edbb29..5e73fe755be6 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -153,7 +153,6 @@ CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y
# CONFIG_INPUT is not set
-# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_RAW=m
# CONFIG_VT is not set
CONFIG_SERIAL_NONSTANDARD=y
diff --git a/arch/mips/configs/gcw0_defconfig b/arch/mips/configs/gcw0_defconfig
new file mode 100644
index 000000000000..99ac1fa3b35f
--- /dev/null
+++ b/arch/mips/configs/gcw0_defconfig
@@ -0,0 +1,27 @@
+CONFIG_MACH_INGENIC=y
+CONFIG_JZ4770_GCW0=y
+CONFIG_HIGHMEM=y
+# CONFIG_BOUNCE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_SECCOMP is not set
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_EMBEDDED=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_NETDEVICES=y
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_INGENIC=y
+CONFIG_USB=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_TMPFS=y
diff --git a/arch/mips/configs/generic/board-ranchu.config b/arch/mips/configs/generic/board-ranchu.config
new file mode 100644
index 000000000000..fee9ad4c5598
--- /dev/null
+++ b/arch/mips/configs/generic/board-ranchu.config
@@ -0,0 +1,30 @@
+CONFIG_VIRT_BOARD_RANCHU=y
+
+CONFIG_BATTERY_GOLDFISH=y
+CONFIG_FB=y
+CONFIG_FB_GOLDFISH=y
+CONFIG_GOLDFISH=y
+CONFIG_STAGING=y
+CONFIG_GOLDFISH_AUDIO=y
+CONFIG_GOLDFISH_PIC=y
+CONFIG_GOLDFISH_PIPE=y
+CONFIG_GOLDFISH_TTY=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_GOLDFISH=y
+
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_GOLDFISH_EVENTS=y
+
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+
+CONFIG_VIRTIO_BLK=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
+CONFIG_NETDEVICES=y
+CONFIG_VIRTIO_NET=y
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index a0d593248668..91a9c13e2c82 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -252,7 +252,6 @@ CONFIG_RT2800PCI=m
CONFIG_WL12XX=m
CONFIG_WL1251=m
# CONFIG_INPUT is not set
-# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_LIBPS2=m
CONFIG_SERIO_RAW=m
CONFIG_SERIO_ALTERA_PS2=m
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 1e26e58b9dc3..ebff297328ae 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -75,7 +75,6 @@ CONFIG_DE2104X=m
CONFIG_TULIP=m
CONFIG_TULIP_MMIO=y
CONFIG_INPUT_EVDEV=m
-# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_MACEPS2=y
CONFIG_SERIO_RAW=y
# CONFIG_CONSOLE_TRANSLATIONS is not set
diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig
index 396408404487..df8a9a15ca83 100644
--- a/arch/mips/configs/malta_defconfig
+++ b/arch/mips/configs/malta_defconfig
@@ -312,9 +312,8 @@ CONFIG_HOSTAP_PCI=m
CONFIG_IPW2100=m
CONFIG_IPW2100_MONITOR=y
CONFIG_LIBERTAS=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_POWER_RESET=y
diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig
index 5691673a3327..14df9ef15d40 100644
--- a/arch/mips/configs/malta_kvm_defconfig
+++ b/arch/mips/configs/malta_kvm_defconfig
@@ -324,9 +324,7 @@ CONFIG_HOSTAP_PCI=m
CONFIG_IPW2100=m
CONFIG_IPW2100_MONITOR=y
CONFIG_LIBERTAS=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
+CONFIG_INPUT_MOUSEDEV=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_POWER_RESET=y
diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig
index e9cadb37d684..25092e344574 100644
--- a/arch/mips/configs/malta_kvm_guest_defconfig
+++ b/arch/mips/configs/malta_kvm_guest_defconfig
@@ -326,9 +326,7 @@ CONFIG_HOSTAP_PCI=m
CONFIG_IPW2100=m
CONFIG_IPW2100_MONITOR=y
CONFIG_LIBERTAS=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
+CONFIG_INPUT_MOUSEDEV=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_POWER_RESET=y
diff --git a/arch/mips/configs/malta_qemu_32r6_defconfig b/arch/mips/configs/malta_qemu_32r6_defconfig
index 77145ecaa23b..210bf609f785 100644
--- a/arch/mips/configs/malta_qemu_32r6_defconfig
+++ b/arch/mips/configs/malta_qemu_32r6_defconfig
@@ -126,6 +126,7 @@ CONFIG_PCNET32=y
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=y
# CONFIG_VT is not set
CONFIG_LEGACY_PTY_COUNT=4
CONFIG_SERIAL_8250=y
diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig
index cc2687cfdc13..e5934aa98397 100644
--- a/arch/mips/configs/maltaaprp_defconfig
+++ b/arch/mips/configs/maltaaprp_defconfig
@@ -126,6 +126,7 @@ CONFIG_PCNET32=y
# CONFIG_NET_VENDOR_TOSHIBA is not set
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=y
# CONFIG_VT is not set
CONFIG_LEGACY_PTY_COUNT=16
CONFIG_SERIAL_8250=y
diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig
index d8c8f5fb8918..cb2ca11c1789 100644
--- a/arch/mips/configs/maltasmvp_defconfig
+++ b/arch/mips/configs/maltasmvp_defconfig
@@ -127,6 +127,7 @@ CONFIG_PCNET32=y
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=y
# CONFIG_VT is not set
CONFIG_LEGACY_PTY_COUNT=4
CONFIG_SERIAL_8250=y
diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig
index 04827bc9f87f..be29fcec69fc 100644
--- a/arch/mips/configs/maltasmvp_eva_defconfig
+++ b/arch/mips/configs/maltasmvp_eva_defconfig
@@ -130,6 +130,7 @@ CONFIG_PCNET32=y
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set
# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=y
# CONFIG_VT is not set
CONFIG_LEGACY_PTY_COUNT=4
CONFIG_SERIAL_8250=y
diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig
index 7ea7c0ba2666..40462d4c90a0 100644
--- a/arch/mips/configs/maltaup_defconfig
+++ b/arch/mips/configs/maltaup_defconfig
@@ -125,6 +125,7 @@ CONFIG_PCNET32=y
# CONFIG_NET_VENDOR_TOSHIBA is not set
# CONFIG_NET_VENDOR_VIA is not set
# CONFIG_WLAN is not set
+CONFIG_INPUT_MOUSEDEV=y
# CONFIG_VT is not set
CONFIG_LEGACY_PTY_COUNT=16
CONFIG_SERIAL_8250=y
diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig
index 2942610e4082..4e50176cb3df 100644
--- a/arch/mips/configs/maltaup_xpa_defconfig
+++ b/arch/mips/configs/maltaup_xpa_defconfig
@@ -321,9 +321,8 @@ CONFIG_HOSTAP_PCI=m
CONFIG_IPW2100=m
CONFIG_IPW2100_MONITOR=y
CONFIG_LIBERTAS=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_POWER_RESET=y
diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig
index 7357248b3d7a..e8e1dd8e0e99 100644
--- a/arch/mips/configs/nlm_xlp_defconfig
+++ b/arch/mips/configs/nlm_xlp_defconfig
@@ -399,7 +399,6 @@ CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=m
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=m
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=m
diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig
index 1e18fd7de209..c4477a4d40c1 100644
--- a/arch/mips/configs/nlm_xlr_defconfig
+++ b/arch/mips/configs/nlm_xlr_defconfig
@@ -332,7 +332,6 @@ CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=m
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_SERPORT=m
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_RAW=m
diff --git a/arch/mips/configs/pnx8335_stb225_defconfig b/arch/mips/configs/pnx8335_stb225_defconfig
index 81b5eb89446c..e73cdb08fc6e 100644
--- a/arch/mips/configs/pnx8335_stb225_defconfig
+++ b/arch/mips/configs/pnx8335_stb225_defconfig
@@ -49,7 +49,6 @@ CONFIG_INPUT_EVDEV=m
CONFIG_INPUT_EVBUG=m
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
# CONFIG_VT_CONSOLE is not set
CONFIG_SERIAL_PNX8XXX=y
CONFIG_SERIAL_PNX8XXX_CONSOLE=y
diff --git a/arch/mips/configs/sb1250_swarm_defconfig b/arch/mips/configs/sb1250_swarm_defconfig
index c724bdd6a7e6..1edd8430ad61 100644
--- a/arch/mips/configs/sb1250_swarm_defconfig
+++ b/arch/mips/configs/sb1250_swarm_defconfig
@@ -65,7 +65,6 @@ CONFIG_NET_ETHERNET=y
CONFIG_MII=y
CONFIG_SB1250_MAC=y
# CONFIG_INPUT is not set
-# CONFIG_SERIO_I8042 is not set
CONFIG_SERIO_RAW=m
# CONFIG_VT is not set
# CONFIG_HW_RANDOM is not set
diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig
index 52e0286a1612..2ff3b17bfab1 100644
--- a/arch/mips/generic/Kconfig
+++ b/arch/mips/generic/Kconfig
@@ -49,4 +49,14 @@ config FIT_IMAGE_FDT_XILFPGA
Enable this to include the FDT for the MIPSfpga platform
from Imagination Technologies in the FIT kernel image.
+config VIRT_BOARD_RANCHU
+ bool "Support Ranchu platform for Android emulator"
+ help
+ This enables support for the platform used by Android emulator.
+
+ Ranchu platform consists of a set of virtual devices. This platform
+ enables emulation of variety of virtual configurations while using
+ Android emulator. Android emulator is based on Qemu, and contains
+ the support for the same set of virtual devices.
+
endif
diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile
index 874967363dbb..5c31e0c4697d 100644
--- a/arch/mips/generic/Makefile
+++ b/arch/mips/generic/Makefile
@@ -15,3 +15,4 @@ obj-y += proc.o
obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o
obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o
obj-$(CONFIG_KEXEC) += kexec.o
+obj-$(CONFIG_VIRT_BOARD_RANCHU) += board-ranchu.o
diff --git a/arch/mips/generic/board-ranchu.c b/arch/mips/generic/board-ranchu.c
new file mode 100644
index 000000000000..59a8c18fa2cc
--- /dev/null
+++ b/arch/mips/generic/board-ranchu.c
@@ -0,0 +1,93 @@
+/*
+ * Support code for virtual Ranchu board for MIPS.
+ *
+ * Author: Miodrag Dinic <miodrag.dinic@mips.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/of_address.h>
+#include <linux/types.h>
+
+#include <asm/machine.h>
+#include <asm/mipsregs.h>
+#include <asm/time.h>
+
+#define GOLDFISH_TIMER_LOW 0x00
+#define GOLDFISH_TIMER_HIGH 0x04
+
+static __init u64 read_rtc_time(void __iomem *base)
+{
+ u32 time_low;
+ u32 time_high;
+
+ /*
+ * Reading the low address latches the high value
+ * as well so there is no fear that we may read
+ * inaccurate high value.
+ */
+ time_low = readl(base + GOLDFISH_TIMER_LOW);
+ time_high = readl(base + GOLDFISH_TIMER_HIGH);
+
+ return ((u64)time_high << 32) | time_low;
+}
+
+static __init unsigned int ranchu_measure_hpt_freq(void)
+{
+ u64 rtc_start, rtc_current, rtc_delta;
+ unsigned int start, count;
+ struct device_node *np;
+ void __iomem *rtc_base;
+
+ np = of_find_compatible_node(NULL, NULL, "google,goldfish-rtc");
+ if (!np)
+ panic("%s(): Failed to find 'google,goldfish-rtc' dt node!",
+ __func__);
+
+ rtc_base = of_iomap(np, 0);
+ if (!rtc_base)
+ panic("%s(): Failed to ioremap Goldfish RTC base!", __func__);
+
+ /*
+ * Poll the nanosecond resolution RTC for one
+ * second to calibrate the CPU frequency.
+ */
+ rtc_start = read_rtc_time(rtc_base);
+ start = read_c0_count();
+
+ do {
+ rtc_current = read_rtc_time(rtc_base);
+ rtc_delta = rtc_current - rtc_start;
+ } while (rtc_delta < NSEC_PER_SEC);
+
+ count = read_c0_count() - start;
+
+ /*
+ * Make sure the frequency will be a round number.
+ * Without this correction, the returned value may vary
+ * between subsequent emulation executions.
+ *
+ * TODO: Set this value using device tree.
+ */
+ count += 5000;
+ count -= count % 10000;
+
+ iounmap(rtc_base);
+
+ return count;
+}
+
+static const struct of_device_id ranchu_of_match[] __initconst = {
+ {
+ .compatible = "mti,ranchu",
+ },
+ {}
+};
+
+MIPS_MACHINE(ranchu) = {
+ .matches = ranchu_of_match,
+ .measure_hpt_freq = ranchu_measure_hpt_freq,
+};
diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c
index 394f8161e462..cb7fdaeef426 100644
--- a/arch/mips/generic/irq.c
+++ b/arch/mips/generic/irq.c
@@ -22,10 +22,10 @@ int get_c0_fdc_int(void)
{
int mips_cpu_fdc_irq;
- if (cpu_has_veic)
- panic("Unimplemented!");
- else if (mips_gic_present())
+ if (mips_gic_present())
mips_cpu_fdc_irq = gic_get_c0_fdc_int();
+ else if (cpu_has_veic)
+ panic("Unimplemented!");
else if (cp0_fdc_irq >= 0)
mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
else
@@ -38,10 +38,10 @@ int get_c0_perfcount_int(void)
{
int mips_cpu_perf_irq;
- if (cpu_has_veic)
- panic("Unimplemented!");
- else if (mips_gic_present())
+ if (mips_gic_present())
mips_cpu_perf_irq = gic_get_c0_perfcount_int();
+ else if (cpu_has_veic)
+ panic("Unimplemented!");
else if (cp0_perfcount_irq >= 0)
mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
else
@@ -54,10 +54,10 @@ unsigned int get_c0_compare_int(void)
{
int mips_cpu_timer_irq;
- if (cpu_has_veic)
- panic("Unimplemented!");
- else if (mips_gic_present())
+ if (mips_gic_present())
mips_cpu_timer_irq = gic_get_c0_compare_int();
+ else if (cpu_has_veic)
+ panic("Unimplemented!");
else
mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index e26a093bb17a..a301a8f4bc66 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -79,6 +79,8 @@ enum loongson_machine_type {
*/
#define MACH_INGENIC_JZ4730 0 /* JZ4730 SOC */
#define MACH_INGENIC_JZ4740 1 /* JZ4740 SOC */
+#define MACH_INGENIC_JZ4770 2 /* JZ4770 SOC */
+#define MACH_INGENIC_JZ4780 3 /* JZ4780 SOC */
extern char *system_type;
const char *get_system_type(void);
diff --git a/arch/mips/include/asm/checksum.h b/arch/mips/include/asm/checksum.h
index 77cad232a1c6..e8161e4dfde7 100644
--- a/arch/mips/include/asm/checksum.h
+++ b/arch/mips/include/asm/checksum.h
@@ -110,7 +110,7 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst,
*/
static inline __sum16 csum_fold(__wsum csum)
{
- u32 sum = (__force u32)csum;;
+ u32 sum = (__force u32)csum;
sum += (sum << 16);
csum = (sum < csum);
diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h
index 4f69f08717f6..8c286bedff3e 100644
--- a/arch/mips/include/asm/mach-loongson64/boot_param.h
+++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
@@ -4,7 +4,7 @@
#define SYSTEM_RAM_LOW 1
#define SYSTEM_RAM_HIGH 2
-#define MEM_RESERVED 3
+#define SYSTEM_RAM_RESERVED 3
#define PCI_IO 4
#define PCI_MEM 5
#define LOONGSON_CFG_REG 6
diff --git a/arch/mips/include/asm/machine.h b/arch/mips/include/asm/machine.h
index e0d9b373d415..f83879dadd1e 100644
--- a/arch/mips/include/asm/machine.h
+++ b/arch/mips/include/asm/machine.h
@@ -52,7 +52,7 @@ mips_machine_is_compatible(const struct mips_machine *mach, const void *fdt)
if (!mach->matches)
return NULL;
- for (match = mach->matches; match->compatible; match++) {
+ for (match = mach->matches; match->compatible[0]; match++) {
if (fdt_node_check_compatible(fdt, 0, match->compatible) == 0)
return match;
}
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 6b1f1ad0542c..858752dac337 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1181,6 +1181,89 @@ static inline int mm_insn_16bit(u16 insn)
#endif
/*
+ * parse_r var, r - Helper assembler macro for parsing register names.
+ *
+ * This converts the register name in $n form provided in \r to the
+ * corresponding register number, which is assigned to the variable \var. It is
+ * needed to allow explicit encoding of instructions in inline assembly where
+ * registers are chosen by the compiler in $n form, allowing us to avoid using
+ * fixed register numbers.
+ *
+ * It also allows newer instructions (not implemented by the assembler) to be
+ * transparently implemented using assembler macros, instead of needing separate
+ * cases depending on toolchain support.
+ *
+ * Simple usage example:
+ * __asm__ __volatile__("parse_r __rt, %0\n\t"
+ * ".insn\n\t"
+ * "# di %0\n\t"
+ * ".word (0x41606000 | (__rt << 16))"
+ * : "=r" (status);
+ */
+
+/* Match an individual register number and assign to \var */
+#define _IFC_REG(n) \
+ ".ifc \\r, $" #n "\n\t" \
+ "\\var = " #n "\n\t" \
+ ".endif\n\t"
+
+__asm__(".macro parse_r var r\n\t"
+ "\\var = -1\n\t"
+ _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3)
+ _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7)
+ _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11)
+ _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15)
+ _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19)
+ _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23)
+ _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27)
+ _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31)
+ ".iflt \\var\n\t"
+ ".error \"Unable to parse register name \\r\"\n\t"
+ ".endif\n\t"
+ ".endm");
+
+#undef _IFC_REG
+
+/*
+ * C macros for generating assembler macros for common instruction formats.
+ *
+ * The names of the operands can be chosen by the caller, and the encoding of
+ * register operand \<Rn> is assigned to __<Rn> where it can be accessed from
+ * the ENC encodings.
+ */
+
+/* Instructions with no operands */
+#define _ASM_MACRO_0(OP, ENC) \
+ __asm__(".macro " #OP "\n\t" \
+ ENC \
+ ".endm")
+
+/* Instructions with 2 register operands */
+#define _ASM_MACRO_2R(OP, R1, R2, ENC) \
+ __asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \
+ "parse_r __" #R1 ", \\" #R1 "\n\t" \
+ "parse_r __" #R2 ", \\" #R2 "\n\t" \
+ ENC \
+ ".endm")
+
+/* Instructions with 3 register operands */
+#define _ASM_MACRO_3R(OP, R1, R2, R3, ENC) \
+ __asm__(".macro " #OP " " #R1 ", " #R2 ", " #R3 "\n\t" \
+ "parse_r __" #R1 ", \\" #R1 "\n\t" \
+ "parse_r __" #R2 ", \\" #R2 "\n\t" \
+ "parse_r __" #R3 ", \\" #R3 "\n\t" \
+ ENC \
+ ".endm")
+
+/* Instructions with 2 register operands and 1 optional select operand */
+#define _ASM_MACRO_2R_1S(OP, R1, R2, SEL3, ENC) \
+ __asm__(".macro " #OP " " #R1 ", " #R2 ", " #SEL3 " = 0\n\t" \
+ "parse_r __" #R1 ", \\" #R1 "\n\t" \
+ "parse_r __" #R2 ", \\" #R2 "\n\t" \
+ ENC \
+ ".endm")
+
+/*
* TLB Invalidate Flush
*/
static inline void tlbinvf(void)
@@ -1245,14 +1328,14 @@ do { \
* Macros to access the system control coprocessor
*/
-#define __read_32bit_c0_register(source, sel) \
+#define ___read_32bit_c0_register(source, sel, vol) \
({ unsigned int __res; \
if (sel == 0) \
- __asm__ __volatile__( \
+ __asm__ vol( \
"mfc0\t%0, " #source "\n\t" \
: "=r" (__res)); \
else \
- __asm__ __volatile__( \
+ __asm__ vol( \
".set\tmips32\n\t" \
"mfc0\t%0, " #source ", " #sel "\n\t" \
".set\tmips0\n\t" \
@@ -1260,18 +1343,18 @@ do { \
__res; \
})
-#define __read_64bit_c0_register(source, sel) \
+#define ___read_64bit_c0_register(source, sel, vol) \
({ unsigned long long __res; \
if (sizeof(unsigned long) == 4) \
- __res = __read_64bit_c0_split(source, sel); \
+ __res = __read_64bit_c0_split(source, sel, vol); \
else if (sel == 0) \
- __asm__ __volatile__( \
+ __asm__ vol( \
".set\tmips3\n\t" \
"dmfc0\t%0, " #source "\n\t" \
".set\tmips0" \
: "=r" (__res)); \
else \
- __asm__ __volatile__( \
+ __asm__ vol( \
".set\tmips64\n\t" \
"dmfc0\t%0, " #source ", " #sel "\n\t" \
".set\tmips0" \
@@ -1279,6 +1362,18 @@ do { \
__res; \
})
+#define __read_32bit_c0_register(source, sel) \
+ ___read_32bit_c0_register(source, sel, __volatile__)
+
+#define __read_const_32bit_c0_register(source, sel) \
+ ___read_32bit_c0_register(source, sel,)
+
+#define __read_64bit_c0_register(source, sel) \
+ ___read_64bit_c0_register(source, sel, __volatile__)
+
+#define __read_const_64bit_c0_register(source, sel) \
+ ___read_64bit_c0_register(source, sel,)
+
#define __write_32bit_c0_register(register, sel, value) \
do { \
if (sel == 0) \
@@ -1316,6 +1411,11 @@ do { \
(unsigned long) __read_32bit_c0_register(reg, sel) : \
(unsigned long) __read_64bit_c0_register(reg, sel))
+#define __read_const_ulong_c0_register(reg, sel) \
+ ((sizeof(unsigned long) == 4) ? \
+ (unsigned long) __read_const_32bit_c0_register(reg, sel) : \
+ (unsigned long) __read_const_64bit_c0_register(reg, sel))
+
#define __write_ulong_c0_register(reg, sel, val) \
do { \
if (sizeof(unsigned long) == 4) \
@@ -1346,14 +1446,14 @@ do { \
* These versions are only needed for systems with more than 38 bits of
* physical address space running the 32-bit kernel. That's none atm :-)
*/
-#define __read_64bit_c0_split(source, sel) \
+#define __read_64bit_c0_split(source, sel, vol) \
({ \
unsigned long long __val; \
unsigned long __flags; \
\
local_irq_save(__flags); \
if (sel == 0) \
- __asm__ __volatile__( \
+ __asm__ vol( \
".set\tmips64\n\t" \
"dmfc0\t%L0, " #source "\n\t" \
"dsra\t%M0, %L0, 32\n\t" \
@@ -1361,7 +1461,7 @@ do { \
".set\tmips0" \
: "=r" (__val)); \
else \
- __asm__ __volatile__( \
+ __asm__ vol( \
".set\tmips64\n\t" \
"dmfc0\t%L0, " #source ", " #sel "\n\t" \
"dsra\t%M0, %L0, 32\n\t" \
@@ -1404,37 +1504,43 @@ do { \
local_irq_restore(__flags); \
} while (0)
-#define __readx_32bit_c0_register(source) \
+#ifndef TOOLCHAIN_SUPPORTS_XPA
+_ASM_MACRO_2R_1S(mfhc0, rt, rs, sel,
+ _ASM_INSN_IF_MIPS(0x40400000 | __rt << 16 | __rs << 11 | \\sel)
+ _ASM_INSN32_IF_MM(0x000000f4 | __rt << 21 | __rs << 16 | \\sel << 11));
+_ASM_MACRO_2R_1S(mthc0, rt, rd, sel,
+ _ASM_INSN_IF_MIPS(0x40c00000 | __rt << 16 | __rd << 11 | \\sel)
+ _ASM_INSN32_IF_MM(0x000002f4 | __rt << 21 | __rd << 16 | \\sel << 11));
+#define _ASM_SET_XPA ""
+#else /* !TOOLCHAIN_SUPPORTS_XPA */
+#define _ASM_SET_XPA ".set\txpa\n\t"
+#endif
+
+#define __readx_32bit_c0_register(source, sel) \
({ \
unsigned int __res; \
\
__asm__ __volatile__( \
" .set push \n" \
- " .set noat \n" \
" .set mips32r2 \n" \
- " # mfhc0 $1, %1 \n" \
- _ASM_INSN_IF_MIPS(0x40410000 | ((%1 & 0x1f) << 11)) \
- _ASM_INSN32_IF_MM(0x002000f4 | ((%1 & 0x1f) << 16)) \
- " move %0, $1 \n" \
+ _ASM_SET_XPA \
+ " mfhc0 %0, " #source ", %1 \n" \
" .set pop \n" \
: "=r" (__res) \
- : "i" (source)); \
+ : "i" (sel)); \
__res; \
})
-#define __writex_32bit_c0_register(register, value) \
+#define __writex_32bit_c0_register(register, sel, value) \
do { \
__asm__ __volatile__( \
" .set push \n" \
- " .set noat \n" \
" .set mips32r2 \n" \
- " move $1, %0 \n" \
- " # mthc0 $1, %1 \n" \
- _ASM_INSN_IF_MIPS(0x40c10000 | ((%1 & 0x1f) << 11)) \
- _ASM_INSN32_IF_MM(0x002002f4 | ((%1 & 0x1f) << 16)) \
+ _ASM_SET_XPA \
+ " mthc0 %z0, " #register ", %1 \n" \
" .set pop \n" \
: \
- : "r" (value), "i" (register)); \
+ : "Jr" (value), "i" (sel)); \
} while (0)
#define read_c0_index() __read_32bit_c0_register($0, 0)
@@ -1446,14 +1552,14 @@ do { \
#define read_c0_entrylo0() __read_ulong_c0_register($2, 0)
#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val)
-#define readx_c0_entrylo0() __readx_32bit_c0_register(2)
-#define writex_c0_entrylo0(val) __writex_32bit_c0_register(2, val)
+#define readx_c0_entrylo0() __readx_32bit_c0_register($2, 0)
+#define writex_c0_entrylo0(val) __writex_32bit_c0_register($2, 0, val)
#define read_c0_entrylo1() __read_ulong_c0_register($3, 0)
#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val)
-#define readx_c0_entrylo1() __readx_32bit_c0_register(3)
-#define writex_c0_entrylo1(val) __writex_32bit_c0_register(3, val)
+#define readx_c0_entrylo1() __readx_32bit_c0_register($3, 0)
+#define writex_c0_entrylo1(val) __writex_32bit_c0_register($3, 0, val)
#define read_c0_conf() __read_32bit_c0_register($3, 0)
#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val)
@@ -1541,7 +1647,7 @@ do { \
#define read_c0_epc() __read_ulong_c0_register($14, 0)
#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val)
-#define read_c0_prid() __read_32bit_c0_register($15, 0)
+#define read_c0_prid() __read_const_32bit_c0_register($15, 0)
#define read_c0_cmgcrbase() __read_ulong_c0_register($15, 3)
@@ -1830,18 +1936,44 @@ do { \
* Macros to access the guest system control coprocessor
*/
-#ifdef TOOLCHAIN_SUPPORTS_VIRT
+#ifndef TOOLCHAIN_SUPPORTS_VIRT
+_ASM_MACRO_2R_1S(mfgc0, rt, rs, sel,
+ _ASM_INSN_IF_MIPS(0x40600000 | __rt << 16 | __rs << 11 | \\sel)
+ _ASM_INSN32_IF_MM(0x000004fc | __rt << 21 | __rs << 16 | \\sel << 11));
+_ASM_MACRO_2R_1S(dmfgc0, rt, rs, sel,
+ _ASM_INSN_IF_MIPS(0x40600100 | __rt << 16 | __rs << 11 | \\sel)
+ _ASM_INSN32_IF_MM(0x580004fc | __rt << 21 | __rs << 16 | \\sel << 11));
+_ASM_MACRO_2R_1S(mtgc0, rt, rd, sel,
+ _ASM_INSN_IF_MIPS(0x40600200 | __rt << 16 | __rd << 11 | \\sel)
+ _ASM_INSN32_IF_MM(0x000006fc | __rt << 21 | __rd << 16 | \\sel << 11));
+_ASM_MACRO_2R_1S(dmtgc0, rt, rd, sel,
+ _ASM_INSN_IF_MIPS(0x40600300 | __rt << 16 | __rd << 11 | \\sel)
+ _ASM_INSN32_IF_MM(0x580006fc | __rt << 21 | __rd << 16 | \\sel << 11));
+_ASM_MACRO_0(tlbgp, _ASM_INSN_IF_MIPS(0x42000010)
+ _ASM_INSN32_IF_MM(0x0000017c));
+_ASM_MACRO_0(tlbgr, _ASM_INSN_IF_MIPS(0x42000009)
+ _ASM_INSN32_IF_MM(0x0000117c));
+_ASM_MACRO_0(tlbgwi, _ASM_INSN_IF_MIPS(0x4200000a)
+ _ASM_INSN32_IF_MM(0x0000217c));
+_ASM_MACRO_0(tlbgwr, _ASM_INSN_IF_MIPS(0x4200000e)
+ _ASM_INSN32_IF_MM(0x0000317c));
+_ASM_MACRO_0(tlbginvf, _ASM_INSN_IF_MIPS(0x4200000c)
+ _ASM_INSN32_IF_MM(0x0000517c));
+#define _ASM_SET_VIRT ""
+#else /* !TOOLCHAIN_SUPPORTS_VIRT */
+#define _ASM_SET_VIRT ".set\tvirt\n\t"
+#endif
#define __read_32bit_gc0_register(source, sel) \
({ int __res; \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips32r2\n\t" \
- ".set\tvirt\n\t" \
- "mfgc0\t%0, $%1, %2\n\t" \
+ _ASM_SET_VIRT \
+ "mfgc0\t%0, " #source ", %1\n\t" \
".set\tpop" \
: "=r" (__res) \
- : "i" (source), "i" (sel)); \
+ : "i" (sel)); \
__res; \
})
@@ -1850,11 +1982,11 @@ do { \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips64r2\n\t" \
- ".set\tvirt\n\t" \
- "dmfgc0\t%0, $%1, %2\n\t" \
+ _ASM_SET_VIRT \
+ "dmfgc0\t%0, " #source ", %1\n\t" \
".set\tpop" \
: "=r" (__res) \
- : "i" (source), "i" (sel)); \
+ : "i" (sel)); \
__res; \
})
@@ -1863,11 +1995,11 @@ do { \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips32r2\n\t" \
- ".set\tvirt\n\t" \
- "mtgc0\t%z0, $%1, %2\n\t" \
+ _ASM_SET_VIRT \
+ "mtgc0\t%z0, " #register ", %1\n\t" \
".set\tpop" \
: : "Jr" ((unsigned int)(value)), \
- "i" (register), "i" (sel)); \
+ "i" (sel)); \
} while (0)
#define __write_64bit_gc0_register(register, sel, value) \
@@ -1875,75 +2007,13 @@ do { \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\tmips64r2\n\t" \
- ".set\tvirt\n\t" \
- "dmtgc0\t%z0, $%1, %2\n\t" \
+ _ASM_SET_VIRT \
+ "dmtgc0\t%z0, " #register ", %1\n\t" \
".set\tpop" \
: : "Jr" (value), \
- "i" (register), "i" (sel)); \
+ "i" (sel)); \
} while (0)
-#else /* TOOLCHAIN_SUPPORTS_VIRT */
-
-#define __read_32bit_gc0_register(source, sel) \
-({ int __res; \
- __asm__ __volatile__( \
- ".set\tpush\n\t" \
- ".set\tnoat\n\t" \
- "# mfgc0\t$1, $%1, %2\n\t" \
- _ASM_INSN_IF_MIPS(0x40610000 | %1 << 11 | %2) \
- _ASM_INSN32_IF_MM(0x002004fc | %1 << 16 | %2 << 11) \
- "move\t%0, $1\n\t" \
- ".set\tpop" \
- : "=r" (__res) \
- : "i" (source), "i" (sel)); \
- __res; \
-})
-
-#define __read_64bit_gc0_register(source, sel) \
-({ unsigned long long __res; \
- __asm__ __volatile__( \
- ".set\tpush\n\t" \
- ".set\tnoat\n\t" \
- "# dmfgc0\t$1, $%1, %2\n\t" \
- _ASM_INSN_IF_MIPS(0x40610100 | %1 << 11 | %2) \
- _ASM_INSN32_IF_MM(0x582004fc | %1 << 16 | %2 << 11) \
- "move\t%0, $1\n\t" \
- ".set\tpop" \
- : "=r" (__res) \
- : "i" (source), "i" (sel)); \
- __res; \
-})
-
-#define __write_32bit_gc0_register(register, sel, value) \
-do { \
- __asm__ __volatile__( \
- ".set\tpush\n\t" \
- ".set\tnoat\n\t" \
- "move\t$1, %z0\n\t" \
- "# mtgc0\t$1, $%1, %2\n\t" \
- _ASM_INSN_IF_MIPS(0x40610200 | %1 << 11 | %2) \
- _ASM_INSN32_IF_MM(0x002006fc | %1 << 16 | %2 << 11) \
- ".set\tpop" \
- : : "Jr" ((unsigned int)(value)), \
- "i" (register), "i" (sel)); \
-} while (0)
-
-#define __write_64bit_gc0_register(register, sel, value) \
-do { \
- __asm__ __volatile__( \
- ".set\tpush\n\t" \
- ".set\tnoat\n\t" \
- "move\t$1, %z0\n\t" \
- "# dmtgc0\t$1, $%1, %2\n\t" \
- _ASM_INSN_IF_MIPS(0x40610300 | %1 << 11 | %2) \
- _ASM_INSN32_IF_MM(0x582006fc | %1 << 16 | %2 << 11) \
- ".set\tpop" \
- : : "Jr" (value), \
- "i" (register), "i" (sel)); \
-} while (0)
-
-#endif /* !TOOLCHAIN_SUPPORTS_VIRT */
-
#define __read_ulong_gc0_register(reg, sel) \
((sizeof(unsigned long) == 4) ? \
(unsigned long) __read_32bit_gc0_register(reg, sel) : \
@@ -1957,207 +2027,207 @@ do { \
__write_64bit_gc0_register(reg, sel, val); \
} while (0)
-#define read_gc0_index() __read_32bit_gc0_register(0, 0)
-#define write_gc0_index(val) __write_32bit_gc0_register(0, 0, val)
+#define read_gc0_index() __read_32bit_gc0_register($0, 0)
+#define write_gc0_index(val) __write_32bit_gc0_register($0, 0, val)
-#define read_gc0_entrylo0() __read_ulong_gc0_register(2, 0)
-#define write_gc0_entrylo0(val) __write_ulong_gc0_register(2, 0, val)
+#define read_gc0_entrylo0() __read_ulong_gc0_register($2, 0)
+#define write_gc0_entrylo0(val) __write_ulong_gc0_register($2, 0, val)
-#define read_gc0_entrylo1() __read_ulong_gc0_register(3, 0)
-#define write_gc0_entrylo1(val) __write_ulong_gc0_register(3, 0, val)
+#define read_gc0_entrylo1() __read_ulong_gc0_register($3, 0)
+#define write_gc0_entrylo1(val) __write_ulong_gc0_register($3, 0, val)
-#define read_gc0_context() __read_ulong_gc0_register(4, 0)
-#define write_gc0_context(val) __write_ulong_gc0_register(4, 0, val)
+#define read_gc0_context() __read_ulong_gc0_register($4, 0)
+#define write_gc0_context(val) __write_ulong_gc0_register($4, 0, val)
-#define read_gc0_contextconfig() __read_32bit_gc0_register(4, 1)
-#define write_gc0_contextconfig(val) __write_32bit_gc0_register(4, 1, val)
+#define read_gc0_contextconfig() __read_32bit_gc0_register($4, 1)
+#define write_gc0_contextconfig(val) __write_32bit_gc0_register($4, 1, val)
-#define read_gc0_userlocal() __read_ulong_gc0_register(4, 2)
-#define write_gc0_userlocal(val) __write_ulong_gc0_register(4, 2, val)
+#define read_gc0_userlocal() __read_ulong_gc0_register($4, 2)
+#define write_gc0_userlocal(val) __write_ulong_gc0_register($4, 2, val)
-#define read_gc0_xcontextconfig() __read_ulong_gc0_register(4, 3)
-#define write_gc0_xcontextconfig(val) __write_ulong_gc0_register(4, 3, val)
+#define read_gc0_xcontextconfig() __read_ulong_gc0_register($4, 3)
+#define write_gc0_xcontextconfig(val) __write_ulong_gc0_register($4, 3, val)
-#define read_gc0_pagemask() __read_32bit_gc0_register(5, 0)
-#define write_gc0_pagemask(val) __write_32bit_gc0_register(5, 0, val)
+#define read_gc0_pagemask() __read_32bit_gc0_register($5, 0)
+#define write_gc0_pagemask(val) __write_32bit_gc0_register($5, 0, val)
-#define read_gc0_pagegrain() __read_32bit_gc0_register(5, 1)
-#define write_gc0_pagegrain(val) __write_32bit_gc0_register(5, 1, val)
+#define read_gc0_pagegrain() __read_32bit_gc0_register($5, 1)
+#define write_gc0_pagegrain(val) __write_32bit_gc0_register($5, 1, val)
-#define read_gc0_segctl0() __read_ulong_gc0_register(5, 2)
-#define write_gc0_segctl0(val) __write_ulong_gc0_register(5, 2, val)
+#define read_gc0_segctl0() __read_ulong_gc0_register($5, 2)
+#define write_gc0_segctl0(val) __write_ulong_gc0_register($5, 2, val)
-#define read_gc0_segctl1() __read_ulong_gc0_register(5, 3)
-#define write_gc0_segctl1(val) __write_ulong_gc0_register(5, 3, val)
+#define read_gc0_segctl1() __read_ulong_gc0_register($5, 3)
+#define write_gc0_segctl1(val) __write_ulong_gc0_register($5, 3, val)
-#define read_gc0_segctl2() __read_ulong_gc0_register(5, 4)
-#define write_gc0_segctl2(val) __write_ulong_gc0_register(5, 4, val)
+#define read_gc0_segctl2() __read_ulong_gc0_register($5, 4)
+#define write_gc0_segctl2(val) __write_ulong_gc0_register($5, 4, val)
-#define read_gc0_pwbase() __read_ulong_gc0_register(5, 5)
-#define write_gc0_pwbase(val) __write_ulong_gc0_register(5, 5, val)
+#define read_gc0_pwbase() __read_ulong_gc0_register($5, 5)
+#define write_gc0_pwbase(val) __write_ulong_gc0_register($5, 5, val)
-#define read_gc0_pwfield() __read_ulong_gc0_register(5, 6)
-#define write_gc0_pwfield(val) __write_ulong_gc0_register(5, 6, val)
+#define read_gc0_pwfield() __read_ulong_gc0_register($5, 6)
+#define write_gc0_pwfield(val) __write_ulong_gc0_register($5, 6, val)
-#define read_gc0_pwsize() __read_ulong_gc0_register(5, 7)
-#define write_gc0_pwsize(val) __write_ulong_gc0_register(5, 7, val)
+#define read_gc0_pwsize() __read_ulong_gc0_register($5, 7)
+#define write_gc0_pwsize(val) __write_ulong_gc0_register($5, 7, val)
-#define read_gc0_wired() __read_32bit_gc0_register(6, 0)
-#define write_gc0_wired(val) __write_32bit_gc0_register(6, 0, val)
+#define read_gc0_wired() __read_32bit_gc0_register($6, 0)
+#define write_gc0_wired(val) __write_32bit_gc0_register($6, 0, val)
-#define read_gc0_pwctl() __read_32bit_gc0_register(6, 6)
-#define write_gc0_pwctl(val) __write_32bit_gc0_register(6, 6, val)
-
-#define read_gc0_hwrena() __read_32bit_gc0_register(7, 0)
-#define write_gc0_hwrena(val) __write_32bit_gc0_register(7, 0, val)
-
-#define read_gc0_badvaddr() __read_ulong_gc0_register(8, 0)
-#define write_gc0_badvaddr(val) __write_ulong_gc0_register(8, 0, val)
-
-#define read_gc0_badinstr() __read_32bit_gc0_register(8, 1)
-#define write_gc0_badinstr(val) __write_32bit_gc0_register(8, 1, val)
-
-#define read_gc0_badinstrp() __read_32bit_gc0_register(8, 2)
-#define write_gc0_badinstrp(val) __write_32bit_gc0_register(8, 2, val)
-
-#define read_gc0_count() __read_32bit_gc0_register(9, 0)
-
-#define read_gc0_entryhi() __read_ulong_gc0_register(10, 0)
-#define write_gc0_entryhi(val) __write_ulong_gc0_register(10, 0, val)
-
-#define read_gc0_compare() __read_32bit_gc0_register(11, 0)
-#define write_gc0_compare(val) __write_32bit_gc0_register(11, 0, val)
-
-#define read_gc0_status() __read_32bit_gc0_register(12, 0)
-#define write_gc0_status(val) __write_32bit_gc0_register(12, 0, val)
-
-#define read_gc0_intctl() __read_32bit_gc0_register(12, 1)
-#define write_gc0_intctl(val) __write_32bit_gc0_register(12, 1, val)
-
-#define read_gc0_cause() __read_32bit_gc0_register(13, 0)
-#define write_gc0_cause(val) __write_32bit_gc0_register(13, 0, val)
-
-#define read_gc0_epc() __read_ulong_gc0_register(14, 0)
-#define write_gc0_epc(val) __write_ulong_gc0_register(14, 0, val)
-
-#define read_gc0_prid() __read_32bit_gc0_register(15, 0)
-
-#define read_gc0_ebase() __read_32bit_gc0_register(15, 1)
-#define write_gc0_ebase(val) __write_32bit_gc0_register(15, 1, val)
-
-#define read_gc0_ebase_64() __read_64bit_gc0_register(15, 1)
-#define write_gc0_ebase_64(val) __write_64bit_gc0_register(15, 1, val)
-
-#define read_gc0_config() __read_32bit_gc0_register(16, 0)
-#define read_gc0_config1() __read_32bit_gc0_register(16, 1)
-#define read_gc0_config2() __read_32bit_gc0_register(16, 2)
-#define read_gc0_config3() __read_32bit_gc0_register(16, 3)
-#define read_gc0_config4() __read_32bit_gc0_register(16, 4)
-#define read_gc0_config5() __read_32bit_gc0_register(16, 5)
-#define read_gc0_config6() __read_32bit_gc0_register(16, 6)
-#define read_gc0_config7() __read_32bit_gc0_register(16, 7)
-#define write_gc0_config(val) __write_32bit_gc0_register(16, 0, val)
-#define write_gc0_config1(val) __write_32bit_gc0_register(16, 1, val)
-#define write_gc0_config2(val) __write_32bit_gc0_register(16, 2, val)
-#define write_gc0_config3(val) __write_32bit_gc0_register(16, 3, val)
-#define write_gc0_config4(val) __write_32bit_gc0_register(16, 4, val)
-#define write_gc0_config5(val) __write_32bit_gc0_register(16, 5, val)
-#define write_gc0_config6(val) __write_32bit_gc0_register(16, 6, val)
-#define write_gc0_config7(val) __write_32bit_gc0_register(16, 7, val)
-
-#define read_gc0_lladdr() __read_ulong_gc0_register(17, 0)
-#define write_gc0_lladdr(val) __write_ulong_gc0_register(17, 0, val)
-
-#define read_gc0_watchlo0() __read_ulong_gc0_register(18, 0)
-#define read_gc0_watchlo1() __read_ulong_gc0_register(18, 1)
-#define read_gc0_watchlo2() __read_ulong_gc0_register(18, 2)
-#define read_gc0_watchlo3() __read_ulong_gc0_register(18, 3)
-#define read_gc0_watchlo4() __read_ulong_gc0_register(18, 4)
-#define read_gc0_watchlo5() __read_ulong_gc0_register(18, 5)
-#define read_gc0_watchlo6() __read_ulong_gc0_register(18, 6)
-#define read_gc0_watchlo7() __read_ulong_gc0_register(18, 7)
-#define write_gc0_watchlo0(val) __write_ulong_gc0_register(18, 0, val)
-#define write_gc0_watchlo1(val) __write_ulong_gc0_register(18, 1, val)
-#define write_gc0_watchlo2(val) __write_ulong_gc0_register(18, 2, val)
-#define write_gc0_watchlo3(val) __write_ulong_gc0_register(18, 3, val)
-#define write_gc0_watchlo4(val) __write_ulong_gc0_register(18, 4, val)
-#define write_gc0_watchlo5(val) __write_ulong_gc0_register(18, 5, val)
-#define write_gc0_watchlo6(val) __write_ulong_gc0_register(18, 6, val)
-#define write_gc0_watchlo7(val) __write_ulong_gc0_register(18, 7, val)
-
-#define read_gc0_watchhi0() __read_32bit_gc0_register(19, 0)
-#define read_gc0_watchhi1() __read_32bit_gc0_register(19, 1)
-#define read_gc0_watchhi2() __read_32bit_gc0_register(19, 2)
-#define read_gc0_watchhi3() __read_32bit_gc0_register(19, 3)
-#define read_gc0_watchhi4() __read_32bit_gc0_register(19, 4)
-#define read_gc0_watchhi5() __read_32bit_gc0_register(19, 5)
-#define read_gc0_watchhi6() __read_32bit_gc0_register(19, 6)
-#define read_gc0_watchhi7() __read_32bit_gc0_register(19, 7)
-#define write_gc0_watchhi0(val) __write_32bit_gc0_register(19, 0, val)
-#define write_gc0_watchhi1(val) __write_32bit_gc0_register(19, 1, val)
-#define write_gc0_watchhi2(val) __write_32bit_gc0_register(19, 2, val)
-#define write_gc0_watchhi3(val) __write_32bit_gc0_register(19, 3, val)
-#define write_gc0_watchhi4(val) __write_32bit_gc0_register(19, 4, val)
-#define write_gc0_watchhi5(val) __write_32bit_gc0_register(19, 5, val)
-#define write_gc0_watchhi6(val) __write_32bit_gc0_register(19, 6, val)
-#define write_gc0_watchhi7(val) __write_32bit_gc0_register(19, 7, val)
-
-#define read_gc0_xcontext() __read_ulong_gc0_register(20, 0)
-#define write_gc0_xcontext(val) __write_ulong_gc0_register(20, 0, val)
-
-#define read_gc0_perfctrl0() __read_32bit_gc0_register(25, 0)
-#define write_gc0_perfctrl0(val) __write_32bit_gc0_register(25, 0, val)
-#define read_gc0_perfcntr0() __read_32bit_gc0_register(25, 1)
-#define write_gc0_perfcntr0(val) __write_32bit_gc0_register(25, 1, val)
-#define read_gc0_perfcntr0_64() __read_64bit_gc0_register(25, 1)
-#define write_gc0_perfcntr0_64(val) __write_64bit_gc0_register(25, 1, val)
-#define read_gc0_perfctrl1() __read_32bit_gc0_register(25, 2)
-#define write_gc0_perfctrl1(val) __write_32bit_gc0_register(25, 2, val)
-#define read_gc0_perfcntr1() __read_32bit_gc0_register(25, 3)
-#define write_gc0_perfcntr1(val) __write_32bit_gc0_register(25, 3, val)
-#define read_gc0_perfcntr1_64() __read_64bit_gc0_register(25, 3)
-#define write_gc0_perfcntr1_64(val) __write_64bit_gc0_register(25, 3, val)
-#define read_gc0_perfctrl2() __read_32bit_gc0_register(25, 4)
-#define write_gc0_perfctrl2(val) __write_32bit_gc0_register(25, 4, val)
-#define read_gc0_perfcntr2() __read_32bit_gc0_register(25, 5)
-#define write_gc0_perfcntr2(val) __write_32bit_gc0_register(25, 5, val)
-#define read_gc0_perfcntr2_64() __read_64bit_gc0_register(25, 5)
-#define write_gc0_perfcntr2_64(val) __write_64bit_gc0_register(25, 5, val)
-#define read_gc0_perfctrl3() __read_32bit_gc0_register(25, 6)
-#define write_gc0_perfctrl3(val) __write_32bit_gc0_register(25, 6, val)
-#define read_gc0_perfcntr3() __read_32bit_gc0_register(25, 7)
-#define write_gc0_perfcntr3(val) __write_32bit_gc0_register(25, 7, val)
-#define read_gc0_perfcntr3_64() __read_64bit_gc0_register(25, 7)
-#define write_gc0_perfcntr3_64(val) __write_64bit_gc0_register(25, 7, val)
-
-#define read_gc0_errorepc() __read_ulong_gc0_register(30, 0)
-#define write_gc0_errorepc(val) __write_ulong_gc0_register(30, 0, val)
-
-#define read_gc0_kscratch1() __read_ulong_gc0_register(31, 2)
-#define read_gc0_kscratch2() __read_ulong_gc0_register(31, 3)
-#define read_gc0_kscratch3() __read_ulong_gc0_register(31, 4)
-#define read_gc0_kscratch4() __read_ulong_gc0_register(31, 5)
-#define read_gc0_kscratch5() __read_ulong_gc0_register(31, 6)
-#define read_gc0_kscratch6() __read_ulong_gc0_register(31, 7)
-#define write_gc0_kscratch1(val) __write_ulong_gc0_register(31, 2, val)
-#define write_gc0_kscratch2(val) __write_ulong_gc0_register(31, 3, val)
-#define write_gc0_kscratch3(val) __write_ulong_gc0_register(31, 4, val)
-#define write_gc0_kscratch4(val) __write_ulong_gc0_register(31, 5, val)
-#define write_gc0_kscratch5(val) __write_ulong_gc0_register(31, 6, val)
-#define write_gc0_kscratch6(val) __write_ulong_gc0_register(31, 7, val)
+#define read_gc0_pwctl() __read_32bit_gc0_register($6, 6)
+#define write_gc0_pwctl(val) __write_32bit_gc0_register($6, 6, val)
+
+#define read_gc0_hwrena() __read_32bit_gc0_register($7, 0)
+#define write_gc0_hwrena(val) __write_32bit_gc0_register($7, 0, val)
+
+#define read_gc0_badvaddr() __read_ulong_gc0_register($8, 0)
+#define write_gc0_badvaddr(val) __write_ulong_gc0_register($8, 0, val)
+
+#define read_gc0_badinstr() __read_32bit_gc0_register($8, 1)
+#define write_gc0_badinstr(val) __write_32bit_gc0_register($8, 1, val)
+
+#define read_gc0_badinstrp() __read_32bit_gc0_register($8, 2)
+#define write_gc0_badinstrp(val) __write_32bit_gc0_register($8, 2, val)
+
+#define read_gc0_count() __read_32bit_gc0_register($9, 0)
+
+#define read_gc0_entryhi() __read_ulong_gc0_register($10, 0)
+#define write_gc0_entryhi(val) __write_ulong_gc0_register($10, 0, val)
+
+#define read_gc0_compare() __read_32bit_gc0_register($11, 0)
+#define write_gc0_compare(val) __write_32bit_gc0_register($11, 0, val)
+
+#define read_gc0_status() __read_32bit_gc0_register($12, 0)
+#define write_gc0_status(val) __write_32bit_gc0_register($12, 0, val)
+
+#define read_gc0_intctl() __read_32bit_gc0_register($12, 1)
+#define write_gc0_intctl(val) __write_32bit_gc0_register($12, 1, val)
+
+#define read_gc0_cause() __read_32bit_gc0_register($13, 0)
+#define write_gc0_cause(val) __write_32bit_gc0_register($13, 0, val)
+
+#define read_gc0_epc() __read_ulong_gc0_register($14, 0)
+#define write_gc0_epc(val) __write_ulong_gc0_register($14, 0, val)
+
+#define read_gc0_prid() __read_32bit_gc0_register($15, 0)
+
+#define read_gc0_ebase() __read_32bit_gc0_register($15, 1)
+#define write_gc0_ebase(val) __write_32bit_gc0_register($15, 1, val)
+
+#define read_gc0_ebase_64() __read_64bit_gc0_register($15, 1)
+#define write_gc0_ebase_64(val) __write_64bit_gc0_register($15, 1, val)
+
+#define read_gc0_config() __read_32bit_gc0_register($16, 0)
+#define read_gc0_config1() __read_32bit_gc0_register($16, 1)
+#define read_gc0_config2() __read_32bit_gc0_register($16, 2)
+#define read_gc0_config3() __read_32bit_gc0_register($16, 3)
+#define read_gc0_config4() __read_32bit_gc0_register($16, 4)
+#define read_gc0_config5() __read_32bit_gc0_register($16, 5)
+#define read_gc0_config6() __read_32bit_gc0_register($16, 6)
+#define read_gc0_config7() __read_32bit_gc0_register($16, 7)
+#define write_gc0_config(val) __write_32bit_gc0_register($16, 0, val)
+#define write_gc0_config1(val) __write_32bit_gc0_register($16, 1, val)
+#define write_gc0_config2(val) __write_32bit_gc0_register($16, 2, val)
+#define write_gc0_config3(val) __write_32bit_gc0_register($16, 3, val)
+#define write_gc0_config4(val) __write_32bit_gc0_register($16, 4, val)
+#define write_gc0_config5(val) __write_32bit_gc0_register($16, 5, val)
+#define write_gc0_config6(val) __write_32bit_gc0_register($16, 6, val)
+#define write_gc0_config7(val) __write_32bit_gc0_register($16, 7, val)
+
+#define read_gc0_lladdr() __read_ulong_gc0_register($17, 0)
+#define write_gc0_lladdr(val) __write_ulong_gc0_register($17, 0, val)
+
+#define read_gc0_watchlo0() __read_ulong_gc0_register($18, 0)
+#define read_gc0_watchlo1() __read_ulong_gc0_register($18, 1)
+#define read_gc0_watchlo2() __read_ulong_gc0_register($18, 2)
+#define read_gc0_watchlo3() __read_ulong_gc0_register($18, 3)
+#define read_gc0_watchlo4() __read_ulong_gc0_register($18, 4)
+#define read_gc0_watchlo5() __read_ulong_gc0_register($18, 5)
+#define read_gc0_watchlo6() __read_ulong_gc0_register($18, 6)
+#define read_gc0_watchlo7() __read_ulong_gc0_register($18, 7)
+#define write_gc0_watchlo0(val) __write_ulong_gc0_register($18, 0, val)
+#define write_gc0_watchlo1(val) __write_ulong_gc0_register($18, 1, val)
+#define write_gc0_watchlo2(val) __write_ulong_gc0_register($18, 2, val)
+#define write_gc0_watchlo3(val) __write_ulong_gc0_register($18, 3, val)
+#define write_gc0_watchlo4(val) __write_ulong_gc0_register($18, 4, val)
+#define write_gc0_watchlo5(val) __write_ulong_gc0_register($18, 5, val)
+#define write_gc0_watchlo6(val) __write_ulong_gc0_register($18, 6, val)
+#define write_gc0_watchlo7(val) __write_ulong_gc0_register($18, 7, val)
+
+#define read_gc0_watchhi0() __read_32bit_gc0_register($19, 0)
+#define read_gc0_watchhi1() __read_32bit_gc0_register($19, 1)
+#define read_gc0_watchhi2() __read_32bit_gc0_register($19, 2)
+#define read_gc0_watchhi3() __read_32bit_gc0_register($19, 3)
+#define read_gc0_watchhi4() __read_32bit_gc0_register($19, 4)
+#define read_gc0_watchhi5() __read_32bit_gc0_register($19, 5)
+#define read_gc0_watchhi6() __read_32bit_gc0_register($19, 6)
+#define read_gc0_watchhi7() __read_32bit_gc0_register($19, 7)
+#define write_gc0_watchhi0(val) __write_32bit_gc0_register($19, 0, val)
+#define write_gc0_watchhi1(val) __write_32bit_gc0_register($19, 1, val)
+#define write_gc0_watchhi2(val) __write_32bit_gc0_register($19, 2, val)
+#define write_gc0_watchhi3(val) __write_32bit_gc0_register($19, 3, val)
+#define write_gc0_watchhi4(val) __write_32bit_gc0_register($19, 4, val)
+#define write_gc0_watchhi5(val) __write_32bit_gc0_register($19, 5, val)
+#define write_gc0_watchhi6(val) __write_32bit_gc0_register($19, 6, val)
+#define write_gc0_watchhi7(val) __write_32bit_gc0_register($19, 7, val)
+
+#define read_gc0_xcontext() __read_ulong_gc0_register($20, 0)
+#define write_gc0_xcontext(val) __write_ulong_gc0_register($20, 0, val)
+
+#define read_gc0_perfctrl0() __read_32bit_gc0_register($25, 0)
+#define write_gc0_perfctrl0(val) __write_32bit_gc0_register($25, 0, val)
+#define read_gc0_perfcntr0() __read_32bit_gc0_register($25, 1)
+#define write_gc0_perfcntr0(val) __write_32bit_gc0_register($25, 1, val)
+#define read_gc0_perfcntr0_64() __read_64bit_gc0_register($25, 1)
+#define write_gc0_perfcntr0_64(val) __write_64bit_gc0_register($25, 1, val)
+#define read_gc0_perfctrl1() __read_32bit_gc0_register($25, 2)
+#define write_gc0_perfctrl1(val) __write_32bit_gc0_register($25, 2, val)
+#define read_gc0_perfcntr1() __read_32bit_gc0_register($25, 3)
+#define write_gc0_perfcntr1(val) __write_32bit_gc0_register($25, 3, val)
+#define read_gc0_perfcntr1_64() __read_64bit_gc0_register($25, 3)
+#define write_gc0_perfcntr1_64(val) __write_64bit_gc0_register($25, 3, val)
+#define read_gc0_perfctrl2() __read_32bit_gc0_register($25, 4)
+#define write_gc0_perfctrl2(val) __write_32bit_gc0_register($25, 4, val)
+#define read_gc0_perfcntr2() __read_32bit_gc0_register($25, 5)
+#define write_gc0_perfcntr2(val) __write_32bit_gc0_register($25, 5, val)
+#define read_gc0_perfcntr2_64() __read_64bit_gc0_register($25, 5)
+#define write_gc0_perfcntr2_64(val) __write_64bit_gc0_register($25, 5, val)
+#define read_gc0_perfctrl3() __read_32bit_gc0_register($25, 6)
+#define write_gc0_perfctrl3(val) __write_32bit_gc0_register($25, 6, val)
+#define read_gc0_perfcntr3() __read_32bit_gc0_register($25, 7)
+#define write_gc0_perfcntr3(val) __write_32bit_gc0_register($25, 7, val)
+#define read_gc0_perfcntr3_64() __read_64bit_gc0_register($25, 7)
+#define write_gc0_perfcntr3_64(val) __write_64bit_gc0_register($25, 7, val)
+
+#define read_gc0_errorepc() __read_ulong_gc0_register($30, 0)
+#define write_gc0_errorepc(val) __write_ulong_gc0_register($30, 0, val)
+
+#define read_gc0_kscratch1() __read_ulong_gc0_register($31, 2)
+#define read_gc0_kscratch2() __read_ulong_gc0_register($31, 3)
+#define read_gc0_kscratch3() __read_ulong_gc0_register($31, 4)
+#define read_gc0_kscratch4() __read_ulong_gc0_register($31, 5)
+#define read_gc0_kscratch5() __read_ulong_gc0_register($31, 6)
+#define read_gc0_kscratch6() __read_ulong_gc0_register($31, 7)
+#define write_gc0_kscratch1(val) __write_ulong_gc0_register($31, 2, val)
+#define write_gc0_kscratch2(val) __write_ulong_gc0_register($31, 3, val)
+#define write_gc0_kscratch3(val) __write_ulong_gc0_register($31, 4, val)
+#define write_gc0_kscratch4(val) __write_ulong_gc0_register($31, 5, val)
+#define write_gc0_kscratch5(val) __write_ulong_gc0_register($31, 6, val)
+#define write_gc0_kscratch6(val) __write_ulong_gc0_register($31, 7, val)
/* Cavium OCTEON (cnMIPS) */
-#define read_gc0_cvmcount() __read_ulong_gc0_register(9, 6)
-#define write_gc0_cvmcount(val) __write_ulong_gc0_register(9, 6, val)
+#define read_gc0_cvmcount() __read_ulong_gc0_register($9, 6)
+#define write_gc0_cvmcount(val) __write_ulong_gc0_register($9, 6, val)
-#define read_gc0_cvmctl() __read_64bit_gc0_register(9, 7)
-#define write_gc0_cvmctl(val) __write_64bit_gc0_register(9, 7, val)
+#define read_gc0_cvmctl() __read_64bit_gc0_register($9, 7)
+#define write_gc0_cvmctl(val) __write_64bit_gc0_register($9, 7, val)
-#define read_gc0_cvmmemctl() __read_64bit_gc0_register(11, 7)
-#define write_gc0_cvmmemctl(val) __write_64bit_gc0_register(11, 7, val)
+#define read_gc0_cvmmemctl() __read_64bit_gc0_register($11, 7)
+#define write_gc0_cvmmemctl(val) __write_64bit_gc0_register($11, 7, val)
-#define read_gc0_cvmmemctl2() __read_64bit_gc0_register(16, 6)
-#define write_gc0_cvmmemctl2(val) __write_64bit_gc0_register(16, 6, val)
+#define read_gc0_cvmmemctl2() __read_64bit_gc0_register($16, 6)
+#define write_gc0_cvmmemctl2(val) __write_64bit_gc0_register($16, 6, val)
/*
* Macros to access the floating point coprocessor control registers
@@ -2581,8 +2651,6 @@ static inline void tlb_write_random(void)
".set reorder");
}
-#ifdef TOOLCHAIN_SUPPORTS_VIRT
-
/*
* Guest TLB operations.
*
@@ -2593,7 +2661,7 @@ static inline void guest_tlb_probe(void)
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
- ".set virt\n\t"
+ _ASM_SET_VIRT
"tlbgp\n\t"
".set pop");
}
@@ -2603,7 +2671,7 @@ static inline void guest_tlb_read(void)
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
- ".set virt\n\t"
+ _ASM_SET_VIRT
"tlbgr\n\t"
".set pop");
}
@@ -2613,7 +2681,7 @@ static inline void guest_tlb_write_indexed(void)
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
- ".set virt\n\t"
+ _ASM_SET_VIRT
"tlbgwi\n\t"
".set pop");
}
@@ -2623,7 +2691,7 @@ static inline void guest_tlb_write_random(void)
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
- ".set virt\n\t"
+ _ASM_SET_VIRT
"tlbgwr\n\t"
".set pop");
}
@@ -2636,63 +2704,11 @@ static inline void guest_tlbinvf(void)
__asm__ __volatile__(
".set push\n\t"
".set noreorder\n\t"
- ".set virt\n\t"
+ _ASM_SET_VIRT
"tlbginvf\n\t"
".set pop");
}
-#else /* TOOLCHAIN_SUPPORTS_VIRT */
-
-/*
- * Guest TLB operations.
- *
- * It is responsibility of the caller to take care of any TLB hazards.
- */
-static inline void guest_tlb_probe(void)
-{
- __asm__ __volatile__(
- "# tlbgp\n\t"
- _ASM_INSN_IF_MIPS(0x42000010)
- _ASM_INSN32_IF_MM(0x0000017c));
-}
-
-static inline void guest_tlb_read(void)
-{
- __asm__ __volatile__(
- "# tlbgr\n\t"
- _ASM_INSN_IF_MIPS(0x42000009)
- _ASM_INSN32_IF_MM(0x0000117c));
-}
-
-static inline void guest_tlb_write_indexed(void)
-{
- __asm__ __volatile__(
- "# tlbgwi\n\t"
- _ASM_INSN_IF_MIPS(0x4200000a)
- _ASM_INSN32_IF_MM(0x0000217c));
-}
-
-static inline void guest_tlb_write_random(void)
-{
- __asm__ __volatile__(
- "# tlbgwr\n\t"
- _ASM_INSN_IF_MIPS(0x4200000e)
- _ASM_INSN32_IF_MM(0x0000317c));
-}
-
-/*
- * Guest TLB Invalidate Flush
- */
-static inline void guest_tlbinvf(void)
-{
- __asm__ __volatile__(
- "# tlbginvf\n\t"
- _ASM_INSN_IF_MIPS(0x4200000c)
- _ASM_INSN32_IF_MM(0x0000517c));
-}
-
-#endif /* !TOOLCHAIN_SUPPORTS_VIRT */
-
/*
* Manipulate bits in a register.
*/
diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h
index b1845102f8f9..b4f9577ed96a 100644
--- a/arch/mips/include/asm/msa.h
+++ b/arch/mips/include/asm/msa.h
@@ -160,7 +160,23 @@ static inline void init_msa_upper(void)
_init_msa_upper();
}
-#ifdef TOOLCHAIN_SUPPORTS_MSA
+#ifndef TOOLCHAIN_SUPPORTS_MSA
+/*
+ * Define assembler macros using .word for the c[ft]cmsa instructions in order
+ * to allow compilation with toolchains that do not support MSA. Once all
+ * toolchains in use support MSA these can be removed.
+ */
+_ASM_MACRO_2R(cfcmsa, rd, cs,
+ _ASM_INSN_IF_MIPS(0x787e0019 | __cs << 11 | __rd << 6)
+ _ASM_INSN32_IF_MM(0x587e0016 | __cs << 11 | __rd << 6));
+_ASM_MACRO_2R(ctcmsa, cd, rs,
+ _ASM_INSN_IF_MIPS(0x783e0019 | __rs << 11 | __cd << 6)
+ _ASM_INSN32_IF_MM(0x583e0016 | __rs << 11 | __cd << 6));
+#define _ASM_SET_MSA ""
+#else /* TOOLCHAIN_SUPPORTS_MSA */
+#define _ASM_SET_MSA ".set\tfp=64\n\t" \
+ ".set\tmsa\n\t"
+#endif
#define __BUILD_MSA_CTL_REG(name, cs) \
static inline unsigned int read_msa_##name(void) \
@@ -168,8 +184,7 @@ static inline unsigned int read_msa_##name(void) \
unsigned int reg; \
__asm__ __volatile__( \
" .set push\n" \
- " .set fp=64\n" \
- " .set msa\n" \
+ _ASM_SET_MSA \
" cfcmsa %0, $" #cs "\n" \
" .set pop\n" \
: "=r"(reg)); \
@@ -180,52 +195,12 @@ static inline void write_msa_##name(unsigned int val) \
{ \
__asm__ __volatile__( \
" .set push\n" \
- " .set fp=64\n" \
- " .set msa\n" \
+ _ASM_SET_MSA \
" ctcmsa $" #cs ", %0\n" \
" .set pop\n" \
: : "r"(val)); \
}
-#else /* !TOOLCHAIN_SUPPORTS_MSA */
-
-/*
- * Define functions using .word for the c[ft]cmsa instructions in order to
- * allow compilation with toolchains that do not support MSA. Once all
- * toolchains in use support MSA these can be removed.
- */
-
-#define __BUILD_MSA_CTL_REG(name, cs) \
-static inline unsigned int read_msa_##name(void) \
-{ \
- unsigned int reg; \
- __asm__ __volatile__( \
- " .set push\n" \
- " .set noat\n" \
- " # cfcmsa $1, $%1\n" \
- _ASM_INSN_IF_MIPS(0x787e0059 | %1 << 11) \
- _ASM_INSN32_IF_MM(0x587e0056 | %1 << 11) \
- " move %0, $1\n" \
- " .set pop\n" \
- : "=r"(reg) : "i"(cs)); \
- return reg; \
-} \
- \
-static inline void write_msa_##name(unsigned int val) \
-{ \
- __asm__ __volatile__( \
- " .set push\n" \
- " .set noat\n" \
- " move $1, %0\n" \
- " # ctcmsa $%1, $1\n" \
- _ASM_INSN_IF_MIPS(0x783e0819 | %1 << 6) \
- _ASM_INSN32_IF_MM(0x583e0816 | %1 << 6) \
- " .set pop\n" \
- : : "r"(val), "i"(cs)); \
-}
-
-#endif /* !TOOLCHAIN_SUPPORTS_MSA */
-
__BUILD_MSA_CTL_REG(ir, 0)
__BUILD_MSA_CTL_REG(csr, 1)
__BUILD_MSA_CTL_REG(access, 2)
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index e4374a5651ce..448fd41792e4 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -32,22 +32,22 @@ static struct resource jazz_io_resources[] = {
.start = 0x00,
.end = 0x1f,
.name = "dma1",
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
}, {
.start = 0x40,
.end = 0x5f,
.name = "timer",
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
}, {
.start = 0x80,
.end = 0x8f,
.name = "dma page reg",
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
}, {
.start = 0xc0,
.end = 0xdf,
.name = "dma2",
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
}
};
diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
index 643af2012e14..4dd0c446ecec 100644
--- a/arch/mips/jz4740/Kconfig
+++ b/arch/mips/jz4740/Kconfig
@@ -8,6 +8,10 @@ config JZ4740_QI_LB60
bool "Qi Hardware Ben NanoNote"
select MACH_JZ4740
+config JZ4770_GCW0
+ bool "Game Consoles Worldwide GCW Zero"
+ select MACH_JZ4770
+
config JZ4780_CI20
bool "MIPS Creator CI20"
select MACH_JZ4780
@@ -18,6 +22,12 @@ config MACH_JZ4740
bool
select SYS_HAS_CPU_MIPS32_R1
+config MACH_JZ4770
+ bool
+ select MIPS_CPU_SCACHE
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_SUPPORTS_HIGHMEM
+
config MACH_JZ4780
bool
select MIPS_CPU_SCACHE
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c
index 47e857194ce6..eb9f2f97bedb 100644
--- a/arch/mips/jz4740/prom.c
+++ b/arch/mips/jz4740/prom.c
@@ -20,33 +20,12 @@
#include <linux/serial_reg.h>
#include <asm/bootinfo.h>
+#include <asm/fw/fw.h>
#include <asm/mach-jz4740/base.h>
-static __init void jz4740_init_cmdline(int argc, char *argv[])
-{
- unsigned int count = COMMAND_LINE_SIZE - 1;
- int i;
- char *dst = &(arcs_cmdline[0]);
- char *src;
-
- for (i = 1; i < argc && count; ++i) {
- src = argv[i];
- while (*src && count) {
- *dst++ = *src++;
- --count;
- }
- *dst++ = ' ';
- }
- if (i > 1)
- --dst;
-
- *dst = 0;
-}
-
void __init prom_init(void)
{
- jz4740_init_cmdline((int)fw_arg0, (char **)fw_arg1);
- mips_machtype = MACH_INGENIC_JZ4740;
+ fw_init_cmdline();
}
void __init prom_free_prom_memory(void)
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c
index 6d0152321819..afb40f8bce96 100644
--- a/arch/mips/jz4740/setup.c
+++ b/arch/mips/jz4740/setup.c
@@ -53,6 +53,16 @@ static void __init jz4740_detect_mem(void)
add_memory_region(0, size, BOOT_MEM_RAM);
}
+static unsigned long __init get_board_mach_type(const void *fdt)
+{
+ if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4780"))
+ return MACH_INGENIC_JZ4780;
+ if (!fdt_node_check_compatible(fdt, 0, "ingenic,jz4770"))
+ return MACH_INGENIC_JZ4770;
+
+ return MACH_INGENIC_JZ4740;
+}
+
void __init plat_mem_setup(void)
{
int offset;
@@ -63,6 +73,8 @@ void __init plat_mem_setup(void)
offset = fdt_path_offset(__dtb_start, "/memory");
if (offset < 0)
jz4740_detect_mem();
+
+ mips_machtype = get_board_mach_type(__dtb_start);
}
void __init device_tree_init(void)
@@ -75,10 +87,14 @@ void __init device_tree_init(void)
const char *get_system_type(void)
{
- if (IS_ENABLED(CONFIG_MACH_JZ4780))
+ switch (mips_machtype) {
+ case MACH_INGENIC_JZ4780:
return "JZ4780";
-
- return "JZ4740";
+ case MACH_INGENIC_JZ4770:
+ return "JZ4770";
+ default:
+ return "JZ4740";
+ }
}
void __init arch_init_irq(void)
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index bb1ad5119da4..2ca9160f642a 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -113,7 +113,7 @@ static struct clock_event_device jz4740_clockevent = {
#ifdef CONFIG_MACH_JZ4740
.irq = JZ4740_IRQ_TCU0,
#endif
-#ifdef CONFIG_MACH_JZ4780
+#if defined(CONFIG_MACH_JZ4770) || defined(CONFIG_MACH_JZ4780)
.irq = JZ4780_IRQ_TCU2,
#endif
};
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index b79ed9af9886..e48f6c0a9e4a 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -399,7 +399,7 @@ int __MIPS16e_compute_return_epc(struct pt_regs *regs)
*
* @regs: Pointer to pt_regs
* @insn: branch instruction to decode
- * @returns: -EFAULT on error and forces SIGILL, and on success
+ * Return: -EFAULT on error and forces SIGILL, and on success
* returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
* evaluating the branch.
*
diff --git a/arch/mips/kernel/cps-vec.S b/arch/mips/kernel/cps-vec.S
index e68e6e04063a..1025f937ab0e 100644
--- a/arch/mips/kernel/cps-vec.S
+++ b/arch/mips/kernel/cps-vec.S
@@ -388,15 +388,16 @@ LEAF(mips_cps_boot_vpes)
#elif defined(CONFIG_MIPS_MT)
- .set push
- .set MIPS_ISA_LEVEL_RAW
- .set mt
-
/* If the core doesn't support MT then return */
has_mt t0, 5f
/* Enter VPE configuration state */
+ .set push
+ .set MIPS_ISA_LEVEL_RAW
+ .set mt
dvpe
+ .set pop
+
PTR_LA t1, 1f
jr.hb t1
nop
@@ -422,6 +423,10 @@ LEAF(mips_cps_boot_vpes)
mtc0 t0, CP0_VPECONTROL
ehb
+ .set push
+ .set MIPS_ISA_LEVEL_RAW
+ .set mt
+
/* Skip the VPE if its TC is not halted */
mftc0 t0, CP0_TCHALT
beqz t0, 2f
@@ -495,6 +500,8 @@ LEAF(mips_cps_boot_vpes)
ehb
evpe
+ .set pop
+
/* Check whether this VPE is meant to be running */
li t0, 1
sll t0, t0, a1
@@ -509,7 +516,7 @@ LEAF(mips_cps_boot_vpes)
1: jr.hb t0
nop
-2: .set pop
+2:
#endif /* CONFIG_MIPS_MT_SMP */
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index 99285be0e088..7f3dfdbc3657 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -361,7 +361,7 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
* If fails when getting the stack address of the non-leaf function's
* ra, stop function graph tracer and return
*/
- if (parent_ra_addr == 0)
+ if (parent_ra_addr == NULL)
goto out;
#endif
/* *parent_ra_addr = return_hooker; */
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 702c678de116..85bc601e9a0d 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -826,25 +826,6 @@ static void __init arch_mem_init(char **cmdline_p)
struct memblock_region *reg;
extern void plat_mem_setup(void);
- /* call board setup routine */
- plat_mem_setup();
-
- /*
- * Make sure all kernel memory is in the maps. The "UP" and
- * "DOWN" are opposite for initdata since if it crosses over
- * into another memory section you don't want that to be
- * freed when the initdata is freed.
- */
- arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
- PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
- BOOT_MEM_RAM);
- arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
- PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
- BOOT_MEM_INIT_RAM);
-
- pr_info("Determined physical RAM map:\n");
- print_memory_map();
-
#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
#else
@@ -872,6 +853,26 @@ static void __init arch_mem_init(char **cmdline_p)
}
#endif
#endif
+
+ /* call board setup routine */
+ plat_mem_setup();
+
+ /*
+ * Make sure all kernel memory is in the maps. The "UP" and
+ * "DOWN" are opposite for initdata since if it crosses over
+ * into another memory section you don't want that to be
+ * freed when the initdata is freed.
+ */
+ arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
+ PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
+ BOOT_MEM_RAM);
+ arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
+ PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
+ BOOT_MEM_INIT_RAM);
+
+ pr_info("Determined physical RAM map:\n");
+ print_memory_map();
+
strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
*cmdline_p = command_line;
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c
index ecc1a853f48d..03f1026ad148 100644
--- a/arch/mips/kernel/smp-cps.c
+++ b/arch/mips/kernel/smp-cps.c
@@ -439,8 +439,6 @@ void play_dead(void)
pr_debug("CPU%d going offline\n", cpu);
if (cpu_has_mipsmt || cpu_has_vp) {
- core = cpu_core(&cpu_data[cpu]);
-
/* Look for another online VPE within the core */
for_each_online_cpu(cpu_death_sibling) {
if (!cpus_are_siblings(cpu, cpu_death_sibling))
diff --git a/arch/mips/kernel/watch.c b/arch/mips/kernel/watch.c
index 19fcab7348b1..0e61a5b7647f 100644
--- a/arch/mips/kernel/watch.c
+++ b/arch/mips/kernel/watch.c
@@ -18,27 +18,24 @@
void mips_install_watch_registers(struct task_struct *t)
{
struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264;
+ unsigned int watchhi = MIPS_WATCHHI_G | /* Trap all ASIDs */
+ MIPS_WATCHHI_IRW; /* Clear result bits */
+
switch (current_cpu_data.watch_reg_use_cnt) {
default:
BUG();
case 4:
write_c0_watchlo3(watches->watchlo[3]);
- /* Write 1 to the I, R, and W bits to clear them, and
- 1 to G so all ASIDs are trapped. */
- write_c0_watchhi3(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
- watches->watchhi[3]);
+ write_c0_watchhi3(watchhi | watches->watchhi[3]);
case 3:
write_c0_watchlo2(watches->watchlo[2]);
- write_c0_watchhi2(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
- watches->watchhi[2]);
+ write_c0_watchhi2(watchhi | watches->watchhi[2]);
case 2:
write_c0_watchlo1(watches->watchlo[1]);
- write_c0_watchhi1(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
- watches->watchhi[1]);
+ write_c0_watchhi1(watchhi | watches->watchhi[1]);
case 1:
write_c0_watchlo0(watches->watchlo[0]);
- write_c0_watchhi0(MIPS_WATCHHI_G | MIPS_WATCHHI_IRW |
- watches->watchhi[0]);
+ write_c0_watchhi0(watchhi | watches->watchhi[0]);
}
}
@@ -51,21 +48,19 @@ void mips_read_watch_registers(void)
{
struct mips3264_watch_reg_state *watches =
&current->thread.watch.mips3264;
+ unsigned int watchhi_mask = MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW;
+
switch (current_cpu_data.watch_reg_use_cnt) {
default:
BUG();
case 4:
- watches->watchhi[3] = (read_c0_watchhi3() &
- (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
+ watches->watchhi[3] = (read_c0_watchhi3() & watchhi_mask);
case 3:
- watches->watchhi[2] = (read_c0_watchhi2() &
- (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
+ watches->watchhi[2] = (read_c0_watchhi2() & watchhi_mask);
case 2:
- watches->watchhi[1] = (read_c0_watchhi1() &
- (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
+ watches->watchhi[1] = (read_c0_watchhi1() & watchhi_mask);
case 1:
- watches->watchhi[0] = (read_c0_watchhi0() &
- (MIPS_WATCHHI_MASK | MIPS_WATCHHI_IRW));
+ watches->watchhi[0] = (read_c0_watchhi0() & watchhi_mask);
}
if (current_cpu_data.watch_reg_use_cnt == 1 &&
(watches->watchhi[0] & MIPS_WATCHHI_IRW) == 0) {
diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig
index 6f109bb54cdb..bc2fdbfa8223 100644
--- a/arch/mips/loongson64/Kconfig
+++ b/arch/mips/loongson64/Kconfig
@@ -17,7 +17,6 @@ config LEMOTE_FULOONG2E
select I8259
select ISA
select IRQ_MIPS_CPU
- select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_HIGHMEM
@@ -49,7 +48,6 @@ config LEMOTE_MACH2F
select ISA
select SYS_HAS_CPU_LOONGSON2F
select SYS_HAS_EARLY_PRINTK
- select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_LITTLE_ENDIAN
diff --git a/arch/mips/loongson64/common/mem.c b/arch/mips/loongson64/common/mem.c
index b01d52473da8..c549e525fc11 100644
--- a/arch/mips/loongson64/common/mem.c
+++ b/arch/mips/loongson64/common/mem.c
@@ -79,7 +79,7 @@ void __init prom_init_memory(void)
(u64)loongson_memmap->map[i].mem_size << 20,
BOOT_MEM_RAM);
break;
- case MEM_RESERVED:
+ case SYSTEM_RAM_RESERVED:
add_memory_region(loongson_memmap->map[i].mem_start,
(u64)loongson_memmap->map[i].mem_size << 20,
BOOT_MEM_RESERVED);
diff --git a/arch/mips/loongson64/loongson-3/numa.c b/arch/mips/loongson64/loongson-3/numa.c
index f17ef520799a..9717106de4a5 100644
--- a/arch/mips/loongson64/loongson-3/numa.c
+++ b/arch/mips/loongson64/loongson-3/numa.c
@@ -166,7 +166,7 @@ static void __init szmem(unsigned int node)
memblock_add_node(PFN_PHYS(start_pfn),
PFN_PHYS(end_pfn - start_pfn), node);
break;
- case MEM_RESERVED:
+ case SYSTEM_RAM_RESERVED:
pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n",
(u32)node_id, mem_type, mem_start, mem_size);
add_memory_region((node_id << 44) + mem_start,
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index da6c1c0c30c1..62deb025970b 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -451,7 +451,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
regs->cp0_epc + dec_insn.pc_inc +
dec_insn.next_pc_inc;
}
- /* Fall through */
+ /* fall through */
case jr_op:
/* For R6, JR already emulated in jalr_op */
if (NO_R6EMU && insn.r_format.func == jr_op)
@@ -471,10 +471,11 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
regs->regs[31] = regs->cp0_epc +
dec_insn.pc_inc +
dec_insn.next_pc_inc;
- /* Fall through */
+ /* fall through */
case bltzl_op:
if (NO_R6EMU)
break;
+ /* fall through */
case bltz_op:
if ((long)regs->regs[insn.i_format.rs] < 0)
*contpc = regs->cp0_epc +
@@ -494,10 +495,11 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
regs->regs[31] = regs->cp0_epc +
dec_insn.pc_inc +
dec_insn.next_pc_inc;
- /* Fall through */
+ /* fall through */
case bgezl_op:
if (NO_R6EMU)
break;
+ /* fall through */
case bgez_op:
if ((long)regs->regs[insn.i_format.rs] >= 0)
*contpc = regs->cp0_epc +
@@ -512,11 +514,12 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
break;
case jalx_op:
set_isa16_mode(bit);
+ /* fall through */
case jal_op:
regs->regs[31] = regs->cp0_epc +
dec_insn.pc_inc +
dec_insn.next_pc_inc;
- /* Fall through */
+ /* fall through */
case j_op:
*contpc = regs->cp0_epc + dec_insn.pc_inc;
*contpc >>= 28;
@@ -528,6 +531,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
case beql_op:
if (NO_R6EMU)
break;
+ /* fall through */
case beq_op:
if (regs->regs[insn.i_format.rs] ==
regs->regs[insn.i_format.rt])
@@ -542,6 +546,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
case bnel_op:
if (NO_R6EMU)
break;
+ /* fall through */
case bne_op:
if (regs->regs[insn.i_format.rs] !=
regs->regs[insn.i_format.rt])
@@ -556,6 +561,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
case blezl_op:
if (!insn.i_format.rt && NO_R6EMU)
break;
+ /* fall through */
case blez_op:
/*
@@ -593,6 +599,7 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
case bgtzl_op:
if (!insn.i_format.rt && NO_R6EMU)
break;
+ /* fall through */
case bgtz_op:
/*
* Compact branches for R6 for the
@@ -729,7 +736,8 @@ int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
return 1;
}
- /* R2/R6 compatible cop1 instruction. Fall through */
+ /* R2/R6 compatible cop1 instruction */
+ /* fall through */
case cop2_op:
case cop1x_op:
if (insn.i_format.rs == bc_op) {
@@ -1190,7 +1198,8 @@ emul:
if (!cpu_has_mips_r6 || delay_slot(xcp))
return SIGILL;
- cond = likely = 0;
+ likely = 0;
+ cond = 0;
fpr = &current->thread.fpu.fpr[MIPSInst_RT(ir)];
bit0 = get_fpr32(fpr, 0) & 0x1;
switch (MIPSInst_RS(ir)) {
@@ -1220,14 +1229,14 @@ emul:
case bcfl_op:
if (cpu_has_mips_2_3_4_5_r)
likely = 1;
- /* Fall through */
+ /* fall through */
case bcf_op:
cond = !cond;
break;
case bctl_op:
if (cpu_has_mips_2_3_4_5_r)
likely = 1;
- /* Fall through */
+ /* fall through */
case bct_op:
break;
}
@@ -1353,7 +1362,8 @@ branch_common:
return SIGILL;
/* a real fpu computation instruction */
- if ((sig = fpu_emu(xcp, ctx, ir)))
+ sig = fpu_emu(xcp, ctx, ir);
+ if (sig)
return sig;
}
break;
diff --git a/arch/mips/math-emu/dp_add.c b/arch/mips/math-emu/dp_add.c
index 8954ef031f84..678de20e4cb1 100644
--- a/arch/mips/math-emu/dp_add.c
+++ b/arch/mips/math-emu/dp_add.c
@@ -104,8 +104,7 @@ union ieee754dp ieee754dp_add(union ieee754dp x, union ieee754dp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
-
- /* FALL THROUGH */
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
DPDNORMY;
diff --git a/arch/mips/math-emu/dp_div.c b/arch/mips/math-emu/dp_div.c
index f4746f7c5f63..3063ae3ab3b9 100644
--- a/arch/mips/math-emu/dp_div.c
+++ b/arch/mips/math-emu/dp_div.c
@@ -103,6 +103,7 @@ union ieee754dp ieee754dp_div(union ieee754dp x, union ieee754dp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
DPDNORMY;
diff --git a/arch/mips/math-emu/dp_fmax.c b/arch/mips/math-emu/dp_fmax.c
index 5bec64f2884e..d1f984b40344 100644
--- a/arch/mips/math-emu/dp_fmax.c
+++ b/arch/mips/math-emu/dp_fmax.c
@@ -96,6 +96,7 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
DPDNORMY;
@@ -224,6 +225,7 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
DPDNORMY;
diff --git a/arch/mips/math-emu/dp_fmin.c b/arch/mips/math-emu/dp_fmin.c
index a287b23818d8..f98b96135c8d 100644
--- a/arch/mips/math-emu/dp_fmin.c
+++ b/arch/mips/math-emu/dp_fmin.c
@@ -96,6 +96,7 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
DPDNORMY;
@@ -224,6 +225,7 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
DPDNORMY;
diff --git a/arch/mips/math-emu/dp_maddf.c b/arch/mips/math-emu/dp_maddf.c
index 7ad79ed411f5..7ea2f8222026 100644
--- a/arch/mips/math-emu/dp_maddf.c
+++ b/arch/mips/math-emu/dp_maddf.c
@@ -16,7 +16,7 @@
/* 128 bits shift right logical with rounding. */
-void srl128(u64 *hptr, u64 *lptr, int count)
+static void srl128(u64 *hptr, u64 *lptr, int count)
{
u64 low;
@@ -157,6 +157,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
if (zc == IEEE754_CLASS_INF)
@@ -173,7 +174,7 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
if (zc == IEEE754_CLASS_INF)
return ieee754dp_inf(zs);
- /* fall through to real computations */
+ /* continue to real computations */
}
/* Finally get to do some computation */
@@ -201,9 +202,6 @@ static union ieee754dp _dp_maddf(union ieee754dp z, union ieee754dp x,
* Multiply 64 bits xm and ym to give 128 bits result in hrm:lrm.
*/
- /* 32 * 32 => 64 */
-#define DPXMULT(x, y) ((u64)(x) * (u64)y)
-
lxm = xm;
hxm = xm >> 32;
lym = ym;
diff --git a/arch/mips/math-emu/dp_mul.c b/arch/mips/math-emu/dp_mul.c
index 60c8bfe40947..c34a6cdf1b25 100644
--- a/arch/mips/math-emu/dp_mul.c
+++ b/arch/mips/math-emu/dp_mul.c
@@ -101,6 +101,7 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
DPDNORMY;
@@ -128,9 +129,6 @@ union ieee754dp ieee754dp_mul(union ieee754dp x, union ieee754dp y)
* Multiply 64 bits xm, ym to give high 64 bits rm with stickness.
*/
- /* 32 * 32 => 64 */
-#define DPXMULT(x, y) ((u64)(x) * (u64)y)
-
lxm = xm;
hxm = xm >> 32;
lym = ym;
diff --git a/arch/mips/math-emu/dp_sqrt.c b/arch/mips/math-emu/dp_sqrt.c
index cea907b83146..1d26c92e5295 100644
--- a/arch/mips/math-emu/dp_sqrt.c
+++ b/arch/mips/math-emu/dp_sqrt.c
@@ -91,7 +91,8 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x)
scalx -= 256;
}
- y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+ x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT);
+ y = x;
/* magic initial approximation to almost 8 sig. bits */
yh = y.bits >> 32;
@@ -108,7 +109,8 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x)
/* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */
/* t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */
- z = t = ieee754dp_mul(y, y);
+ t = ieee754dp_mul(y, y);
+ z = t;
t.bexp += 0x001;
t = ieee754dp_add(t, z);
z = ieee754dp_mul(ieee754dp_sub(x, z), y);
@@ -140,7 +142,7 @@ union ieee754dp ieee754dp_sqrt(union ieee754dp x)
switch (oldcsr.rm) {
case FPU_CSR_RU:
y.bits += 1;
- /* drop through */
+ /* fall through */
case FPU_CSR_RN:
t.bits += 1;
break;
diff --git a/arch/mips/math-emu/dp_sub.c b/arch/mips/math-emu/dp_sub.c
index fc17a781b9ae..3cc48b86519b 100644
--- a/arch/mips/math-emu/dp_sub.c
+++ b/arch/mips/math-emu/dp_sub.c
@@ -106,7 +106,7 @@ union ieee754dp ieee754dp_sub(union ieee754dp x, union ieee754dp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
DPDNORMX;
- /* FALL THROUGH */
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
/* normalize ym,ye */
diff --git a/arch/mips/math-emu/ieee754dp.h b/arch/mips/math-emu/ieee754dp.h
index 9ba023004eb6..a56707b75282 100644
--- a/arch/mips/math-emu/ieee754dp.h
+++ b/arch/mips/math-emu/ieee754dp.h
@@ -55,6 +55,9 @@ static inline int ieee754dp_finite(union ieee754dp x)
#define XDPSRS1(v) \
(((v) >> 1) | ((v) & 1))
+/* 32bit * 32bit => 64bit unsigned integer multiplication */
+#define DPXMULT(x, y) ((u64)(x) * (u64)y)
+
/* convert denormal to normalized with extended exponent */
#define DPDNORMx(m,e) \
while ((m >> DP_FBITS) == 0) { m <<= 1; e--; }
diff --git a/arch/mips/math-emu/sp_add.c b/arch/mips/math-emu/sp_add.c
index c55c0c00bca8..51dced9fbdaf 100644
--- a/arch/mips/math-emu/sp_add.c
+++ b/arch/mips/math-emu/sp_add.c
@@ -104,8 +104,7 @@ union ieee754sp ieee754sp_add(union ieee754sp x, union ieee754sp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
-
- /* FALL THROUGH */
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
SPDNORMY;
diff --git a/arch/mips/math-emu/sp_div.c b/arch/mips/math-emu/sp_div.c
index 23587b31ca87..5d2904960eb8 100644
--- a/arch/mips/math-emu/sp_div.c
+++ b/arch/mips/math-emu/sp_div.c
@@ -103,6 +103,7 @@ union ieee754sp ieee754sp_div(union ieee754sp x, union ieee754sp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
SPDNORMY;
diff --git a/arch/mips/math-emu/sp_fdp.c b/arch/mips/math-emu/sp_fdp.c
index 5060e8fdcb0b..36a50f9082d1 100644
--- a/arch/mips/math-emu/sp_fdp.c
+++ b/arch/mips/math-emu/sp_fdp.c
@@ -46,7 +46,8 @@ union ieee754sp ieee754sp_fdp(union ieee754dp x)
case IEEE754_CLASS_SNAN:
x = ieee754dp_nanxcpt(x);
EXPLODEXDP;
- /* Fall through. */
+ /* fall through */
+
case IEEE754_CLASS_QNAN:
y = ieee754sp_nan_fdp(xs, xm);
if (!ieee754_csr.nan2008) {
diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c
index 74a5a00d2f22..22019ed691df 100644
--- a/arch/mips/math-emu/sp_fmax.c
+++ b/arch/mips/math-emu/sp_fmax.c
@@ -96,6 +96,7 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
SPDNORMY;
@@ -224,6 +225,7 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
SPDNORMY;
diff --git a/arch/mips/math-emu/sp_fmin.c b/arch/mips/math-emu/sp_fmin.c
index c51385f46b09..feaec3985cca 100644
--- a/arch/mips/math-emu/sp_fmin.c
+++ b/arch/mips/math-emu/sp_fmin.c
@@ -96,6 +96,7 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
SPDNORMY;
@@ -224,6 +225,7 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
SPDNORMY;
diff --git a/arch/mips/math-emu/sp_maddf.c b/arch/mips/math-emu/sp_maddf.c
index f823338dbb65..07ba675401e2 100644
--- a/arch/mips/math-emu/sp_maddf.c
+++ b/arch/mips/math-emu/sp_maddf.c
@@ -126,6 +126,7 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
if (zc == IEEE754_CLASS_INF)
@@ -142,7 +143,7 @@ static union ieee754sp _sp_maddf(union ieee754sp z, union ieee754sp x,
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM):
if (zc == IEEE754_CLASS_INF)
return ieee754sp_inf(zs);
- /* fall through to real computations */
+ /* continue to real computations */
}
/* Finally get to do some computation */
diff --git a/arch/mips/math-emu/sp_mul.c b/arch/mips/math-emu/sp_mul.c
index 4015101fbc37..fde71e293ec4 100644
--- a/arch/mips/math-emu/sp_mul.c
+++ b/arch/mips/math-emu/sp_mul.c
@@ -101,6 +101,7 @@ union ieee754sp ieee754sp_mul(union ieee754sp x, union ieee754sp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
SPDNORMY;
diff --git a/arch/mips/math-emu/sp_sqrt.c b/arch/mips/math-emu/sp_sqrt.c
index 67059c33a250..9cc83f012342 100644
--- a/arch/mips/math-emu/sp_sqrt.c
+++ b/arch/mips/math-emu/sp_sqrt.c
@@ -82,7 +82,8 @@ union ieee754sp ieee754sp_sqrt(union ieee754sp x)
/* generate sqrt(x) bit by bit */
ix += ix;
- q = s = 0; /* q = sqrt(x) */
+ s = 0;
+ q = 0; /* q = sqrt(x) */
r = 0x01000000; /* r = moving bit from right to left */
while (r != 0) {
diff --git a/arch/mips/math-emu/sp_sub.c b/arch/mips/math-emu/sp_sub.c
index dc998ed47295..9f2ff72c3d6b 100644
--- a/arch/mips/math-emu/sp_sub.c
+++ b/arch/mips/math-emu/sp_sub.c
@@ -106,6 +106,7 @@ union ieee754sp ieee754sp_sub(union ieee754sp x, union ieee754sp y)
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
SPDNORMX;
+ /* fall through */
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
SPDNORMY;
diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c
index a2450c7e452a..bca5ac995801 100644
--- a/arch/mips/math-emu/sp_tlong.c
+++ b/arch/mips/math-emu/sp_tlong.c
@@ -20,7 +20,6 @@
*/
#include "ieee754sp.h"
-#include "ieee754dp.h"
s64 ieee754sp_tlong(union ieee754sp x)
{
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 237532e89919..dcafa43613b6 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -370,11 +370,6 @@ static void mips_dma_sync_sg_for_device(struct device *dev,
}
}
-static int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
- return 0;
-}
-
static int mips_dma_supported(struct device *dev, u64 mask)
{
return plat_dma_supported(dev, mask);
@@ -401,7 +396,6 @@ static const struct dma_map_ops mips_default_dma_map_ops = {
.sync_single_for_device = mips_dma_sync_single_for_device,
.sync_sg_for_cpu = mips_dma_sync_sg_for_cpu,
.sync_sg_for_device = mips_dma_sync_sg_for_device,
- .mapping_error = mips_dma_mapping_error,
.dma_supported = mips_dma_supported,
.cache_sync = mips_dma_cache_sync,
};
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
index 548acb7f8557..394673991bab 100644
--- a/arch/mips/mm/sc-mips.c
+++ b/arch/mips/mm/sc-mips.c
@@ -16,6 +16,7 @@
#include <asm/mmu_context.h>
#include <asm/r4kcache.h>
#include <asm/mips-cps.h>
+#include <asm/bootinfo.h>
/*
* MIPS32/MIPS64 L2 cache handling
@@ -220,6 +221,14 @@ static inline int __init mips_sc_probe(void)
else
return 0;
+ /*
+ * According to config2 it would be 5-ways, but that is contradicted
+ * by all documentation.
+ */
+ if (current_cpu_type() == CPU_JZRISC &&
+ mips_machtype == MACH_INGENIC_JZ4770)
+ c->scache.ways = 4;
+
c->scache.waysize = c->scache.sets * c->scache.linesz;
c->scache.waybit = __ffs(c->scache.waysize);
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
index de34adb76157..7b63914d2e58 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -47,31 +47,31 @@ static struct resource standard_io_resources[] = {
.name = "dma1",
.start = 0x00,
.end = 0x1f,
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
},
{
.name = "timer",
.start = 0x40,
.end = 0x5f,
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
},
{
.name = "keyboard",
.start = 0x60,
.end = 0x6f,
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
},
{
.name = "dma page reg",
.start = 0x80,
.end = 0x8f,
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
},
{
.name = "dma2",
.start = 0xc0,
.end = 0xdf,
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
},
};
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index 8b937300fb7f..fd26fadc8617 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -186,7 +186,7 @@ static void __init rbtx4939_update_ioc_pen(void)
#define RBTX4939_MAX_7SEGLEDS 8
-#if IS_ENABLED(CONFIG_LEDS_CLASS)
+#if IS_BUILTIN(CONFIG_LEDS_CLASS)
static u8 led_val[RBTX4939_MAX_7SEGLEDS];
struct rbtx4939_led_data {
struct led_classdev cdev;
@@ -261,7 +261,7 @@ static inline void rbtx4939_led_setup(void)
static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
{
-#if IS_ENABLED(CONFIG_LEDS_CLASS)
+#if IS_BUILTIN(CONFIG_LEDS_CLASS)
unsigned long flags;
local_irq_save(flags);
/* bit7: reserved for LED class */
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9d3329811cc1..73ce5dd07642 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -141,6 +141,7 @@ config PPC
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_PHYS_TO_DMA
select ARCH_HAS_PMEM_API if PPC64
+ select ARCH_HAS_MEMBARRIER_CALLBACKS
select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE
select ARCH_HAS_SG_CHAIN
select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION)
diff --git a/arch/powerpc/include/asm/membarrier.h b/arch/powerpc/include/asm/membarrier.h
new file mode 100644
index 000000000000..6e20bb5c74ea
--- /dev/null
+++ b/arch/powerpc/include/asm/membarrier.h
@@ -0,0 +1,27 @@
+#ifndef _ASM_POWERPC_MEMBARRIER_H
+#define _ASM_POWERPC_MEMBARRIER_H
+
+static inline void membarrier_arch_switch_mm(struct mm_struct *prev,
+ struct mm_struct *next,
+ struct task_struct *tsk)
+{
+ /*
+ * Only need the full barrier when switching between processes.
+ * Barrier when switching from kernel to userspace is not
+ * required here, given that it is implied by mmdrop(). Barrier
+ * when switching from userspace to kernel is not needed after
+ * store to rq->curr.
+ */
+ if (likely(!(atomic_read(&next->membarrier_state) &
+ (MEMBARRIER_STATE_PRIVATE_EXPEDITED |
+ MEMBARRIER_STATE_GLOBAL_EXPEDITED)) || !prev))
+ return;
+
+ /*
+ * The membarrier system call requires a full memory barrier
+ * after storing to rq->curr, before going back to user-space.
+ */
+ smp_mb();
+}
+
+#endif /* _ASM_POWERPC_MEMBARRIER_H */
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index cc649809885e..2b9df0040d6b 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -756,14 +756,14 @@ int eeh_restore_vf_config(struct pci_dn *pdn)
eeh_ops->write_config(pdn, edev->pcie_cap + PCI_EXP_DEVCTL,
2, devctl);
- /* Disable Completion Timeout */
+ /* Disable Completion Timeout if possible */
eeh_ops->read_config(pdn, edev->pcie_cap + PCI_EXP_DEVCAP2,
4, &cap2);
- if (cap2 & 0x10) {
+ if (cap2 & PCI_EXP_DEVCAP2_COMP_TMOUT_DIS) {
eeh_ops->read_config(pdn,
edev->pcie_cap + PCI_EXP_DEVCTL2,
4, &cap2);
- cap2 |= 0x10;
+ cap2 |= PCI_EXP_DEVCTL2_COMP_TMOUT_DIS;
eeh_ops->write_config(pdn,
edev->pcie_cap + PCI_EXP_DEVCTL2,
4, cap2);
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 208e623b2557..ae2ede4de6be 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -362,8 +362,7 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
*/
static int pci_read_irq_line(struct pci_dev *pci_dev)
{
- struct of_phandle_args oirq;
- unsigned int virq;
+ unsigned int virq = 0;
pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev));
@@ -371,7 +370,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
memset(&oirq, 0xff, sizeof(oirq));
#endif
/* Try to get a mapping from the device-tree */
- if (of_irq_parse_pci(pci_dev, &oirq)) {
+ if (!of_irq_parse_and_map_pci(pci_dev, 0, 0)) {
u8 line, pin;
/* If that fails, lets fallback to what is in the config
@@ -395,11 +394,6 @@ static int pci_read_irq_line(struct pci_dev *pci_dev)
virq = irq_create_mapping(NULL, line);
if (virq)
irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
- } else {
- pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %pOF\n",
- oirq.args_count, oirq.args[0], oirq.args[1], oirq.np);
-
- virq = irq_create_of_mapping(&oirq);
}
if (!virq) {
diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c
index 2d71269e7dc1..cf47b1aec4c2 100644
--- a/arch/powerpc/kernel/pci-hotplug.c
+++ b/arch/powerpc/kernel/pci-hotplug.c
@@ -104,7 +104,7 @@ EXPORT_SYMBOL_GPL(pci_hp_remove_devices);
*/
void pci_hp_add_devices(struct pci_bus *bus)
{
- int slotno, mode, pass, max;
+ int slotno, mode, max;
struct pci_dev *dev;
struct pci_controller *phb;
struct device_node *dn = pci_bus_to_OF_node(bus);
@@ -133,13 +133,17 @@ void pci_hp_add_devices(struct pci_bus *bus)
pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
pcibios_setup_bus_devices(bus);
max = bus->busn_res.start;
- for (pass = 0; pass < 2; pass++) {
- list_for_each_entry(dev, &bus->devices, bus_list) {
- if (pci_is_bridge(dev))
- max = pci_scan_bridge(bus, dev,
- max, pass);
- }
- }
+ /*
+ * Scan bridges that are already configured. We don't touch
+ * them unless they are misconfigured (which will be done in
+ * the second scan below).
+ */
+ for_each_pci_bridge(dev, bus)
+ max = pci_scan_bridge(bus, dev, max, 0);
+
+ /* Scan bridges that need to be reconfigured */
+ for_each_pci_bridge(dev, bus)
+ max = pci_scan_bridge(bus, dev, max, 1);
}
pcibios_finish_adding_to_bus(bus);
}
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 1d817f4d97d9..85ad2f78b889 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -96,7 +96,8 @@ make_one_node_map(struct device_node* node, u8 pci_bus)
reg = of_get_property(node, "reg", NULL);
if (!reg)
continue;
- dev = pci_get_bus_and_slot(pci_bus, ((reg[0] >> 8) & 0xff));
+ dev = pci_get_domain_bus_and_slot(0, pci_bus,
+ ((reg[0] >> 8) & 0xff));
if (!dev || !dev->subordinate) {
pci_dev_put(dev);
continue;
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 20ceec4a5f5e..98f04725def7 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -369,11 +369,8 @@ static void __of_scan_bus(struct device_node *node, struct pci_bus *bus,
pcibios_setup_bus_devices(bus);
/* Now scan child busses */
- list_for_each_entry(dev, &bus->devices, bus_list) {
- if (pci_is_bridge(dev)) {
- of_scan_pci_bridge(dev);
- }
- }
+ for_each_pci_bridge(dev, bus)
+ of_scan_pci_bridge(dev);
}
/**
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index f6eb7e8f4c93..fdb424a29f03 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -183,7 +183,8 @@ static __meminit void vmemmap_list_populate(unsigned long phys,
vmemmap_list = vmem_back;
}
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+ struct vmem_altmap *altmap)
{
unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
@@ -193,17 +194,16 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node);
for (; start < end; start += page_size) {
- struct vmem_altmap *altmap;
void *p;
int rc;
if (vmemmap_populated(start, page_size))
continue;
- /* altmap lookups only work at section boundaries */
- altmap = to_vmem_altmap(SECTION_ALIGN_DOWN(start));
-
- p = __vmemmap_alloc_block_buf(page_size, node, altmap);
+ if (altmap)
+ p = altmap_alloc_block_buf(page_size, altmap);
+ else
+ p = vmemmap_alloc_block_buf(page_size, node);
if (!p)
return -ENOMEM;
@@ -256,7 +256,8 @@ static unsigned long vmemmap_list_free(unsigned long start)
return vmem_back->phys;
}
-void __ref vmemmap_free(unsigned long start, unsigned long end)
+void __ref vmemmap_free(unsigned long start, unsigned long end,
+ struct vmem_altmap *altmap)
{
unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
unsigned long page_order = get_order(page_size);
@@ -267,7 +268,6 @@ void __ref vmemmap_free(unsigned long start, unsigned long end)
for (; start < end; start += page_size) {
unsigned long nr_pages, addr;
- struct vmem_altmap *altmap;
struct page *section_base;
struct page *page;
@@ -287,7 +287,6 @@ void __ref vmemmap_free(unsigned long start, unsigned long end)
section_base = pfn_to_page(vmemmap_section_start(start));
nr_pages = 1 << page_order;
- altmap = to_vmem_altmap((unsigned long) section_base);
if (altmap) {
vmem_altmap_free(altmap, nr_pages);
} else if (PageReserved(page)) {
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 1281c6eb3a85..fe8c61149fb8 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -127,7 +127,8 @@ int __weak remove_section_mapping(unsigned long start, unsigned long end)
return -ENODEV;
}
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+ bool want_memblock)
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
@@ -143,15 +144,14 @@ int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
return -EFAULT;
}
- return __add_pages(nid, start_pfn, nr_pages, want_memblock);
+ return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
}
#ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
+int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
- struct vmem_altmap *altmap;
struct page *page;
int ret;
@@ -160,11 +160,10 @@ int arch_remove_memory(u64 start, u64 size)
* when querying the zone.
*/
page = pfn_to_page(start_pfn);
- altmap = to_vmem_altmap((unsigned long) page);
if (altmap)
page += vmem_altmap_offset(altmap);
- ret = __remove_pages(page_zone(page), start_pfn, nr_pages);
+ ret = __remove_pages(page_zone(page), start_pfn, nr_pages, altmap);
if (ret)
return ret;
diff --git a/arch/powerpc/mm/mmu_context.c b/arch/powerpc/mm/mmu_context.c
index d60a62bf4fc7..0ab297c4cfad 100644
--- a/arch/powerpc/mm/mmu_context.c
+++ b/arch/powerpc/mm/mmu_context.c
@@ -12,6 +12,7 @@
#include <linux/mm.h>
#include <linux/cpu.h>
+#include <linux/sched/mm.h>
#include <asm/mmu_context.h>
@@ -58,6 +59,10 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
*
* On the read side the barrier is in pte_xchg(), which orders
* the store to the PTE vs the load of mm_cpumask.
+ *
+ * This full barrier is needed by membarrier when switching
+ * between processes after store to rq->curr, before user-space
+ * memory accesses.
*/
smp_mb();
@@ -80,6 +85,8 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
if (new_on_cpu)
radix_kvm_prefetch_workaround(next);
+ else
+ membarrier_arch_switch_mm(prev, next, tsk);
/*
* The actual HW switching method differs between the various
diff --git a/arch/powerpc/platforms/maple/time.c b/arch/powerpc/platforms/maple/time.c
index 81799d70a1ee..cfddc87f81bf 100644
--- a/arch/powerpc/platforms/maple/time.c
+++ b/arch/powerpc/platforms/maple/time.c
@@ -134,7 +134,7 @@ int maple_set_rtc_time(struct rtc_time *tm)
static struct resource rtc_iores = {
.name = "rtc",
- .flags = IORESOURCE_BUSY,
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY,
};
unsigned long __init maple_get_boot_time(void)
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index 466b84234683..3f82cb24eb2b 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -829,7 +829,7 @@ core99_ata100_enable(struct device_node *node, long value)
if (value) {
if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
- pdev = pci_get_bus_and_slot(pbus, pid);
+ pdev = pci_get_domain_bus_and_slot(0, pbus, pid);
if (pdev == NULL)
return 0;
rc = pci_enable_device(pdev);
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index bafb014e1a7e..cb9a8b71fd0f 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -145,21 +145,21 @@ static struct resource pic1_iores = {
.name = "8259 (master)",
.start = 0x20,
.end = 0x21,
- .flags = IORESOURCE_BUSY,
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY,
};
static struct resource pic2_iores = {
.name = "8259 (slave)",
.start = 0xa0,
.end = 0xa1,
- .flags = IORESOURCE_BUSY,
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY,
};
static struct resource pic_edgectrl_iores = {
.name = "8259 edge control",
.start = 0x4d0,
.end = 0x4d1,
- .flags = IORESOURCE_BUSY,
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY,
};
static int i8259_host_match(struct irq_domain *h, struct device_node *node,
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c
index 50c411b1761e..1afcdb428e51 100644
--- a/arch/powerpc/sysdev/mv64x60_pci.c
+++ b/arch/powerpc/sysdev/mv64x60_pci.c
@@ -37,7 +37,7 @@ static ssize_t mv64x60_hs_reg_read(struct file *filp, struct kobject *kobj,
if (count < MV64X60_VAL_LEN_MAX)
return -EINVAL;
- phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+ phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
if (!phb)
return -ENODEV;
pci_read_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, &v);
@@ -61,7 +61,7 @@ static ssize_t mv64x60_hs_reg_write(struct file *filp, struct kobject *kobj,
if (sscanf(buf, "%i", &v) != 1)
return -EINVAL;
- phb = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+ phb = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
if (!phb)
return -ENODEV;
pci_write_config_dword(phb, MV64X60_PCICFG_CPCI_HOTSWAP, v);
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 865e14f50c14..b6722c246d9c 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -22,6 +22,7 @@ config RISCV
select GENERIC_ATOMIC64 if !64BIT || !RISCV_ISA_A
select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_MEMBLOCK
+ select HAVE_MEMBLOCK_NODE_MAP
select HAVE_DMA_API_DEBUG
select HAVE_DMA_CONTIGUOUS
select HAVE_GENERIC_DMA_COHERENT
@@ -43,6 +44,10 @@ config MMU
config ARCH_PHYS_ADDR_T_64BIT
def_bool y
+config ZONE_DMA32
+ bool
+ default y
+
config ARCH_DMA_ADDR_T_64BIT
def_bool y
@@ -55,6 +60,9 @@ config PAGE_OFFSET
config STACKTRACE_SUPPORT
def_bool y
+config TRACE_IRQFLAGS_SUPPORT
+ def_bool y
+
config RWSEM_GENERIC_SPINLOCK
def_bool y
@@ -107,6 +115,8 @@ config ARCH_RV64I
bool "RV64I"
select CPU_SUPPORTS_64BIT_KERNEL
select 64BIT
+ select HAVE_FUNCTION_TRACER
+ select HAVE_FUNCTION_GRAPH_TRACER
endchoice
diff --git a/arch/riscv/include/asm/Kbuild b/arch/riscv/include/asm/Kbuild
index 681ac0d09314..4286a5f83876 100644
--- a/arch/riscv/include/asm/Kbuild
+++ b/arch/riscv/include/asm/Kbuild
@@ -12,7 +12,6 @@ generic-y += errno.h
generic-y += exec.h
generic-y += fb.h
generic-y += fcntl.h
-generic-y += ftrace.h
generic-y += futex.h
generic-y += hardirq.h
generic-y += hash.h
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 3c7a2c97e377..421fa3585798 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -40,15 +40,15 @@
#define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */
#endif
-/* SPTBR flags */
+/* SATP flags */
#if __riscv_xlen == 32
-#define SPTBR_PPN _AC(0x003FFFFF, UL)
-#define SPTBR_MODE_32 _AC(0x80000000, UL)
-#define SPTBR_MODE SPTBR_MODE_32
+#define SATP_PPN _AC(0x003FFFFF, UL)
+#define SATP_MODE_32 _AC(0x80000000, UL)
+#define SATP_MODE SATP_MODE_32
#else
-#define SPTBR_PPN _AC(0x00000FFFFFFFFFFF, UL)
-#define SPTBR_MODE_39 _AC(0x8000000000000000, UL)
-#define SPTBR_MODE SPTBR_MODE_39
+#define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL)
+#define SATP_MODE_39 _AC(0x8000000000000000, UL)
+#define SATP_MODE SATP_MODE_39
#endif
/* Interrupt Enable and Interrupt Pending flags */
diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
new file mode 100644
index 000000000000..66d4175eb13e
--- /dev/null
+++ b/arch/riscv/include/asm/ftrace.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2017 Andes Technology Corporation */
+
+/*
+ * The graph frame test is not possible if CONFIG_FRAME_POINTER is not enabled.
+ * Check arch/riscv/kernel/mcount.S for detail.
+ */
+#if defined(CONFIG_FUNCTION_GRAPH_TRACER) && defined(CONFIG_FRAME_POINTER)
+#define HAVE_FUNCTION_GRAPH_FP_TEST
+#endif
diff --git a/arch/riscv/include/asm/mmu_context.h b/arch/riscv/include/asm/mmu_context.h
index 97424834dce2..336d60ec5698 100644
--- a/arch/riscv/include/asm/mmu_context.h
+++ b/arch/riscv/include/asm/mmu_context.h
@@ -39,16 +39,6 @@ static inline void destroy_context(struct mm_struct *mm)
{
}
-static inline pgd_t *current_pgdir(void)
-{
- return pfn_to_virt(csr_read(sptbr) & SPTBR_PPN);
-}
-
-static inline void set_pgdir(pgd_t *pgd)
-{
- csr_write(sptbr, virt_to_pfn(pgd) | SPTBR_MODE);
-}
-
/*
* When necessary, performs a deferred icache flush for the given MM context,
* on the local CPU. RISC-V has no direct mechanism for instruction cache
@@ -93,7 +83,12 @@ static inline void switch_mm(struct mm_struct *prev,
cpumask_clear_cpu(cpu, mm_cpumask(prev));
cpumask_set_cpu(cpu, mm_cpumask(next));
- set_pgdir(next->pgd);
+ /*
+ * Use the old spbtr name instead of using the current satp
+ * name to support binutils 2.29 which doesn't know about the
+ * privileged ISA 1.10 yet.
+ */
+ csr_write(sptbr, virt_to_pfn(next->pgd) | SATP_MODE);
local_flush_tlb_all();
flush_icache_deferred(next);
diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
index 7b9c24ebdf52..7b209aec355d 100644
--- a/arch/riscv/include/asm/tlbflush.h
+++ b/arch/riscv/include/asm/tlbflush.h
@@ -36,7 +36,14 @@ static inline void local_flush_tlb_page(unsigned long addr)
#define flush_tlb_all() local_flush_tlb_all()
#define flush_tlb_page(vma, addr) local_flush_tlb_page(addr)
-#define flush_tlb_range(vma, start, end) local_flush_tlb_all()
+
+static inline void flush_tlb_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ local_flush_tlb_all();
+}
+
+#define flush_tlb_mm(mm) flush_tlb_all()
#else /* CONFIG_SMP */
@@ -45,16 +52,13 @@ static inline void local_flush_tlb_page(unsigned long addr)
#define flush_tlb_all() sbi_remote_sfence_vma(0, 0, -1)
#define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, 0)
#define flush_tlb_range(vma, start, end) \
- sbi_remote_sfence_vma(0, start, (end) - (start))
+ sbi_remote_sfence_vma(mm_cpumask((vma)->vm_mm)->bits, \
+ start, (end) - (start))
+#define flush_tlb_mm(mm) \
+ sbi_remote_sfence_vma(mm_cpumask(mm)->bits, 0, -1)
#endif /* CONFIG_SMP */
-/* Flush the TLB entries of the specified mm context */
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
- flush_tlb_all();
-}
-
/* Flush a range of kernel pages */
static inline void flush_tlb_kernel_range(unsigned long start,
unsigned long end)
diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h
index 2f704a5c4196..080fb28061de 100644
--- a/arch/riscv/include/asm/unistd.h
+++ b/arch/riscv/include/asm/unistd.h
@@ -11,7 +11,6 @@
* GNU General Public License for more details.
*/
-#define __ARCH_HAVE_MMU
#define __ARCH_WANT_SYS_CLONE
#include <uapi/asm/unistd.h>
#include <uapi/asm/syscalls.h>
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index ab8baf7bd142..196f62ffc428 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -2,6 +2,11 @@
# Makefile for the RISC-V Linux kernel
#
+ifdef CONFIG_FTRACE
+CFLAGS_REMOVE_ftrace.o = -pg
+CFLAGS_REMOVE_setup.o = -pg
+endif
+
extra-y += head.o
extra-y += vmlinux.lds
@@ -29,5 +34,7 @@ CFLAGS_setup.o := -mcmodel=medany
obj-$(CONFIG_SMP) += smpboot.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
clean:
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 7404ec222406..87fc045be51f 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -78,10 +78,13 @@ _save_context:
REG_S x31, PT_T6(sp)
/*
- * Disable FPU to detect illegal usage of
- * floating point in kernel space
+ * Disable user-mode memory access as it should only be set in the
+ * actual user copy routines.
+ *
+ * Disable the FPU to detect illegal usage of floating point in kernel
+ * space.
*/
- li t0, SR_FS
+ li t0, SR_SUM | SR_FS
REG_L s0, TASK_TI_USER_SP(tp)
csrrc s1, sstatus, t0
diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
new file mode 100644
index 000000000000..d0de68d144cb
--- /dev/null
+++ b/arch/riscv/kernel/ftrace.c
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2013 Linaro Limited
+ * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
+ * Copyright (C) 2017 Andes Technology Corporation
+ */
+
+#include <linux/ftrace.h>
+
+/*
+ * Most of this file is copied from arm64.
+ */
+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
+ unsigned long frame_pointer)
+{
+ unsigned long return_hooker = (unsigned long)&return_to_handler;
+ unsigned long old;
+ struct ftrace_graph_ent trace;
+ int err;
+
+ if (unlikely(atomic_read(&current->tracing_graph_pause)))
+ return;
+
+ /*
+ * We don't suffer access faults, so no extra fault-recovery assembly
+ * is needed here.
+ */
+ old = *parent;
+
+ trace.func = self_addr;
+ trace.depth = current->curr_ret_stack + 1;
+
+ if (!ftrace_graph_entry(&trace))
+ return;
+
+ err = ftrace_push_return_trace(old, self_addr, &trace.depth,
+ frame_pointer, NULL);
+ if (err == -EBUSY)
+ return;
+ *parent = return_hooker;
+}
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 78f670d70133..226eeb190f90 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -74,15 +74,15 @@ relocate:
sub a1, a1, a0
add ra, ra, a1
- /* Point stvec to virtual address of intruction after sptbr write */
+ /* Point stvec to virtual address of intruction after satp write */
la a0, 1f
add a0, a0, a1
csrw stvec, a0
- /* Compute sptbr for kernel page tables, but don't load it yet */
+ /* Compute satp for kernel page tables, but don't load it yet */
la a2, swapper_pg_dir
srl a2, a2, PAGE_SHIFT
- li a1, SPTBR_MODE
+ li a1, SATP_MODE
or a2, a2, a1
/*
diff --git a/arch/riscv/kernel/mcount.S b/arch/riscv/kernel/mcount.S
new file mode 100644
index 000000000000..c46a778627be
--- /dev/null
+++ b/arch/riscv/kernel/mcount.S
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2017 Andes Technology Corporation */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/asm.h>
+#include <asm/csr.h>
+#include <asm/unistd.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+#include <asm-generic/export.h>
+#include <asm/ftrace.h>
+
+ .text
+
+ .macro SAVE_ABI_STATE
+ addi sp, sp, -16
+ sd s0, 0(sp)
+ sd ra, 8(sp)
+ addi s0, sp, 16
+ .endm
+
+ /*
+ * The call to ftrace_return_to_handler would overwrite the return
+ * register if a0 was not saved.
+ */
+ .macro SAVE_RET_ABI_STATE
+ addi sp, sp, -32
+ sd s0, 16(sp)
+ sd ra, 24(sp)
+ sd a0, 8(sp)
+ addi s0, sp, 32
+ .endm
+
+ .macro STORE_ABI_STATE
+ ld ra, 8(sp)
+ ld s0, 0(sp)
+ addi sp, sp, 16
+ .endm
+
+ .macro STORE_RET_ABI_STATE
+ ld ra, 24(sp)
+ ld s0, 16(sp)
+ ld a0, 8(sp)
+ addi sp, sp, 32
+ .endm
+
+ENTRY(ftrace_stub)
+ ret
+ENDPROC(ftrace_stub)
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ENTRY(return_to_handler)
+/*
+ * On implementing the frame point test, the ideal way is to compare the
+ * s0 (frame pointer, if enabled) on entry and the sp (stack pointer) on return.
+ * However, the psABI of variable-length-argument functions does not allow this.
+ *
+ * So alternatively we check the *old* frame pointer position, that is, the
+ * value stored in -16(s0) on entry, and the s0 on return.
+ */
+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
+ mv t6, s0
+#endif
+ SAVE_RET_ABI_STATE
+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
+ mv a0, t6
+#endif
+ la t0, ftrace_return_to_handler
+ jalr t0
+ mv a1, a0
+ STORE_RET_ABI_STATE
+ jalr a1
+ENDPROC(return_to_handler)
+EXPORT_SYMBOL(return_to_handler)
+#endif
+
+ENTRY(_mcount)
+ la t4, ftrace_stub
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ la t0, ftrace_graph_return
+ ld t1, 0(t0)
+ bne t1, t4, do_ftrace_graph_caller
+
+ la t3, ftrace_graph_entry
+ ld t2, 0(t3)
+ la t6, ftrace_graph_entry_stub
+ bne t2, t6, do_ftrace_graph_caller
+#endif
+ la t3, ftrace_trace_function
+ ld t5, 0(t3)
+ bne t5, t4, do_trace
+ ret
+
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+/*
+ * A pseudo representation for the function graph tracer:
+ * prepare_to_return(&ra_to_caller_of_caller, ra_to_caller)
+ */
+do_ftrace_graph_caller:
+ addi a0, s0, -8
+ mv a1, ra
+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
+ ld a2, -16(s0)
+#endif
+ SAVE_ABI_STATE
+ la t0, prepare_ftrace_return
+ jalr t0
+ STORE_ABI_STATE
+ ret
+#endif
+
+/*
+ * A pseudo representation for the function tracer:
+ * (*ftrace_trace_function)(ra_to_caller, ra_to_caller_of_caller)
+ */
+do_trace:
+ ld a1, -8(s0)
+ mv a0, ra
+
+ SAVE_ABI_STATE
+ jalr t5
+ STORE_ABI_STATE
+ ret
+ENDPROC(_mcount)
+EXPORT_SYMBOL(_mcount)
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index cb7b0c63014e..09f7064e898c 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -49,10 +49,6 @@ struct screen_info screen_info = {
};
#endif
-#ifdef CONFIG_CMDLINE_BOOL
-static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
-#endif /* CONFIG_CMDLINE_BOOL */
-
unsigned long va_pa_offset;
EXPORT_SYMBOL(va_pa_offset);
unsigned long pfn_base;
@@ -153,25 +149,6 @@ void __init sbi_save(unsigned int hartid, void *dtb)
early_init_dt_scan(__va(dtb));
}
-/*
- * Allow the user to manually add a memory region (in case DTS is broken);
- * "mem_end=nn[KkMmGg]"
- */
-static int __init mem_end_override(char *p)
-{
- resource_size_t base, end;
-
- if (!p)
- return -EINVAL;
- base = (uintptr_t) __pa(PAGE_OFFSET);
- end = memparse(p, &p) & PMD_MASK;
- if (end == 0)
- return -EINVAL;
- memblock_add(base, end - base);
- return 0;
-}
-early_param("mem_end", mem_end_override);
-
static void __init setup_bootmem(void)
{
struct memblock_region *reg;
@@ -204,22 +181,19 @@ static void __init setup_bootmem(void)
early_init_fdt_scan_reserved_mem();
memblock_allow_resize();
memblock_dump_all();
+
+ for_each_memblock(memory, reg) {
+ unsigned long start_pfn = memblock_region_memory_base_pfn(reg);
+ unsigned long end_pfn = memblock_region_memory_end_pfn(reg);
+
+ memblock_set_node(PFN_PHYS(start_pfn),
+ PFN_PHYS(end_pfn - start_pfn),
+ &memblock.memory, 0);
+ }
}
void __init setup_arch(char **cmdline_p)
{
-#ifdef CONFIG_CMDLINE_BOOL
-#ifdef CONFIG_CMDLINE_OVERRIDE
- strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
-#else
- if (builtin_cmdline[0] != '\0') {
- /* Append bootloader command line to built-in */
- strlcat(builtin_cmdline, " ", COMMAND_LINE_SIZE);
- strlcat(builtin_cmdline, boot_command_line, COMMAND_LINE_SIZE);
- strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
- }
-#endif /* CONFIG_CMDLINE_OVERRIDE */
-#endif /* CONFIG_CMDLINE_BOOL */
*cmdline_p = boot_command_line;
parse_early_param();
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index e8a178df8144..582cb153eb24 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -74,7 +74,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
down_write(&mm->mmap_sem);
vdso_base = get_unmapped_area(NULL, 0, vdso_len, 0, 0);
- if (unlikely(IS_ERR_VALUE(vdso_base))) {
+ if (IS_ERR_VALUE(vdso_base)) {
ret = vdso_base;
goto end;
}
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index ceebfc29305b..148c98ca9b45 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -238,6 +238,10 @@ vmalloc_fault:
* Do _not_ use "tsk->active_mm->pgd" here.
* We might be inside an interrupt in the middle
* of a task switch.
+ *
+ * Note: Use the old spbtr name instead of using the current
+ * satp name to support binutils 2.29 which doesn't know about
+ * the privileged ISA 1.10 yet.
*/
index = pgd_index(addr);
pgd = (pgd_t *)pfn_to_virt(csr_read(sptbr)) + index;
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 9f4bee5e51fd..c77df8142be2 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -17,6 +17,7 @@
#include <linux/initrd.h>
#include <linux/memblock.h>
#include <linux/swap.h>
+#include <linux/sizes.h>
#include <asm/tlbflush.h>
#include <asm/sections.h>
@@ -25,11 +26,12 @@
static void __init zone_sizes_init(void)
{
- unsigned long zones_size[MAX_NR_ZONES];
+ unsigned long max_zone_pfns[MAX_NR_ZONES] = { 0, };
- memset(zones_size, 0, sizeof(zones_size));
- zones_size[ZONE_NORMAL] = max_mapnr;
- free_area_init_node(0, zones_size, pfn_base, NULL);
+ max_zone_pfns[ZONE_DMA32] = PFN_DOWN(min(4UL * SZ_1G, max_low_pfn));
+ max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+
+ free_area_init_nodes(max_zone_pfns);
}
void setup_zero_page(void)
@@ -39,8 +41,6 @@ void setup_zero_page(void)
void __init paging_init(void)
{
- init_mm.pgd = (pgd_t *)pfn_to_virt(csr_read(sptbr));
-
setup_zero_page();
local_flush_tlb_all();
zone_sizes_init();
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 671535e64aba..3fa3e5323612 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -222,7 +222,8 @@ device_initcall(s390_cma_mem_init);
#endif /* CONFIG_CMA */
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+ bool want_memblock)
{
unsigned long start_pfn = PFN_DOWN(start);
unsigned long size_pages = PFN_DOWN(size);
@@ -232,14 +233,14 @@ int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
if (rc)
return rc;
- rc = __add_pages(nid, start_pfn, size_pages, want_memblock);
+ rc = __add_pages(nid, start_pfn, size_pages, altmap, want_memblock);
if (rc)
vmem_remove_mapping(start, size);
return rc;
}
#ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
+int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
{
/*
* There is no hardware or firmware interface which could trigger a
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 3316d463fc29..db55561c5981 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -211,7 +211,8 @@ static void vmem_remove_range(unsigned long start, unsigned long size)
/*
* Add a backed mem_map array to the virtual mem_map array.
*/
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+ struct vmem_altmap *altmap)
{
unsigned long pgt_prot, sgt_prot;
unsigned long address = start;
@@ -296,7 +297,8 @@ out:
return ret;
}
-void vmemmap_free(unsigned long start, unsigned long end)
+void vmemmap_free(unsigned long start, unsigned long end,
+ struct vmem_altmap *altmap)
{
}
diff --git a/arch/score/kernel/setup.c b/arch/score/kernel/setup.c
index f3a0649ab521..627416bbd0b1 100644
--- a/arch/score/kernel/setup.c
+++ b/arch/score/kernel/setup.c
@@ -124,9 +124,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
{
unsigned long n = (unsigned long) v - 1;
- seq_printf(m, "processor\t\t: %ld\n", n);
- seq_printf(m, "\n");
-
+ seq_printf(m, "processor\t\t: %ld\n\n", n);
return 0;
}
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index bf726af5f1a5..ce0bbaa7e404 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -485,20 +485,20 @@ void free_initrd_mem(unsigned long start, unsigned long end)
#endif
#ifdef CONFIG_MEMORY_HOTPLUG
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+ bool want_memblock)
{
unsigned long start_pfn = PFN_DOWN(start);
unsigned long nr_pages = size >> PAGE_SHIFT;
int ret;
/* We only have ZONE_NORMAL, so this is easy.. */
- ret = __add_pages(nid, start_pfn, nr_pages, want_memblock);
+ ret = __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
if (unlikely(ret))
printk("%s: Failed, __add_pages() == %d\n", __func__, ret);
return ret;
}
-EXPORT_SYMBOL_GPL(arch_add_memory);
#ifdef CONFIG_NUMA
int memory_add_physaddr_to_nid(u64 addr)
@@ -510,7 +510,7 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
#endif
#ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
+int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
{
unsigned long start_pfn = PFN_DOWN(start);
unsigned long nr_pages = size >> PAGE_SHIFT;
@@ -518,7 +518,7 @@ int arch_remove_memory(u64 start, u64 size)
int ret;
zone = page_zone(pfn_to_page(start_pfn));
- ret = __remove_pages(zone, start_pfn, nr_pages);
+ ret = __remove_pages(zone, start_pfn, nr_pages, altmap);
if (unlikely(ret))
pr_warn("%s: Failed, __remove_pages() == %d\n", __func__,
ret);
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 55ba62957e64..995f9490334d 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -2628,7 +2628,7 @@ EXPORT_SYMBOL(_PAGE_CACHE);
#ifdef CONFIG_SPARSEMEM_VMEMMAP
int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend,
- int node)
+ int node, struct vmem_altmap *altmap)
{
unsigned long pte_base;
@@ -2671,7 +2671,8 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend,
return 0;
}
-void vmemmap_free(unsigned long start, unsigned long end)
+void vmemmap_free(unsigned long start, unsigned long end,
+ struct vmem_altmap *altmap)
{
}
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
diff --git a/arch/unicore32/include/asm/bitops.h b/arch/unicore32/include/asm/bitops.h
index 401f597bc38c..c0cbdbe17168 100644
--- a/arch/unicore32/include/asm/bitops.h
+++ b/arch/unicore32/include/asm/bitops.h
@@ -44,4 +44,6 @@ static inline int fls(int x)
#define find_first_bit find_first_bit
#define find_first_zero_bit find_first_zero_bit
+#include <asm-generic/bitops/find.h>
+
#endif /* __UNICORE_BITOPS_H__ */
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b0771ceabb4b..63bf349b2b24 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -55,6 +55,7 @@ config X86
select ARCH_HAS_GCOV_PROFILE_ALL
select ARCH_HAS_KCOV if X86_64
select ARCH_HAS_PHYS_TO_DMA
+ select ARCH_HAS_MEMBARRIER_SYNC_CORE
select ARCH_HAS_PMEM_API if X86_64
select ARCH_HAS_REFCOUNT
select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64
@@ -62,6 +63,7 @@ config X86
select ARCH_HAS_SG_CHAIN
select ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_HAS_STRICT_MODULE_RWX
+ select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARCH_HAS_ZONE_DEVICE if X86_64
select ARCH_HAVE_NMI_SAFE_CMPXCHG
@@ -322,7 +324,7 @@ config X86_64_SMP
config X86_32_LAZY_GS
def_bool y
- depends on X86_32 && !CC_STACKPROTECTOR
+ depends on X86_32 && CC_STACKPROTECTOR_NONE
config ARCH_SUPPORTS_UPROBES
def_bool y
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index 2a35b1e0fb90..abee6d2b9311 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -566,6 +566,11 @@ restore_all:
.Lrestore_nocheck:
RESTORE_REGS 4 # skip orig_eax/error_code
.Lirq_return:
+ /*
+ * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization
+ * when returning from IPI handler and when returning from
+ * scheduler to user-space.
+ */
INTERRUPT_RETURN
.section .fixup, "ax"
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index c752abe89d80..4a9bef6aca34 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -691,6 +691,10 @@ GLOBAL(restore_regs_and_return_to_kernel)
POP_EXTRA_REGS
POP_C_REGS
addq $8, %rsp /* skip regs->orig_ax */
+ /*
+ * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization
+ * when returning from IPI handler.
+ */
INTERRUPT_RETURN
ENTRY(native_iret)
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index 8e4ea143ed96..78f91ec1056e 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -93,7 +93,8 @@ struct amd_nb {
PERF_SAMPLE_ID | PERF_SAMPLE_CPU | PERF_SAMPLE_STREAM_ID | \
PERF_SAMPLE_DATA_SRC | PERF_SAMPLE_IDENTIFIER | \
PERF_SAMPLE_TRANSACTION | PERF_SAMPLE_PHYS_ADDR | \
- PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER)
+ PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER | \
+ PERF_SAMPLE_PERIOD)
#define PEBS_REGS \
(PERF_REG_X86_AX | \
diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
index 35a6bc4da8ad..cf090e584202 100644
--- a/arch/x86/include/asm/intel-family.h
+++ b/arch/x86/include/asm/intel-family.h
@@ -10,6 +10,10 @@
*
* Things ending in "2" are usually because we have no better
* name for them. There's no processor called "SILVERMONT2".
+ *
+ * While adding a new CPUID for a new microarchitecture, add a new
+ * group to keep logically sorted out in chronological order. Within
+ * that group keep the CPUID for the variants sorted by model number.
*/
#define INTEL_FAM6_CORE_YONAH 0x0E
@@ -49,6 +53,8 @@
#define INTEL_FAM6_KABYLAKE_MOBILE 0x8E
#define INTEL_FAM6_KABYLAKE_DESKTOP 0x9E
+#define INTEL_FAM6_CANNONLAKE_MOBILE 0x66
+
/* "Small Core" Processors (Atom) */
#define INTEL_FAM6_ATOM_PINEVIEW 0x1C
diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/arch/x86/include/asm/intel_pmc_ipc.h
index 528ed4be4393..9e7adcdbe031 100644
--- a/arch/x86/include/asm/intel_pmc_ipc.h
+++ b/arch/x86/include/asm/intel_pmc_ipc.h
@@ -38,6 +38,7 @@ int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
u32 *out, u32 outlen);
int intel_pmc_s0ix_counter_read(u64 *data);
int intel_pmc_gcr_read(u32 offset, u32 *data);
+int intel_pmc_gcr_read64(u32 offset, u64 *data);
int intel_pmc_gcr_write(u32 offset, u32 data);
int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val);
@@ -70,6 +71,11 @@ static inline int intel_pmc_gcr_read(u32 offset, u32 *data)
return -EINVAL;
}
+static inline int intel_pmc_gcr_read64(u32 offset, u64 *data)
+{
+ return -EINVAL;
+}
+
static inline int intel_pmc_gcr_write(u32 offset, u32 data)
{
return -EINVAL;
diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h
index b577dd0916aa..13e70da38bed 100644
--- a/arch/x86/include/asm/kasan.h
+++ b/arch/x86/include/asm/kasan.h
@@ -4,6 +4,7 @@
#include <linux/const.h>
#define KASAN_SHADOW_OFFSET _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
+#define KASAN_SHADOW_SCALE_SHIFT 3
/*
* Compiler uses shadow offset assuming that addresses start
@@ -12,12 +13,15 @@
* 'kernel address space start' >> KASAN_SHADOW_SCALE_SHIFT
*/
#define KASAN_SHADOW_START (KASAN_SHADOW_OFFSET + \
- ((-1UL << __VIRTUAL_MASK_SHIFT) >> 3))
+ ((-1UL << __VIRTUAL_MASK_SHIFT) >> \
+ KASAN_SHADOW_SCALE_SHIFT))
/*
- * 47 bits for kernel address -> (47 - 3) bits for shadow
- * 56 bits for kernel address -> (56 - 3) bits for shadow
+ * 47 bits for kernel address -> (47 - KASAN_SHADOW_SCALE_SHIFT) bits for shadow
+ * 56 bits for kernel address -> (56 - KASAN_SHADOW_SCALE_SHIFT) bits for shadow
*/
-#define KASAN_SHADOW_END (KASAN_SHADOW_START + (1ULL << (__VIRTUAL_MASK_SHIFT - 3)))
+#define KASAN_SHADOW_END (KASAN_SHADOW_START + \
+ (1ULL << (__VIRTUAL_MASK_SHIFT - \
+ KASAN_SHADOW_SCALE_SHIFT)))
#ifndef __ASSEMBLY__
diff --git a/arch/x86/include/asm/pmc_core.h b/arch/x86/include/asm/pmc_core.h
deleted file mode 100644
index d4855f11136d..000000000000
--- a/arch/x86/include/asm/pmc_core.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Intel Core SoC Power Management Controller Header File
- *
- * Copyright (c) 2016, Intel Corporation.
- * All Rights Reserved.
- *
- * Authors: Rajneesh Bhardwaj <rajneesh.bhardwaj@intel.com>
- * Vishwanath Somayaji <vishwanath.somayaji@intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- */
-
-#ifndef _ASM_PMC_CORE_H
-#define _ASM_PMC_CORE_H
-
-/* API to read SLP_S0_RESIDENCY counter */
-int intel_pmc_slp_s0_counter_read(u32 *data);
-
-#endif /* _ASM_PMC_CORE_H */
diff --git a/arch/x86/include/asm/sync_core.h b/arch/x86/include/asm/sync_core.h
new file mode 100644
index 000000000000..c67caafd3381
--- /dev/null
+++ b/arch/x86/include/asm/sync_core.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_SYNC_CORE_H
+#define _ASM_X86_SYNC_CORE_H
+
+#include <linux/preempt.h>
+#include <asm/processor.h>
+#include <asm/cpufeature.h>
+
+/*
+ * Ensure that a core serializing instruction is issued before returning
+ * to user-mode. x86 implements return to user-space through sysexit,
+ * sysrel, and sysretq, which are not core serializing.
+ */
+static inline void sync_core_before_usermode(void)
+{
+ /* With PTI, we unconditionally serialize before running user code. */
+ if (static_cpu_has(X86_FEATURE_PTI))
+ return;
+ /*
+ * Return from interrupt and NMI is done through iret, which is core
+ * serializing.
+ */
+ if (in_irq() || in_nmi())
+ return;
+ sync_core();
+}
+
+#endif /* _ASM_X86_SYNC_CORE_H */
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 135c9a7898c7..79cb066f40c0 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -829,23 +829,24 @@ void __init mem_init(void)
}
#ifdef CONFIG_MEMORY_HOTPLUG
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+ bool want_memblock)
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
- return __add_pages(nid, start_pfn, nr_pages, want_memblock);
+ return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
}
#ifdef CONFIG_MEMORY_HOTREMOVE
-int arch_remove_memory(u64 start, u64 size)
+int arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
struct zone *zone;
zone = page_zone(pfn_to_page(start_pfn));
- return __remove_pages(zone, start_pfn, nr_pages);
+ return __remove_pages(zone, start_pfn, nr_pages, altmap);
}
#endif
#endif
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 4a837289f2ad..1ab42c852069 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -772,12 +772,12 @@ static void update_end_of_memory_vars(u64 start, u64 size)
}
}
-int add_pages(int nid, unsigned long start_pfn,
- unsigned long nr_pages, bool want_memblock)
+int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
+ struct vmem_altmap *altmap, bool want_memblock)
{
int ret;
- ret = __add_pages(nid, start_pfn, nr_pages, want_memblock);
+ ret = __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
WARN_ON_ONCE(ret);
/* update max_pfn, max_low_pfn and high_memory */
@@ -787,24 +787,24 @@ int add_pages(int nid, unsigned long start_pfn,
return ret;
}
-int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock)
+int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap,
+ bool want_memblock)
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
init_memory_mapping(start, start + size);
- return add_pages(nid, start_pfn, nr_pages, want_memblock);
+ return add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
}
-EXPORT_SYMBOL_GPL(arch_add_memory);
#define PAGE_INUSE 0xFD
-static void __meminit free_pagetable(struct page *page, int order)
+static void __meminit free_pagetable(struct page *page, int order,
+ struct vmem_altmap *altmap)
{
unsigned long magic;
unsigned int nr_pages = 1 << order;
- struct vmem_altmap *altmap = to_vmem_altmap((unsigned long) page);
if (altmap) {
vmem_altmap_free(altmap, nr_pages);
@@ -826,7 +826,8 @@ static void __meminit free_pagetable(struct page *page, int order)
free_pages((unsigned long)page_address(page), order);
}
-static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
+static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd,
+ struct vmem_altmap *altmap)
{
pte_t *pte;
int i;
@@ -838,13 +839,14 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)
}
/* free a pte talbe */
- free_pagetable(pmd_page(*pmd), 0);
+ free_pagetable(pmd_page(*pmd), 0, altmap);
spin_lock(&init_mm.page_table_lock);
pmd_clear(pmd);
spin_unlock(&init_mm.page_table_lock);
}
-static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
+static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud,
+ struct vmem_altmap *altmap)
{
pmd_t *pmd;
int i;
@@ -856,13 +858,14 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)
}
/* free a pmd talbe */
- free_pagetable(pud_page(*pud), 0);
+ free_pagetable(pud_page(*pud), 0, altmap);
spin_lock(&init_mm.page_table_lock);
pud_clear(pud);
spin_unlock(&init_mm.page_table_lock);
}
-static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d)
+static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d,
+ struct vmem_altmap *altmap)
{
pud_t *pud;
int i;
@@ -874,7 +877,7 @@ static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d)
}
/* free a pud talbe */
- free_pagetable(p4d_page(*p4d), 0);
+ free_pagetable(p4d_page(*p4d), 0, altmap);
spin_lock(&init_mm.page_table_lock);
p4d_clear(p4d);
spin_unlock(&init_mm.page_table_lock);
@@ -882,7 +885,7 @@ static void __meminit free_pud_table(pud_t *pud_start, p4d_t *p4d)
static void __meminit
remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
- bool direct)
+ struct vmem_altmap *altmap, bool direct)
{
unsigned long next, pages = 0;
pte_t *pte;
@@ -913,7 +916,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
* freed when offlining, or simplely not in use.
*/
if (!direct)
- free_pagetable(pte_page(*pte), 0);
+ free_pagetable(pte_page(*pte), 0, altmap);
spin_lock(&init_mm.page_table_lock);
pte_clear(&init_mm, addr, pte);
@@ -936,7 +939,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
page_addr = page_address(pte_page(*pte));
if (!memchr_inv(page_addr, PAGE_INUSE, PAGE_SIZE)) {
- free_pagetable(pte_page(*pte), 0);
+ free_pagetable(pte_page(*pte), 0, altmap);
spin_lock(&init_mm.page_table_lock);
pte_clear(&init_mm, addr, pte);
@@ -953,7 +956,7 @@ remove_pte_table(pte_t *pte_start, unsigned long addr, unsigned long end,
static void __meminit
remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
- bool direct)
+ bool direct, struct vmem_altmap *altmap)
{
unsigned long next, pages = 0;
pte_t *pte_base;
@@ -972,7 +975,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
IS_ALIGNED(next, PMD_SIZE)) {
if (!direct)
free_pagetable(pmd_page(*pmd),
- get_order(PMD_SIZE));
+ get_order(PMD_SIZE),
+ altmap);
spin_lock(&init_mm.page_table_lock);
pmd_clear(pmd);
@@ -986,7 +990,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
if (!memchr_inv(page_addr, PAGE_INUSE,
PMD_SIZE)) {
free_pagetable(pmd_page(*pmd),
- get_order(PMD_SIZE));
+ get_order(PMD_SIZE),
+ altmap);
spin_lock(&init_mm.page_table_lock);
pmd_clear(pmd);
@@ -998,8 +1003,8 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
}
pte_base = (pte_t *)pmd_page_vaddr(*pmd);
- remove_pte_table(pte_base, addr, next, direct);
- free_pte_table(pte_base, pmd);
+ remove_pte_table(pte_base, addr, next, altmap, direct);
+ free_pte_table(pte_base, pmd, altmap);
}
/* Call free_pmd_table() in remove_pud_table(). */
@@ -1009,7 +1014,7 @@ remove_pmd_table(pmd_t *pmd_start, unsigned long addr, unsigned long end,
static void __meminit
remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
- bool direct)
+ struct vmem_altmap *altmap, bool direct)
{
unsigned long next, pages = 0;
pmd_t *pmd_base;
@@ -1028,7 +1033,8 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
IS_ALIGNED(next, PUD_SIZE)) {
if (!direct)
free_pagetable(pud_page(*pud),
- get_order(PUD_SIZE));
+ get_order(PUD_SIZE),
+ altmap);
spin_lock(&init_mm.page_table_lock);
pud_clear(pud);
@@ -1042,7 +1048,8 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
if (!memchr_inv(page_addr, PAGE_INUSE,
PUD_SIZE)) {
free_pagetable(pud_page(*pud),
- get_order(PUD_SIZE));
+ get_order(PUD_SIZE),
+ altmap);
spin_lock(&init_mm.page_table_lock);
pud_clear(pud);
@@ -1054,8 +1061,8 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
}
pmd_base = pmd_offset(pud, 0);
- remove_pmd_table(pmd_base, addr, next, direct);
- free_pmd_table(pmd_base, pud);
+ remove_pmd_table(pmd_base, addr, next, direct, altmap);
+ free_pmd_table(pmd_base, pud, altmap);
}
if (direct)
@@ -1064,7 +1071,7 @@ remove_pud_table(pud_t *pud_start, unsigned long addr, unsigned long end,
static void __meminit
remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
- bool direct)
+ struct vmem_altmap *altmap, bool direct)
{
unsigned long next, pages = 0;
pud_t *pud_base;
@@ -1080,14 +1087,14 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
BUILD_BUG_ON(p4d_large(*p4d));
pud_base = pud_offset(p4d, 0);
- remove_pud_table(pud_base, addr, next, direct);
+ remove_pud_table(pud_base, addr, next, altmap, direct);
/*
* For 4-level page tables we do not want to free PUDs, but in the
* 5-level case we should free them. This code will have to change
* to adapt for boot-time switching between 4 and 5 level page tables.
*/
if (CONFIG_PGTABLE_LEVELS == 5)
- free_pud_table(pud_base, p4d);
+ free_pud_table(pud_base, p4d, altmap);
}
if (direct)
@@ -1096,7 +1103,8 @@ remove_p4d_table(p4d_t *p4d_start, unsigned long addr, unsigned long end,
/* start and end are both virtual address. */
static void __meminit
-remove_pagetable(unsigned long start, unsigned long end, bool direct)
+remove_pagetable(unsigned long start, unsigned long end, bool direct,
+ struct vmem_altmap *altmap)
{
unsigned long next;
unsigned long addr;
@@ -1111,15 +1119,16 @@ remove_pagetable(unsigned long start, unsigned long end, bool direct)
continue;
p4d = p4d_offset(pgd, 0);
- remove_p4d_table(p4d, addr, next, direct);
+ remove_p4d_table(p4d, addr, next, altmap, direct);
}
flush_tlb_all();
}
-void __ref vmemmap_free(unsigned long start, unsigned long end)
+void __ref vmemmap_free(unsigned long start, unsigned long end,
+ struct vmem_altmap *altmap)
{
- remove_pagetable(start, end, false);
+ remove_pagetable(start, end, false, altmap);
}
#ifdef CONFIG_MEMORY_HOTREMOVE
@@ -1129,24 +1138,22 @@ kernel_physical_mapping_remove(unsigned long start, unsigned long end)
start = (unsigned long)__va(start);
end = (unsigned long)__va(end);
- remove_pagetable(start, end, true);
+ remove_pagetable(start, end, true, NULL);
}
-int __ref arch_remove_memory(u64 start, u64 size)
+int __ref arch_remove_memory(u64 start, u64 size, struct vmem_altmap *altmap)
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
struct page *page = pfn_to_page(start_pfn);
- struct vmem_altmap *altmap;
struct zone *zone;
int ret;
/* With altmap the first mapped page is offset from @start */
- altmap = to_vmem_altmap((unsigned long) page);
if (altmap)
page += vmem_altmap_offset(altmap);
zone = page_zone(page);
- ret = __remove_pages(zone, start_pfn, nr_pages);
+ ret = __remove_pages(zone, start_pfn, nr_pages, altmap);
WARN_ON_ONCE(ret);
kernel_physical_mapping_remove(start, start + size);
@@ -1378,7 +1385,10 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start,
if (pmd_none(*pmd)) {
void *p;
- p = __vmemmap_alloc_block_buf(PMD_SIZE, node, altmap);
+ if (altmap)
+ p = altmap_alloc_block_buf(PMD_SIZE, altmap);
+ else
+ p = vmemmap_alloc_block_buf(PMD_SIZE, node);
if (p) {
pte_t entry;
@@ -1411,9 +1421,9 @@ static int __meminit vmemmap_populate_hugepages(unsigned long start,
return 0;
}
-int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node)
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+ struct vmem_altmap *altmap)
{
- struct vmem_altmap *altmap = to_vmem_altmap(start);
int err;
if (boot_cpu_has(X86_FEATURE_PSE))
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 012d02624848..8dcc0607f805 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -229,6 +229,12 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
#endif
this_cpu_write(cpu_tlbstate.is_lazy, false);
+ /*
+ * The membarrier system call requires a full memory barrier and
+ * core serialization before returning to user-space, after
+ * storing to rq->curr. Writing to CR3 provides that full
+ * memory barrier and core serializing instruction.
+ */
if (real_prev == next) {
VM_WARN_ON(this_cpu_read(cpu_tlbstate.ctxs[prev_asid].ctx_id) !=
next->context.ctx_id);
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 0452629148be..52e55108404e 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -839,7 +839,8 @@ static void __init pirq_find_router(struct irq_router *r)
DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for [%04x:%04x]\n",
rt->rtr_vendor, rt->rtr_device);
- pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn);
+ pirq_router_dev = pci_get_domain_bus_and_slot(0, rt->rtr_bus,
+ rt->rtr_devfn);
if (!pirq_router_dev) {
DBG(KERN_DEBUG "PCI: Interrupt router not found at "
"%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn);
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index c4b3646bd04c..9542a746dc50 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -409,10 +409,8 @@ int __init pci_xen_init(void)
pcibios_enable_irq = xen_pcifront_enable_irq;
pcibios_disable_irq = NULL;
-#ifdef CONFIG_ACPI
/* Keep ACPI out of the picture */
- acpi_noirq = 1;
-#endif
+ acpi_noirq_set();
#ifdef CONFIG_PCI_MSI
x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
diff --git a/drivers/Makefile b/drivers/Makefile
index 7a0438744053..24cd47014657 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -16,10 +16,7 @@ obj-$(CONFIG_PINCTRL) += pinctrl/
obj-$(CONFIG_GPIOLIB) += gpio/
obj-y += pwm/
-obj-$(CONFIG_PCI) += pci/
-obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/
-# PCI dwc controller drivers
-obj-y += pci/dwc/
+obj-y += pci/
obj-$(CONFIG_PARISC) += parisc/
obj-$(CONFIG_RAPIDIO) += rapidio/
diff --git a/drivers/acpi/acpi_lpit.c b/drivers/acpi/acpi_lpit.c
index e94e478dd18b..cf4fc0161164 100644
--- a/drivers/acpi/acpi_lpit.c
+++ b/drivers/acpi/acpi_lpit.c
@@ -100,6 +100,7 @@ int lpit_read_residency_count_address(u64 *address)
return 0;
}
+EXPORT_SYMBOL_GPL(lpit_read_residency_count_address);
static void lpit_update_residency(struct lpit_residency_info *info,
struct acpi_lpit_native *lpit_native)
diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index abeb4df4f22e..bbe48ad20886 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -838,6 +838,18 @@ static bool add_flush(struct acpi_nfit_desc *acpi_desc,
return true;
}
+static bool add_platform_cap(struct acpi_nfit_desc *acpi_desc,
+ struct acpi_nfit_capabilities *pcap)
+{
+ struct device *dev = acpi_desc->dev;
+ u32 mask;
+
+ mask = (1 << (pcap->highest_capability + 1)) - 1;
+ acpi_desc->platform_cap = pcap->capabilities & mask;
+ dev_dbg(dev, "%s: cap: %#x\n", __func__, acpi_desc->platform_cap);
+ return true;
+}
+
static void *add_table(struct acpi_nfit_desc *acpi_desc,
struct nfit_table_prev *prev, void *table, const void *end)
{
@@ -883,6 +895,10 @@ static void *add_table(struct acpi_nfit_desc *acpi_desc,
case ACPI_NFIT_TYPE_SMBIOS:
dev_dbg(dev, "%s: smbios\n", __func__);
break;
+ case ACPI_NFIT_TYPE_CAPABILITIES:
+ if (!add_platform_cap(acpi_desc, table))
+ return err;
+ break;
default:
dev_err(dev, "unknown table '%d' parsing nfit\n", hdr->type);
break;
@@ -1867,6 +1883,9 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc)
struct kernfs_node *nfit_kernfs;
nvdimm = nfit_mem->nvdimm;
+ if (!nvdimm)
+ continue;
+
nfit_kernfs = sysfs_get_dirent(nvdimm_kobj(nvdimm)->sd, "nfit");
if (nfit_kernfs)
nfit_mem->flags_attr = sysfs_get_dirent(nfit_kernfs,
@@ -2656,6 +2675,12 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc,
else
ndr_desc->numa_node = NUMA_NO_NODE;
+ if(acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_CACHE_FLUSH)
+ set_bit(ND_REGION_PERSIST_CACHE, &ndr_desc->flags);
+
+ if (acpi_desc->platform_cap & ACPI_NFIT_CAPABILITY_MEM_FLUSH)
+ set_bit(ND_REGION_PERSIST_MEMCTRL, &ndr_desc->flags);
+
list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) {
struct acpi_nfit_memory_map *memdev = nfit_memdev->memdev;
struct nd_mapping_desc *mapping;
@@ -3464,6 +3489,7 @@ static __init int nfit_init(void)
BUILD_BUG_ON(sizeof(struct acpi_nfit_smbios) != 9);
BUILD_BUG_ON(sizeof(struct acpi_nfit_control_region) != 80);
BUILD_BUG_ON(sizeof(struct acpi_nfit_data_region) != 40);
+ BUILD_BUG_ON(sizeof(struct acpi_nfit_capabilities) != 16);
guid_parse(UUID_VOLATILE_MEMORY, &nfit_uuid[NFIT_SPA_VOLATILE]);
guid_parse(UUID_PERSISTENT_MEMORY, &nfit_uuid[NFIT_SPA_PM]);
diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
index f0cf18b2da8b..50d36e166d70 100644
--- a/drivers/acpi/nfit/nfit.h
+++ b/drivers/acpi/nfit/nfit.h
@@ -202,6 +202,7 @@ struct acpi_nfit_desc {
unsigned long dimm_cmd_force_en;
unsigned long bus_cmd_force_en;
unsigned long bus_nfit_cmd_force_en;
+ unsigned int platform_cap;
int (*blk_do_io)(struct nd_blk_region *ndbr, resource_size_t dpa,
void *iobuf, u64 len, int rw);
};
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index d19cd88ed2d3..0b122f903b8a 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -466,7 +466,8 @@ static void ali_init_chipset(struct pci_dev *pdev)
tmp |= 0x01; /* CD_ROM enable for DMA */
pci_write_config_byte(pdev, 0x53, tmp);
}
- north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+ north = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus), 0,
+ PCI_DEVFN(0, 0));
if (north && north->vendor == PCI_VENDOR_ID_AL && ali_isa_bridge) {
/* Configure the ALi bridge logic. For non ALi rely on BIOS.
Set the south bridge enable bit */
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 728075214959..f781eff7d23e 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -268,17 +268,17 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
void *AllocationPointer = NULL;
void *ScatterGatherCPU = NULL;
dma_addr_t ScatterGatherDMA;
- struct pci_pool *ScatterGatherPool;
+ struct dma_pool *ScatterGatherPool;
void *RequestSenseCPU = NULL;
dma_addr_t RequestSenseDMA;
- struct pci_pool *RequestSensePool = NULL;
+ struct dma_pool *RequestSensePool = NULL;
if (Controller->FirmwareType == DAC960_V1_Controller)
{
CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker);
CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize;
- ScatterGatherPool = pci_pool_create("DAC960_V1_ScatterGather",
- Controller->PCIDevice,
+ ScatterGatherPool = dma_pool_create("DAC960_V1_ScatterGather",
+ &Controller->PCIDevice->dev,
DAC960_V1_ScatterGatherLimit * sizeof(DAC960_V1_ScatterGatherSegment_T),
sizeof(DAC960_V1_ScatterGatherSegment_T), 0);
if (ScatterGatherPool == NULL)
@@ -290,18 +290,18 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
{
CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker);
CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize;
- ScatterGatherPool = pci_pool_create("DAC960_V2_ScatterGather",
- Controller->PCIDevice,
+ ScatterGatherPool = dma_pool_create("DAC960_V2_ScatterGather",
+ &Controller->PCIDevice->dev,
DAC960_V2_ScatterGatherLimit * sizeof(DAC960_V2_ScatterGatherSegment_T),
sizeof(DAC960_V2_ScatterGatherSegment_T), 0);
if (ScatterGatherPool == NULL)
return DAC960_Failure(Controller,
"AUXILIARY STRUCTURE CREATION (SG)");
- RequestSensePool = pci_pool_create("DAC960_V2_RequestSense",
- Controller->PCIDevice, sizeof(DAC960_SCSI_RequestSense_T),
+ RequestSensePool = dma_pool_create("DAC960_V2_RequestSense",
+ &Controller->PCIDevice->dev, sizeof(DAC960_SCSI_RequestSense_T),
sizeof(int), 0);
if (RequestSensePool == NULL) {
- pci_pool_destroy(ScatterGatherPool);
+ dma_pool_destroy(ScatterGatherPool);
return DAC960_Failure(Controller,
"AUXILIARY STRUCTURE CREATION (SG)");
}
@@ -335,16 +335,16 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
Command->Next = Controller->FreeCommands;
Controller->FreeCommands = Command;
Controller->Commands[CommandIdentifier-1] = Command;
- ScatterGatherCPU = pci_pool_alloc(ScatterGatherPool, GFP_ATOMIC,
+ ScatterGatherCPU = dma_pool_alloc(ScatterGatherPool, GFP_ATOMIC,
&ScatterGatherDMA);
if (ScatterGatherCPU == NULL)
return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
if (RequestSensePool != NULL) {
- RequestSenseCPU = pci_pool_alloc(RequestSensePool, GFP_ATOMIC,
+ RequestSenseCPU = dma_pool_alloc(RequestSensePool, GFP_ATOMIC,
&RequestSenseDMA);
if (RequestSenseCPU == NULL) {
- pci_pool_free(ScatterGatherPool, ScatterGatherCPU,
+ dma_pool_free(ScatterGatherPool, ScatterGatherCPU,
ScatterGatherDMA);
return DAC960_Failure(Controller,
"AUXILIARY STRUCTURE CREATION");
@@ -379,8 +379,8 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
{
int i;
- struct pci_pool *ScatterGatherPool = Controller->ScatterGatherPool;
- struct pci_pool *RequestSensePool = NULL;
+ struct dma_pool *ScatterGatherPool = Controller->ScatterGatherPool;
+ struct dma_pool *RequestSensePool = NULL;
void *ScatterGatherCPU;
dma_addr_t ScatterGatherDMA;
void *RequestSenseCPU;
@@ -411,9 +411,9 @@ static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
RequestSenseDMA = Command->V2.RequestSenseDMA;
}
if (ScatterGatherCPU != NULL)
- pci_pool_free(ScatterGatherPool, ScatterGatherCPU, ScatterGatherDMA);
+ dma_pool_free(ScatterGatherPool, ScatterGatherCPU, ScatterGatherDMA);
if (RequestSenseCPU != NULL)
- pci_pool_free(RequestSensePool, RequestSenseCPU, RequestSenseDMA);
+ dma_pool_free(RequestSensePool, RequestSenseCPU, RequestSenseDMA);
if ((Command->CommandIdentifier
% Controller->CommandAllocationGroupSize) == 1) {
@@ -437,13 +437,11 @@ static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
Controller->CurrentStatusBuffer = NULL;
}
- if (ScatterGatherPool != NULL)
- pci_pool_destroy(ScatterGatherPool);
+ dma_pool_destroy(ScatterGatherPool);
if (Controller->FirmwareType == DAC960_V1_Controller)
return;
- if (RequestSensePool != NULL)
- pci_pool_destroy(RequestSensePool);
+ dma_pool_destroy(RequestSensePool);
for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
kfree(Controller->V2.LogicalDeviceInformation[i]);
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h
index 6a6226a2b932..21aff470d268 100644
--- a/drivers/block/DAC960.h
+++ b/drivers/block/DAC960.h
@@ -2316,7 +2316,7 @@ typedef struct DAC960_Controller
bool SuppressEnclosureMessages;
struct timer_list MonitoringTimer;
struct gendisk *disks[DAC960_MaxLogicalDrives];
- struct pci_pool *ScatterGatherPool;
+ struct dma_pool *ScatterGatherPool;
DAC960_Command_T *FreeCommands;
unsigned char *CombinedStatusBuffer;
unsigned char *CurrentStatusBuffer;
@@ -2429,7 +2429,7 @@ typedef struct DAC960_Controller
bool NeedDeviceSerialNumberInformation;
bool StartLogicalDeviceInformationScan;
bool StartPhysicalDeviceInformationScan;
- struct pci_pool *RequestSensePool;
+ struct dma_pool *RequestSensePool;
dma_addr_t FirstCommandMailboxDMA;
DAC960_V2_CommandMailbox_T *FirstCommandMailbox;
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 828b34445203..623205bcd04a 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -340,11 +340,17 @@ static int agp_nvidia_probe(struct pci_dev *pdev,
u8 cap_ptr;
nvidia_private.dev_1 =
- pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1));
+ pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
+ (unsigned int)pdev->bus->number,
+ PCI_DEVFN(0, 1));
nvidia_private.dev_2 =
- pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2));
+ pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
+ (unsigned int)pdev->bus->number,
+ PCI_DEVFN(0, 2));
nvidia_private.dev_3 =
- pci_get_bus_and_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0));
+ pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
+ (unsigned int)pdev->bus->number,
+ PCI_DEVFN(30, 0));
if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) {
printk(KERN_INFO PFX "Detected an NVIDIA nForce/nForce2 "
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index 03be4ac79b0d..4dbdd3bc9bb8 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -474,7 +474,8 @@ static int agp_serverworks_probe(struct pci_dev *pdev,
}
/* Everything is on func 1 here so we are hardcoding function one */
- bridge_dev = pci_get_bus_and_slot((unsigned int)pdev->bus->number,
+ bridge_dev = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
+ (unsigned int)pdev->bus->number,
PCI_DEVFN(0, 1));
if (!bridge_dev) {
dev_info(&pdev->dev, "can't find secondary device\n");
diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile
index cd47b0664c2b..1456e4cdb562 100644
--- a/drivers/clk/ingenic/Makefile
+++ b/drivers/clk/ingenic/Makefile
@@ -1,3 +1,4 @@
obj-y += cgu.o
obj-$(CONFIG_MACH_JZ4740) += jz4740-cgu.o
+obj-$(CONFIG_MACH_JZ4770) += jz4770-cgu.o
obj-$(CONFIG_MACH_JZ4780) += jz4780-cgu.o
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
index ab393637f7b0..56a712c9075f 100644
--- a/drivers/clk/ingenic/cgu.c
+++ b/drivers/clk/ingenic/cgu.c
@@ -100,15 +100,13 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
n += pll_info->n_offset;
od_enc = ctl >> pll_info->od_shift;
od_enc &= GENMASK(pll_info->od_bits - 1, 0);
- bypass = !!(ctl & BIT(pll_info->bypass_bit));
+ bypass = !pll_info->no_bypass_bit &&
+ !!(ctl & BIT(pll_info->bypass_bit));
enable = !!(ctl & BIT(pll_info->enable_bit));
if (bypass)
return parent_rate;
- if (!enable)
- return 0;
-
for (od = 0; od < pll_info->od_max; od++) {
if (pll_info->od_encoding[od] == od_enc)
break;
@@ -152,17 +150,25 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
return div_u64((u64)parent_rate * m, n * od);
}
-static long
-ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
- unsigned long *prate)
+static inline const struct ingenic_cgu_clk_info *to_clk_info(
+ struct ingenic_clk *ingenic_clk)
{
- struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
struct ingenic_cgu *cgu = ingenic_clk->cgu;
const struct ingenic_cgu_clk_info *clk_info;
clk_info = &cgu->clock_info[ingenic_clk->idx];
BUG_ON(clk_info->type != CGU_CLK_PLL);
+ return clk_info;
+}
+
+static long
+ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
+ unsigned long *prate)
+{
+ struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
+
return ingenic_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL);
}
@@ -170,19 +176,14 @@ static int
ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
unsigned long parent_rate)
{
- const unsigned timeout = 100;
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
struct ingenic_cgu *cgu = ingenic_clk->cgu;
- const struct ingenic_cgu_clk_info *clk_info;
- const struct ingenic_cgu_pll_info *pll_info;
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
+ const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
unsigned long rate, flags;
- unsigned m, n, od, i;
+ unsigned int m, n, od;
u32 ctl;
- clk_info = &cgu->clock_info[ingenic_clk->idx];
- BUG_ON(clk_info->type != CGU_CLK_PLL);
- pll_info = &clk_info->pll;
-
rate = ingenic_pll_calc(clk_info, req_rate, parent_rate,
&m, &n, &od);
if (rate != req_rate)
@@ -201,6 +202,26 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
ctl &= ~(GENMASK(pll_info->od_bits - 1, 0) << pll_info->od_shift);
ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift;
+ writel(ctl, cgu->base + pll_info->reg);
+ spin_unlock_irqrestore(&cgu->lock, flags);
+
+ return 0;
+}
+
+static int ingenic_pll_enable(struct clk_hw *hw)
+{
+ struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+ struct ingenic_cgu *cgu = ingenic_clk->cgu;
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
+ const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
+ const unsigned int timeout = 100;
+ unsigned long flags;
+ unsigned int i;
+ u32 ctl;
+
+ spin_lock_irqsave(&cgu->lock, flags);
+ ctl = readl(cgu->base + pll_info->reg);
+
ctl &= ~BIT(pll_info->bypass_bit);
ctl |= BIT(pll_info->enable_bit);
@@ -222,10 +243,48 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
return 0;
}
+static void ingenic_pll_disable(struct clk_hw *hw)
+{
+ struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+ struct ingenic_cgu *cgu = ingenic_clk->cgu;
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
+ const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
+ unsigned long flags;
+ u32 ctl;
+
+ spin_lock_irqsave(&cgu->lock, flags);
+ ctl = readl(cgu->base + pll_info->reg);
+
+ ctl &= ~BIT(pll_info->enable_bit);
+
+ writel(ctl, cgu->base + pll_info->reg);
+ spin_unlock_irqrestore(&cgu->lock, flags);
+}
+
+static int ingenic_pll_is_enabled(struct clk_hw *hw)
+{
+ struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+ struct ingenic_cgu *cgu = ingenic_clk->cgu;
+ const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
+ const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
+ unsigned long flags;
+ u32 ctl;
+
+ spin_lock_irqsave(&cgu->lock, flags);
+ ctl = readl(cgu->base + pll_info->reg);
+ spin_unlock_irqrestore(&cgu->lock, flags);
+
+ return !!(ctl & BIT(pll_info->enable_bit));
+}
+
static const struct clk_ops ingenic_pll_ops = {
.recalc_rate = ingenic_pll_recalc_rate,
.round_rate = ingenic_pll_round_rate,
.set_rate = ingenic_pll_set_rate,
+
+ .enable = ingenic_pll_enable,
+ .disable = ingenic_pll_disable,
+ .is_enabled = ingenic_pll_is_enabled,
};
/*
@@ -328,6 +387,8 @@ ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
div *= clk_info->div.div;
rate /= div;
+ } else if (clk_info->type & CGU_CLK_FIXDIV) {
+ rate /= clk_info->fixdiv.div;
}
return rate;
@@ -598,6 +659,7 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
}
} else if (caps & CGU_CLK_PLL) {
clk_init.ops = &ingenic_pll_ops;
+ clk_init.flags |= CLK_SET_RATE_GATE;
caps &= ~CGU_CLK_PLL;
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
index e78b586536ea..9da34910bd80 100644
--- a/drivers/clk/ingenic/cgu.h
+++ b/drivers/clk/ingenic/cgu.h
@@ -48,6 +48,7 @@
* @bypass_bit: the index of the bypass bit in the PLL control register
* @enable_bit: the index of the enable bit in the PLL control register
* @stable_bit: the index of the stable bit in the PLL control register
+ * @no_bypass_bit: if set, the PLL has no bypass functionality
*/
struct ingenic_cgu_pll_info {
unsigned reg;
@@ -58,6 +59,7 @@ struct ingenic_cgu_pll_info {
u8 bypass_bit;
u8 enable_bit;
u8 stable_bit;
+ bool no_bypass_bit;
};
/**
@@ -120,7 +122,7 @@ struct ingenic_cgu_gate_info {
* @clk_ops: custom clock operation callbacks
*/
struct ingenic_cgu_custom_info {
- struct clk_ops *clk_ops;
+ const struct clk_ops *clk_ops;
};
/**
diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c
new file mode 100644
index 000000000000..c78d369b9403
--- /dev/null
+++ b/drivers/clk/ingenic/jz4770-cgu.c
@@ -0,0 +1,483 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * JZ4770 SoC CGU driver
+ * Copyright 2018, Paul Cercueil <paul@crapouillou.net>
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/jz4770-cgu.h>
+#include "cgu.h"
+
+/*
+ * CPM registers offset address definition
+ */
+#define CGU_REG_CPCCR 0x00
+#define CGU_REG_LCR 0x04
+#define CGU_REG_CPPCR0 0x10
+#define CGU_REG_CLKGR0 0x20
+#define CGU_REG_OPCR 0x24
+#define CGU_REG_CLKGR1 0x28
+#define CGU_REG_CPPCR1 0x30
+#define CGU_REG_USBPCR1 0x48
+#define CGU_REG_USBCDR 0x50
+#define CGU_REG_I2SCDR 0x60
+#define CGU_REG_LPCDR 0x64
+#define CGU_REG_MSC0CDR 0x68
+#define CGU_REG_UHCCDR 0x6c
+#define CGU_REG_SSICDR 0x74
+#define CGU_REG_CIMCDR 0x7c
+#define CGU_REG_GPSCDR 0x80
+#define CGU_REG_PCMCDR 0x84
+#define CGU_REG_GPUCDR 0x88
+#define CGU_REG_MSC1CDR 0xA4
+#define CGU_REG_MSC2CDR 0xA8
+#define CGU_REG_BCHCDR 0xAC
+
+/* bits within the LCR register */
+#define LCR_LPM BIT(0) /* Low Power Mode */
+
+/* bits within the OPCR register */
+#define OPCR_SPENDH BIT(5) /* UHC PHY suspend */
+#define OPCR_SPENDN BIT(7) /* OTG PHY suspend */
+
+/* bits within the USBPCR1 register */
+#define USBPCR1_UHC_POWER BIT(5) /* UHC PHY power down */
+
+static struct ingenic_cgu *cgu;
+
+static int jz4770_uhc_phy_enable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1;
+
+ writel(readl(reg_opcr) & ~OPCR_SPENDH, reg_opcr);
+ writel(readl(reg_usbpcr1) | USBPCR1_UHC_POWER, reg_usbpcr1);
+ return 0;
+}
+
+static void jz4770_uhc_phy_disable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1;
+
+ writel(readl(reg_usbpcr1) & ~USBPCR1_UHC_POWER, reg_usbpcr1);
+ writel(readl(reg_opcr) | OPCR_SPENDH, reg_opcr);
+}
+
+static int jz4770_uhc_phy_is_enabled(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+ void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1;
+
+ return !(readl(reg_opcr) & OPCR_SPENDH) &&
+ (readl(reg_usbpcr1) & USBPCR1_UHC_POWER);
+}
+
+static const struct clk_ops jz4770_uhc_phy_ops = {
+ .enable = jz4770_uhc_phy_enable,
+ .disable = jz4770_uhc_phy_disable,
+ .is_enabled = jz4770_uhc_phy_is_enabled,
+};
+
+static int jz4770_otg_phy_enable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+
+ writel(readl(reg_opcr) | OPCR_SPENDN, reg_opcr);
+
+ /* Wait for the clock to be stable */
+ udelay(50);
+ return 0;
+}
+
+static void jz4770_otg_phy_disable(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+
+ writel(readl(reg_opcr) & ~OPCR_SPENDN, reg_opcr);
+}
+
+static int jz4770_otg_phy_is_enabled(struct clk_hw *hw)
+{
+ void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
+
+ return !!(readl(reg_opcr) & OPCR_SPENDN);
+}
+
+static const struct clk_ops jz4770_otg_phy_ops = {
+ .enable = jz4770_otg_phy_enable,
+ .disable = jz4770_otg_phy_disable,
+ .is_enabled = jz4770_otg_phy_is_enabled,
+};
+
+static const s8 pll_od_encoding[8] = {
+ 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
+};
+
+static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
+
+ /* External clocks */
+
+ [JZ4770_CLK_EXT] = { "ext", CGU_CLK_EXT },
+ [JZ4770_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT },
+
+ /* PLLs */
+
+ [JZ4770_CLK_PLL0] = {
+ "pll0", CGU_CLK_PLL,
+ .parents = { JZ4770_CLK_EXT },
+ .pll = {
+ .reg = CGU_REG_CPPCR0,
+ .m_shift = 24,
+ .m_bits = 7,
+ .m_offset = 1,
+ .n_shift = 18,
+ .n_bits = 5,
+ .n_offset = 1,
+ .od_shift = 16,
+ .od_bits = 2,
+ .od_max = 8,
+ .od_encoding = pll_od_encoding,
+ .bypass_bit = 9,
+ .enable_bit = 8,
+ .stable_bit = 10,
+ },
+ },
+
+ [JZ4770_CLK_PLL1] = {
+ /* TODO: PLL1 can depend on PLL0 */
+ "pll1", CGU_CLK_PLL,
+ .parents = { JZ4770_CLK_EXT },
+ .pll = {
+ .reg = CGU_REG_CPPCR1,
+ .m_shift = 24,
+ .m_bits = 7,
+ .m_offset = 1,
+ .n_shift = 18,
+ .n_bits = 5,
+ .n_offset = 1,
+ .od_shift = 16,
+ .od_bits = 2,
+ .od_max = 8,
+ .od_encoding = pll_od_encoding,
+ .enable_bit = 7,
+ .stable_bit = 6,
+ .no_bypass_bit = true,
+ },
+ },
+
+ /* Main clocks */
+
+ [JZ4770_CLK_CCLK] = {
+ "cclk", CGU_CLK_DIV,
+ .parents = { JZ4770_CLK_PLL0, },
+ .div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
+ },
+ [JZ4770_CLK_H0CLK] = {
+ "h0clk", CGU_CLK_DIV,
+ .parents = { JZ4770_CLK_PLL0, },
+ .div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
+ },
+ [JZ4770_CLK_H1CLK] = {
+ "h1clk", CGU_CLK_DIV | CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_PLL0, },
+ .div = { CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1 },
+ .gate = { CGU_REG_LCR, 30 },
+ },
+ [JZ4770_CLK_H2CLK] = {
+ "h2clk", CGU_CLK_DIV,
+ .parents = { JZ4770_CLK_PLL0, },
+ .div = { CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1 },
+ },
+ [JZ4770_CLK_C1CLK] = {
+ "c1clk", CGU_CLK_DIV,
+ .parents = { JZ4770_CLK_PLL0, },
+ .div = { CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1 },
+ },
+ [JZ4770_CLK_PCLK] = {
+ "pclk", CGU_CLK_DIV,
+ .parents = { JZ4770_CLK_PLL0, },
+ .div = { CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1 },
+ },
+
+ /* Those divided clocks can connect to PLL0 or PLL1 */
+
+ [JZ4770_CLK_MMC0_MUX] = {
+ "mmc0_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+ .mux = { CGU_REG_MSC0CDR, 30, 1 },
+ .div = { CGU_REG_MSC0CDR, 0, 1, 7, -1, -1, 31 },
+ .gate = { CGU_REG_MSC0CDR, 31 },
+ },
+ [JZ4770_CLK_MMC1_MUX] = {
+ "mmc1_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+ .mux = { CGU_REG_MSC1CDR, 30, 1 },
+ .div = { CGU_REG_MSC1CDR, 0, 1, 7, -1, -1, 31 },
+ .gate = { CGU_REG_MSC1CDR, 31 },
+ },
+ [JZ4770_CLK_MMC2_MUX] = {
+ "mmc2_mux", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+ .mux = { CGU_REG_MSC2CDR, 30, 1 },
+ .div = { CGU_REG_MSC2CDR, 0, 1, 7, -1, -1, 31 },
+ .gate = { CGU_REG_MSC2CDR, 31 },
+ },
+ [JZ4770_CLK_CIM] = {
+ "cim", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+ .mux = { CGU_REG_CIMCDR, 31, 1 },
+ .div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 26 },
+ },
+ [JZ4770_CLK_UHC] = {
+ "uhc", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+ .mux = { CGU_REG_UHCCDR, 29, 1 },
+ .div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 24 },
+ },
+ [JZ4770_CLK_GPU] = {
+ "gpu", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, -1 },
+ .mux = { CGU_REG_GPUCDR, 31, 1 },
+ .div = { CGU_REG_GPUCDR, 0, 1, 3, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 9 },
+ },
+ [JZ4770_CLK_BCH] = {
+ "bch", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+ .mux = { CGU_REG_BCHCDR, 31, 1 },
+ .div = { CGU_REG_BCHCDR, 0, 1, 3, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 1 },
+ },
+ [JZ4770_CLK_LPCLK_MUX] = {
+ "lpclk", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+ .mux = { CGU_REG_LPCDR, 29, 1 },
+ .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 28 },
+ },
+ [JZ4770_CLK_GPS] = {
+ "gps", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, },
+ .mux = { CGU_REG_GPSCDR, 31, 1 },
+ .div = { CGU_REG_GPSCDR, 0, 1, 4, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 22 },
+ },
+
+ /* Those divided clocks can connect to EXT, PLL0 or PLL1 */
+
+ [JZ4770_CLK_SSI_MUX] = {
+ "ssi_mux", CGU_CLK_DIV | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_EXT, -1,
+ JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 },
+ .mux = { CGU_REG_SSICDR, 30, 2 },
+ .div = { CGU_REG_SSICDR, 0, 1, 6, -1, -1, -1 },
+ },
+ [JZ4770_CLK_PCM_MUX] = {
+ "pcm_mux", CGU_CLK_DIV | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_EXT, -1,
+ JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 },
+ .mux = { CGU_REG_PCMCDR, 30, 2 },
+ .div = { CGU_REG_PCMCDR, 0, 1, 9, -1, -1, -1 },
+ },
+ [JZ4770_CLK_I2S] = {
+ "i2s", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_EXT, -1,
+ JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 },
+ .mux = { CGU_REG_I2SCDR, 30, 2 },
+ .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR1, 13 },
+ },
+ [JZ4770_CLK_OTG] = {
+ "usb", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_EXT, -1,
+ JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 },
+ .mux = { CGU_REG_USBCDR, 30, 2 },
+ .div = { CGU_REG_USBCDR, 0, 1, 8, -1, -1, -1 },
+ .gate = { CGU_REG_CLKGR0, 2 },
+ },
+
+ /* Gate-only clocks */
+
+ [JZ4770_CLK_SSI0] = {
+ "ssi0", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_SSI_MUX, },
+ .gate = { CGU_REG_CLKGR0, 4 },
+ },
+ [JZ4770_CLK_SSI1] = {
+ "ssi1", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_SSI_MUX, },
+ .gate = { CGU_REG_CLKGR0, 19 },
+ },
+ [JZ4770_CLK_SSI2] = {
+ "ssi2", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_SSI_MUX, },
+ .gate = { CGU_REG_CLKGR0, 20 },
+ },
+ [JZ4770_CLK_PCM0] = {
+ "pcm0", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_PCM_MUX, },
+ .gate = { CGU_REG_CLKGR1, 8 },
+ },
+ [JZ4770_CLK_PCM1] = {
+ "pcm1", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_PCM_MUX, },
+ .gate = { CGU_REG_CLKGR1, 10 },
+ },
+ [JZ4770_CLK_DMA] = {
+ "dma", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_H2CLK, },
+ .gate = { CGU_REG_CLKGR0, 21 },
+ },
+ [JZ4770_CLK_I2C0] = {
+ "i2c0", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_EXT, },
+ .gate = { CGU_REG_CLKGR0, 5 },
+ },
+ [JZ4770_CLK_I2C1] = {
+ "i2c1", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_EXT, },
+ .gate = { CGU_REG_CLKGR0, 6 },
+ },
+ [JZ4770_CLK_I2C2] = {
+ "i2c2", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_EXT, },
+ .gate = { CGU_REG_CLKGR1, 15 },
+ },
+ [JZ4770_CLK_UART0] = {
+ "uart0", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_EXT, },
+ .gate = { CGU_REG_CLKGR0, 15 },
+ },
+ [JZ4770_CLK_UART1] = {
+ "uart1", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_EXT, },
+ .gate = { CGU_REG_CLKGR0, 16 },
+ },
+ [JZ4770_CLK_UART2] = {
+ "uart2", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_EXT, },
+ .gate = { CGU_REG_CLKGR0, 17 },
+ },
+ [JZ4770_CLK_UART3] = {
+ "uart3", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_EXT, },
+ .gate = { CGU_REG_CLKGR0, 18 },
+ },
+ [JZ4770_CLK_IPU] = {
+ "ipu", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_H0CLK, },
+ .gate = { CGU_REG_CLKGR0, 29 },
+ },
+ [JZ4770_CLK_ADC] = {
+ "adc", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_EXT, },
+ .gate = { CGU_REG_CLKGR0, 14 },
+ },
+ [JZ4770_CLK_AIC] = {
+ "aic", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_EXT, },
+ .gate = { CGU_REG_CLKGR0, 8 },
+ },
+ [JZ4770_CLK_AUX] = {
+ "aux", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_C1CLK, },
+ .gate = { CGU_REG_CLKGR1, 14 },
+ },
+ [JZ4770_CLK_VPU] = {
+ "vpu", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_H1CLK, },
+ .gate = { CGU_REG_CLKGR1, 7 },
+ },
+ [JZ4770_CLK_MMC0] = {
+ "mmc0", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_MMC0_MUX, },
+ .gate = { CGU_REG_CLKGR0, 3 },
+ },
+ [JZ4770_CLK_MMC1] = {
+ "mmc1", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_MMC1_MUX, },
+ .gate = { CGU_REG_CLKGR0, 11 },
+ },
+ [JZ4770_CLK_MMC2] = {
+ "mmc2", CGU_CLK_GATE,
+ .parents = { JZ4770_CLK_MMC2_MUX, },
+ .gate = { CGU_REG_CLKGR0, 12 },
+ },
+
+ /* Custom clocks */
+
+ [JZ4770_CLK_UHC_PHY] = {
+ "uhc_phy", CGU_CLK_CUSTOM,
+ .parents = { JZ4770_CLK_UHC, -1, -1, -1 },
+ .custom = { &jz4770_uhc_phy_ops },
+ },
+ [JZ4770_CLK_OTG_PHY] = {
+ "usb_phy", CGU_CLK_CUSTOM,
+ .parents = { JZ4770_CLK_OTG, -1, -1, -1 },
+ .custom = { &jz4770_otg_phy_ops },
+ },
+
+ [JZ4770_CLK_EXT512] = {
+ "ext/512", CGU_CLK_FIXDIV,
+ .parents = { JZ4770_CLK_EXT },
+ .fixdiv = { 512 },
+ },
+
+ [JZ4770_CLK_RTC] = {
+ "rtc", CGU_CLK_MUX,
+ .parents = { JZ4770_CLK_EXT512, JZ4770_CLK_OSC32K, },
+ .mux = { CGU_REG_OPCR, 2, 1},
+ },
+};
+
+#if IS_ENABLED(CONFIG_PM_SLEEP)
+static int jz4770_cgu_pm_suspend(void)
+{
+ u32 val;
+
+ val = readl(cgu->base + CGU_REG_LCR);
+ writel(val | LCR_LPM, cgu->base + CGU_REG_LCR);
+ return 0;
+}
+
+static void jz4770_cgu_pm_resume(void)
+{
+ u32 val;
+
+ val = readl(cgu->base + CGU_REG_LCR);
+ writel(val & ~LCR_LPM, cgu->base + CGU_REG_LCR);
+}
+
+static struct syscore_ops jz4770_cgu_pm_ops = {
+ .suspend = jz4770_cgu_pm_suspend,
+ .resume = jz4770_cgu_pm_resume,
+};
+#endif /* CONFIG_PM_SLEEP */
+
+static void __init jz4770_cgu_init(struct device_node *np)
+{
+ int retval;
+
+ cgu = ingenic_cgu_new(jz4770_cgu_clocks,
+ ARRAY_SIZE(jz4770_cgu_clocks), np);
+ if (!cgu)
+ pr_err("%s: failed to initialise CGU\n", __func__);
+
+ retval = ingenic_cgu_register_clocks(cgu);
+ if (retval)
+ pr_err("%s: failed to register CGU Clocks\n", __func__);
+
+#if IS_ENABLED(CONFIG_PM_SLEEP)
+ register_syscore_ops(&jz4770_cgu_pm_ops);
+#endif
+}
+
+/* We only probe via devicetree, no need for a platform driver */
+CLK_OF_DECLARE(jz4770_cgu, "ingenic,jz4770-cgu", jz4770_cgu_init);
diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c
index ac3585ed8228..6427be117ff1 100644
--- a/drivers/clk/ingenic/jz4780-cgu.c
+++ b/drivers/clk/ingenic/jz4780-cgu.c
@@ -203,7 +203,7 @@ static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate,
return 0;
}
-static struct clk_ops jz4780_otg_phy_ops = {
+static const struct clk_ops jz4780_otg_phy_ops = {
.get_parent = jz4780_otg_phy_get_parent,
.set_parent = jz4780_otg_phy_set_parent,
diff --git a/drivers/dax/device.c b/drivers/dax/device.c
index 7b0bf825c4e7..2137dbc29877 100644
--- a/drivers/dax/device.c
+++ b/drivers/dax/device.c
@@ -133,7 +133,7 @@ struct dax_region *alloc_dax_region(struct device *parent, int region_id,
dax_region->base = addr;
if (sysfs_create_groups(&parent->kobj, dax_region_attribute_groups)) {
kfree(dax_region);
- return NULL;;
+ return NULL;
}
kref_get(&dax_region->kref);
diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
index 8d8c852ba8f2..31b6ecce4c64 100644
--- a/drivers/dax/pmem.c
+++ b/drivers/dax/pmem.c
@@ -21,6 +21,7 @@
struct dax_pmem {
struct device *dev;
struct percpu_ref ref;
+ struct dev_pagemap pgmap;
struct completion cmp;
};
@@ -69,20 +70,23 @@ static int dax_pmem_probe(struct device *dev)
struct nd_namespace_common *ndns;
struct nd_dax *nd_dax = to_nd_dax(dev);
struct nd_pfn *nd_pfn = &nd_dax->nd_pfn;
- struct vmem_altmap __altmap, *altmap = NULL;
ndns = nvdimm_namespace_common_probe(dev);
if (IS_ERR(ndns))
return PTR_ERR(ndns);
nsio = to_nd_namespace_io(&ndns->dev);
+ dax_pmem = devm_kzalloc(dev, sizeof(*dax_pmem), GFP_KERNEL);
+ if (!dax_pmem)
+ return -ENOMEM;
+
/* parse the 'pfn' info block via ->rw_bytes */
rc = devm_nsio_enable(dev, nsio);
if (rc)
return rc;
- altmap = nvdimm_setup_pfn(nd_pfn, &res, &__altmap);
- if (IS_ERR(altmap))
- return PTR_ERR(altmap);
+ rc = nvdimm_setup_pfn(nd_pfn, &dax_pmem->pgmap);
+ if (rc)
+ return rc;
devm_nsio_disable(dev, nsio);
pfn_sb = nd_pfn->pfn_sb;
@@ -94,10 +98,6 @@ static int dax_pmem_probe(struct device *dev)
return -EBUSY;
}
- dax_pmem = devm_kzalloc(dev, sizeof(*dax_pmem), GFP_KERNEL);
- if (!dax_pmem)
- return -ENOMEM;
-
dax_pmem->dev = dev;
init_completion(&dax_pmem->cmp);
rc = percpu_ref_init(&dax_pmem->ref, dax_pmem_percpu_release, 0,
@@ -110,7 +110,8 @@ static int dax_pmem_probe(struct device *dev)
if (rc)
return rc;
- addr = devm_memremap_pages(dev, &res, &dax_pmem->ref, altmap);
+ dax_pmem->pgmap.ref = &dax_pmem->ref;
+ addr = devm_memremap_pages(dev, &dax_pmem->pgmap);
if (IS_ERR(addr))
return PTR_ERR(addr);
@@ -120,6 +121,7 @@ static int dax_pmem_probe(struct device *dev)
return rc;
/* adjust the dax_region resource to the start of data */
+ memcpy(&res, &dax_pmem->pgmap.res, sizeof(res));
res.start += le64_to_cpu(pfn_sb->dataoff);
rc = sscanf(dev_name(&ndns->dev), "namespace%d.%d", &region_id, &id);
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 3ec804672601..473af694ad1c 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -15,6 +15,7 @@
#include <linux/mount.h>
#include <linux/magic.h>
#include <linux/genhd.h>
+#include <linux/pfn_t.h>
#include <linux/cdev.h>
#include <linux/hash.h>
#include <linux/slab.h>
@@ -123,6 +124,15 @@ int __bdev_dax_supported(struct super_block *sb, int blocksize)
return len < 0 ? len : -EIO;
}
+ if ((IS_ENABLED(CONFIG_FS_DAX_LIMITED) && pfn_t_special(pfn))
+ || pfn_t_devmap(pfn))
+ /* pass */;
+ else {
+ pr_debug("VFS (%s): error: dax support not enabled\n",
+ sb->s_id);
+ return -EOPNOTSUPP;
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(__bdev_dax_supported);
diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c
index e22957665808..60a8f1363a10 100644
--- a/drivers/firmware/edd.c
+++ b/drivers/firmware/edd.c
@@ -669,10 +669,10 @@ edd_get_pci_dev(struct edd_device *edev)
struct edd_info *info = edd_dev_get_info(edev);
if (edd_dev_is_type(edev, "PCI") || edd_dev_is_type(edev, "XPRS")) {
- return pci_get_bus_and_slot(info->params.interface_path.pci.bus,
- PCI_DEVFN(info->params.interface_path.pci.slot,
- info->params.interface_path.pci.
- function));
+ return pci_get_domain_bus_and_slot(0,
+ info->params.interface_path.pci.bus,
+ PCI_DEVFN(info->params.interface_path.pci.slot,
+ info->params.interface_path.pci.function));
}
return NULL;
}
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index 14042a64bdd5..6bc8e6640d71 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -719,8 +719,9 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header,
* executes only devices which are in domain 0. Furthermore, the
* iBFT spec doesn't have a domain id field :-(
*/
- pci_dev = pci_get_bus_and_slot((nic->pci_bdf & 0xff00) >> 8,
- (nic->pci_bdf & 0xff));
+ pci_dev = pci_get_domain_bus_and_slot(0,
+ (nic->pci_bdf & 0xff00) >> 8,
+ (nic->pci_bdf & 0xff));
if (pci_dev) {
rc = sysfs_create_link(&boot_kobj->kobj,
&pci_dev->dev.kobj, "device");
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index 8745971a7680..3a3bf752e03a 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -185,21 +185,22 @@ static int cdv_backlight_init(struct drm_device *dev)
* for this and the MID devices.
*/
-static inline u32 CDV_MSG_READ32(uint port, uint offset)
+static inline u32 CDV_MSG_READ32(int domain, uint port, uint offset)
{
int mcr = (0x10<<24) | (port << 16) | (offset << 8);
uint32_t ret_val = 0;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
pci_write_config_dword(pci_root, 0xD0, mcr);
pci_read_config_dword(pci_root, 0xD4, &ret_val);
pci_dev_put(pci_root);
return ret_val;
}
-static inline void CDV_MSG_WRITE32(uint port, uint offset, u32 value)
+static inline void CDV_MSG_WRITE32(int domain, uint port, uint offset,
+ u32 value)
{
int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
pci_write_config_dword(pci_root, 0xD4, value);
pci_write_config_dword(pci_root, 0xD0, mcr);
pci_dev_put(pci_root);
@@ -216,11 +217,12 @@ static void cdv_init_pm(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
u32 pwr_cnt;
+ int domain = pci_domain_nr(dev->pdev->bus);
int i;
- dev_priv->apm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
+ dev_priv->apm_base = CDV_MSG_READ32(domain, PSB_PUNIT_PORT,
PSB_APMBA) & 0xFFFF;
- dev_priv->ospm_base = CDV_MSG_READ32(PSB_PUNIT_PORT,
+ dev_priv->ospm_base = CDV_MSG_READ32(domain, PSB_PUNIT_PORT,
PSB_OSPMBA) & 0xFFFF;
/* Power status */
@@ -251,7 +253,7 @@ static void cdv_errata(struct drm_device *dev)
* Bonus Launch to work around the issue, by degrading
* performance.
*/
- CDV_MSG_WRITE32(3, 0x30, 0x08027108);
+ CDV_MSG_WRITE32(pci_domain_nr(dev->pdev->bus), 3, 0x30, 0x08027108);
}
/**
diff --git a/drivers/gpu/drm/gma500/gma_device.c b/drivers/gpu/drm/gma500/gma_device.c
index 4a295f9ba067..a7fb6de4dd15 100644
--- a/drivers/gpu/drm/gma500/gma_device.c
+++ b/drivers/gpu/drm/gma500/gma_device.c
@@ -19,7 +19,9 @@
void gma_get_core_freq(struct drm_device *dev)
{
uint32_t clock;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ struct pci_dev *pci_root =
+ pci_get_domain_bus_and_slot(pci_domain_nr(dev->pdev->bus),
+ 0, 0);
struct drm_psb_private *dev_priv = dev->dev_private;
/*pci_write_config_dword(pci_root, 0xD4, 0x00C32004);*/
diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c
index 1fa163373a47..7171b7475f58 100644
--- a/drivers/gpu/drm/gma500/mid_bios.c
+++ b/drivers/gpu/drm/gma500/mid_bios.c
@@ -32,7 +32,9 @@
static void mid_get_fuse_settings(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ struct pci_dev *pci_root =
+ pci_get_domain_bus_and_slot(pci_domain_nr(dev->pdev->bus),
+ 0, 0);
uint32_t fuse_value = 0;
uint32_t fuse_value_tmp = 0;
@@ -104,7 +106,9 @@ static void mid_get_fuse_settings(struct drm_device *dev)
static void mid_get_pci_revID(struct drm_psb_private *dev_priv)
{
uint32_t platform_rev_id = 0;
- struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
+ int domain = pci_domain_nr(dev_priv->dev->pdev->bus);
+ struct pci_dev *pci_gfx_root =
+ pci_get_domain_bus_and_slot(domain, 0, PCI_DEVFN(2, 0));
if (pci_gfx_root == NULL) {
WARN_ON(1);
@@ -281,7 +285,9 @@ static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
u32 addr;
u8 __iomem *vbt_virtual;
struct mid_vbt_header vbt_header;
- struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
+ struct pci_dev *pci_gfx_root =
+ pci_get_domain_bus_and_slot(pci_domain_nr(dev->pdev->bus),
+ 0, PCI_DEVFN(2, 0));
int ret = -1;
/* Get the address of the platform config vbt */
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 38d09d4b3ed5..ac32ab5aa002 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -248,7 +248,11 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
goto out_err;
if (IS_MRST(dev)) {
- dev_priv->aux_pdev = pci_get_bus_and_slot(0, PCI_DEVFN(3, 0));
+ int domain = pci_domain_nr(dev->pdev->bus);
+
+ dev_priv->aux_pdev =
+ pci_get_domain_bus_and_slot(domain, 0,
+ PCI_DEVFN(3, 0));
if (dev_priv->aux_pdev) {
resource_start = pci_resource_start(dev_priv->aux_pdev,
@@ -268,7 +272,9 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
}
dev_priv->gmbus_reg = dev_priv->aux_reg;
- dev_priv->lpc_pdev = pci_get_bus_and_slot(0, PCI_DEVFN(31, 0));
+ dev_priv->lpc_pdev =
+ pci_get_domain_bus_and_slot(domain, 0,
+ PCI_DEVFN(31, 0));
if (dev_priv->lpc_pdev) {
pci_read_config_word(dev_priv->lpc_pdev, PSB_LPC_GBA,
&dev_priv->lpc_gpio_base);
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index 4918efc57b7a..e8300f509023 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -780,38 +780,40 @@ extern const struct psb_ops cdv_chip_ops;
extern int drm_idle_check_interval;
/* Utilities */
-static inline u32 MRST_MSG_READ32(uint port, uint offset)
+static inline u32 MRST_MSG_READ32(int domain, uint port, uint offset)
{
int mcr = (0xD0<<24) | (port << 16) | (offset << 8);
uint32_t ret_val = 0;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
pci_write_config_dword(pci_root, 0xD0, mcr);
pci_read_config_dword(pci_root, 0xD4, &ret_val);
pci_dev_put(pci_root);
return ret_val;
}
-static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value)
+static inline void MRST_MSG_WRITE32(int domain, uint port, uint offset,
+ u32 value)
{
int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
pci_write_config_dword(pci_root, 0xD4, value);
pci_write_config_dword(pci_root, 0xD0, mcr);
pci_dev_put(pci_root);
}
-static inline u32 MDFLD_MSG_READ32(uint port, uint offset)
+static inline u32 MDFLD_MSG_READ32(int domain, uint port, uint offset)
{
int mcr = (0x10<<24) | (port << 16) | (offset << 8);
uint32_t ret_val = 0;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
pci_write_config_dword(pci_root, 0xD0, mcr);
pci_read_config_dword(pci_root, 0xD4, &ret_val);
pci_dev_put(pci_root);
return ret_val;
}
-static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value)
+static inline void MDFLD_MSG_WRITE32(int domain, uint port, uint offset,
+ u32 value)
{
int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 0, 0);
pci_write_config_dword(pci_root, 0xD4, value);
pci_write_config_dword(pci_root, 0xD0, mcr);
pci_dev_put(pci_root);
diff --git a/drivers/gpu/drm/nouveau/dispnv04/arb.c b/drivers/gpu/drm/nouveau/dispnv04/arb.c
index 90075b676256..c79160c37f84 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/arb.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/arb.c
@@ -213,8 +213,10 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp,
if ((dev->pdev->device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ ||
(dev->pdev->device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) {
uint32_t type;
+ int domain = pci_domain_nr(dev->pdev->bus);
- pci_read_config_dword(pci_get_bus_and_slot(0, 1), 0x7c, &type);
+ pci_read_config_dword(pci_get_domain_bus_and_slot(domain, 0, 1),
+ 0x7c, &type);
sim_data.memory_type = (type >> 12) & 1;
sim_data.memory_width = 64;
diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.c b/drivers/gpu/drm/nouveau/dispnv04/hw.c
index b98599002831..0c9bdf023f5b 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/hw.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c
@@ -216,12 +216,15 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype)
{
struct nvkm_pll_vals pllvals;
int ret;
+ int domain;
+
+ domain = pci_domain_nr(dev->pdev->bus);
if (plltype == PLL_MEMORY &&
(dev->pdev->device & 0x0ff0) == CHIPSET_NFORCE) {
uint32_t mpllP;
-
- pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP);
+ pci_read_config_dword(pci_get_domain_bus_and_slot(domain, 0, 3),
+ 0x6c, &mpllP);
mpllP = (mpllP >> 8) & 0xf;
if (!mpllP)
mpllP = 4;
@@ -232,7 +235,8 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype)
(dev->pdev->device & 0xff0) == CHIPSET_NFORCE2) {
uint32_t clock;
- pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock);
+ pci_read_config_dword(pci_get_domain_bus_and_slot(domain, 0, 5),
+ 0x4c, &clock);
return clock / 1000;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 56fe261b6268..3e293029e3a6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -524,7 +524,8 @@ nouveau_get_hdmi_dev(struct nouveau_drm *drm)
}
/* subfunction one is a hdmi audio device? */
- drm->hdmi_device = pci_get_bus_and_slot((unsigned int)pdev->bus->number,
+ drm->hdmi_device = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus),
+ (unsigned int)pdev->bus->number,
PCI_DEVFN(PCI_SLOT(pdev->devfn), 1));
if (!drm->hdmi_device) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
index 4c07d10bb976..18241c6ba5fa 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
@@ -28,8 +28,16 @@ nv1a_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
{
struct pci_dev *bridge;
u32 mem, mib;
+ int domain = 0;
+ struct pci_dev *pdev = NULL;
- bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1));
+ if (dev_is_pci(fb->subdev.device->dev))
+ pdev = to_pci_dev(fb->subdev.device->dev);
+
+ if (pdev)
+ domain = pci_domain_nr(pdev->bus);
+
+ bridge = pci_get_domain_bus_and_slot(domain, 0, PCI_DEVFN(0, 1));
if (!bridge) {
nvkm_error(&fb->subdev, "no bridge device\n");
return -ENODEV;
diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
index 84911bdc27d1..e67f4ea28c0e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -25,6 +25,7 @@
#include <linux/clk.h>
#include <linux/mfd/syscon.h>
#include <linux/of_graph.h>
+#include <linux/pinctrl/devinfo.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index 8755df3330a0..3300dac56390 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -239,8 +239,9 @@ static u8 sl82c105_bridge_revision(struct pci_dev *dev)
/*
* The bridge should be part of the same device, but function 0.
*/
- bridge = pci_get_bus_and_slot(dev->bus->number,
- PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+ bridge = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus),
+ dev->bus->number,
+ PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
if (!bridge)
return -1;
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 5cd700421695..8517d6ea91a6 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -20,7 +20,8 @@ config INFINIBAND_USER_MAD
Userspace InfiniBand Management Datagram (MAD) support. This
is the kernel side of the userspace MAD support, which allows
userspace processes to send and receive MADs. You will also
- need libibumad from <http://www.openfabrics.org/downloads/management/>.
+ need libibumad from rdma-core
+ <https://github.com/linux-rdma/rdma-core>.
config INFINIBAND_USER_ACCESS
tristate "InfiniBand userspace access (verbs and CM)"
@@ -32,10 +33,10 @@ config INFINIBAND_USER_ACCESS
to set up connections and directly access InfiniBand
hardware for fast-path operations. You will also need
libibverbs, libibcm and a hardware driver library from
- <http://www.openfabrics.org/git/>.
+ rdma-core <https://github.com/linux-rdma/rdma-core>.
config INFINIBAND_EXP_USER_ACCESS
- bool "Allow experimental support for Infiniband ABI"
+ bool "Enable the full uverbs ioctl interface (EXPERIMENTAL)"
depends on INFINIBAND_USER_ACCESS
---help---
IOCTL based ABI support for Infiniband. This allows userspace
diff --git a/drivers/infiniband/core/nldev.c b/drivers/infiniband/core/nldev.c
index fa8655e3b3ed..5326a684555f 100644
--- a/drivers/infiniband/core/nldev.c
+++ b/drivers/infiniband/core/nldev.c
@@ -499,8 +499,10 @@ static int nldev_res_get_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
return -EINVAL;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
- if (!msg)
+ if (!msg) {
+ ret = -ENOMEM;
goto err;
+ }
nlh = nlmsg_put(msg, NETLINK_CB(skb).portid, nlh->nlmsg_seq,
RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_RES_GET),
diff --git a/drivers/infiniband/core/uverbs_std_types.c b/drivers/infiniband/core/uverbs_std_types.c
index b571176babbe..cab0ac3556eb 100644
--- a/drivers/infiniband/core/uverbs_std_types.c
+++ b/drivers/infiniband/core/uverbs_std_types.c
@@ -316,7 +316,7 @@ static int uverbs_create_cq_handler(struct ib_device *ib_dev,
cq->uobject = &obj->uobject;
cq->comp_handler = ib_uverbs_comp_handler;
cq->event_handler = ib_uverbs_cq_event_handler;
- cq->cq_context = &ev_file->ev_queue;
+ cq->cq_context = ev_file ? &ev_file->ev_queue : NULL;
obj->uobject.object = cq;
obj->uobject.user_handle = user_handle;
atomic_set(&cq->usecnt, 0);
diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
index 9b8fa77b8831..ae9e9ff54826 100644
--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -1314,7 +1314,7 @@ int bnxt_re_destroy_srq(struct ib_srq *ib_srq)
return rc;
}
- if (srq->umem && !IS_ERR(srq->umem))
+ if (srq->umem)
ib_umem_release(srq->umem);
kfree(srq);
atomic_dec(&rdev->srq_count);
@@ -1430,11 +1430,8 @@ struct ib_srq *bnxt_re_create_srq(struct ib_pd *ib_pd,
return &srq->ib_srq;
fail:
- if (udata && srq->umem && !IS_ERR(srq->umem)) {
+ if (srq->umem)
ib_umem_release(srq->umem);
- srq->umem = NULL;
- }
-
kfree(srq);
exit:
return ERR_PTR(rc);
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
index 8b5f11ac0e42..1b0e94697fe3 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -557,8 +557,10 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,
srq->swq = kcalloc(srq->hwq.max_elements, sizeof(*srq->swq),
GFP_KERNEL);
- if (!srq->swq)
+ if (!srq->swq) {
+ rc = -ENOMEM;
goto fail;
+ }
RCFW_CMD_PREP(req, CREATE_SRQ, cmd_flags);
diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c
index ad37d54affcc..539a5d44e6db 100644
--- a/drivers/infiniband/hw/bnxt_re/qplib_res.c
+++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c
@@ -705,12 +705,8 @@ static int bnxt_qplib_alloc_dpi_tbl(struct bnxt_qplib_res *res,
dpit->max = dbr_len / PAGE_SIZE;
dpit->app_tbl = kcalloc(dpit->max, sizeof(void *), GFP_KERNEL);
- if (!dpit->app_tbl) {
- pci_iounmap(res->pdev, dpit->dbr_bar_reg_iomem);
- dev_err(&res->pdev->dev,
- "QPLIB: DPI app tbl allocation failed");
- return -ENOMEM;
- }
+ if (!dpit->app_tbl)
+ goto unmap_io;
bytes = dpit->max >> 3;
if (!bytes)
@@ -718,18 +714,18 @@ static int bnxt_qplib_alloc_dpi_tbl(struct bnxt_qplib_res *res,
dpit->tbl = kmalloc(bytes, GFP_KERNEL);
if (!dpit->tbl) {
- pci_iounmap(res->pdev, dpit->dbr_bar_reg_iomem);
kfree(dpit->app_tbl);
dpit->app_tbl = NULL;
- dev_err(&res->pdev->dev,
- "QPLIB: DPI tbl allocation failed for size = %d",
- bytes);
- return -ENOMEM;
+ goto unmap_io;
}
memset((u8 *)dpit->tbl, 0xFF, bytes);
return 0;
+
+unmap_io:
+ pci_iounmap(res->pdev, dpit->dbr_bar_reg_iomem);
+ return -ENOMEM;
}
/* PKEYs */
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
index 6660f920f42e..e6a60fa59f2b 100644
--- a/drivers/infiniband/hw/hfi1/chip.c
+++ b/drivers/infiniband/hw/hfi1/chip.c
@@ -1083,6 +1083,7 @@ static int qos_rmt_entries(struct hfi1_devdata *dd, unsigned int *mp,
static void clear_full_mgmt_pkey(struct hfi1_pportdata *ppd);
static int wait_link_transfer_active(struct hfi1_devdata *dd, int wait_ms);
static void clear_rsm_rule(struct hfi1_devdata *dd, u8 rule_index);
+static void update_xmit_counters(struct hfi1_pportdata *ppd, u16 link_width);
/*
* Error interrupt table entry. This is used as input to the interrupt
@@ -6905,6 +6906,32 @@ void handle_freeze(struct work_struct *work)
/* no longer frozen */
}
+/**
+ * update_xmit_counters - update PortXmitWait/PortVlXmitWait
+ * counters.
+ * @ppd: info of physical Hfi port
+ * @link_width: new link width after link up or downgrade
+ *
+ * Update the PortXmitWait and PortVlXmitWait counters after
+ * a link up or downgrade event to reflect a link width change.
+ */
+static void update_xmit_counters(struct hfi1_pportdata *ppd, u16 link_width)
+{
+ int i;
+ u16 tx_width;
+ u16 link_speed;
+
+ tx_width = tx_link_width(link_width);
+ link_speed = get_link_speed(ppd->link_speed_active);
+
+ /*
+ * There are C_VL_COUNT number of PortVLXmitWait counters.
+ * Adding 1 to C_VL_COUNT to include the PortXmitWait counter.
+ */
+ for (i = 0; i < C_VL_COUNT + 1; i++)
+ get_xmit_wait_counters(ppd, tx_width, link_speed, i);
+}
+
/*
* Handle a link up interrupt from the 8051.
*
@@ -7526,18 +7553,29 @@ void handle_verify_cap(struct work_struct *work)
set_link_state(ppd, HLS_GOING_UP);
}
-/*
- * Apply the link width downgrade enabled policy against the current active
- * link widths.
+/**
+ * apply_link_downgrade_policy - Apply the link width downgrade enabled
+ * policy against the current active link widths.
+ * @ppd: info of physical Hfi port
+ * @refresh_widths: True indicates link downgrade event
+ * @return: True indicates a successful link downgrade. False indicates
+ * link downgrade event failed and the link will bounce back to
+ * default link width.
*
- * Called when the enabled policy changes or the active link widths change.
+ * Called when the enabled policy changes or the active link widths
+ * change.
+ * Refresh_widths indicates that a link downgrade occurred. The
+ * link_downgraded variable is set by refresh_widths and
+ * determines the success/failure of the policy application.
*/
-void apply_link_downgrade_policy(struct hfi1_pportdata *ppd, int refresh_widths)
+bool apply_link_downgrade_policy(struct hfi1_pportdata *ppd,
+ bool refresh_widths)
{
int do_bounce = 0;
int tries;
u16 lwde;
u16 tx, rx;
+ bool link_downgraded = refresh_widths;
/* use the hls lock to avoid a race with actual link up */
tries = 0;
@@ -7571,6 +7609,7 @@ retry:
ppd->link_width_downgrade_rx_active == 0) {
/* the 8051 reported a dead link as a downgrade */
dd_dev_err(ppd->dd, "Link downgrade is really a link down, ignoring\n");
+ link_downgraded = false;
} else if (lwde == 0) {
/* downgrade is disabled */
@@ -7587,6 +7626,7 @@ retry:
ppd->link_width_downgrade_tx_active,
ppd->link_width_downgrade_rx_active);
do_bounce = 1;
+ link_downgraded = false;
}
} else if ((lwde & ppd->link_width_downgrade_tx_active) == 0 ||
(lwde & ppd->link_width_downgrade_rx_active) == 0) {
@@ -7598,6 +7638,7 @@ retry:
lwde, ppd->link_width_downgrade_tx_active,
ppd->link_width_downgrade_rx_active);
do_bounce = 1;
+ link_downgraded = false;
}
done:
@@ -7609,6 +7650,8 @@ done:
set_link_state(ppd, HLS_DN_OFFLINE);
start_link(ppd);
}
+
+ return link_downgraded;
}
/*
@@ -7622,7 +7665,8 @@ void handle_link_downgrade(struct work_struct *work)
link_downgrade_work);
dd_dev_info(ppd->dd, "8051: Link width downgrade\n");
- apply_link_downgrade_policy(ppd, 1);
+ if (apply_link_downgrade_policy(ppd, true))
+ update_xmit_counters(ppd, ppd->link_width_downgrade_tx_active);
}
static char *dcc_err_string(char *buf, int buf_len, u64 flags)
@@ -8264,8 +8308,8 @@ static irqreturn_t sdma_interrupt(int irq, void *data)
/* handle the interrupt(s) */
sdma_engine_interrupt(sde, status);
} else {
- dd_dev_err_ratelimited(dd, "SDMA engine %u interrupt, but no status bits set\n",
- sde->this_idx);
+ dd_dev_info_ratelimited(dd, "SDMA engine %u interrupt, but no status bits set\n",
+ sde->this_idx);
}
return IRQ_HANDLED;
}
@@ -10597,6 +10641,14 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
add_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
handle_linkup_change(dd, 1);
+
+ /*
+ * After link up, a new link width will have been set.
+ * Update the xmit counters with regards to the new
+ * link width.
+ */
+ update_xmit_counters(ppd, ppd->link_width_active);
+
ppd->host_link_state = HLS_UP_INIT;
update_statusp(ppd, IB_PORT_INIT);
break;
@@ -12960,7 +13012,14 @@ static void disable_intx(struct pci_dev *pdev)
pci_intx(pdev, 0);
}
-static void clean_up_interrupts(struct hfi1_devdata *dd)
+/**
+ * hfi1_clean_up_interrupts() - Free all IRQ resources
+ * @dd: valid device data data structure
+ *
+ * Free the MSI or INTx IRQs and assoicated PCI resources,
+ * if they have been allocated.
+ */
+void hfi1_clean_up_interrupts(struct hfi1_devdata *dd)
{
int i;
@@ -13321,7 +13380,7 @@ static int set_up_interrupts(struct hfi1_devdata *dd)
return 0;
fail:
- clean_up_interrupts(dd);
+ hfi1_clean_up_interrupts(dd);
return ret;
}
@@ -14748,7 +14807,6 @@ void hfi1_start_cleanup(struct hfi1_devdata *dd)
aspm_exit(dd);
free_cntrs(dd);
free_rcverr(dd);
- clean_up_interrupts(dd);
finish_chip_resources(dd);
}
@@ -15204,7 +15262,7 @@ bail_free_rcverr:
bail_free_cntrs:
free_cntrs(dd);
bail_clear_intr:
- clean_up_interrupts(dd);
+ hfi1_clean_up_interrupts(dd);
bail_cleanup:
hfi1_pcie_ddcleanup(dd);
bail_free:
diff --git a/drivers/infiniband/hw/hfi1/chip.h b/drivers/infiniband/hw/hfi1/chip.h
index 21fca8ec5076..c0d70f255050 100644
--- a/drivers/infiniband/hw/hfi1/chip.h
+++ b/drivers/infiniband/hw/hfi1/chip.h
@@ -736,8 +736,8 @@ int read_8051_config(struct hfi1_devdata *, u8, u8, u32 *);
int start_link(struct hfi1_pportdata *ppd);
int bringup_serdes(struct hfi1_pportdata *ppd);
void set_intr_state(struct hfi1_devdata *dd, u32 enable);
-void apply_link_downgrade_policy(struct hfi1_pportdata *ppd,
- int refresh_widths);
+bool apply_link_downgrade_policy(struct hfi1_pportdata *ppd,
+ bool refresh_widths);
void update_usrhead(struct hfi1_ctxtdata *rcd, u32 hd, u32 updegr, u32 egrhd,
u32 intr_adjust, u32 npkts);
int stop_drain_data_vls(struct hfi1_devdata *dd);
diff --git a/drivers/infiniband/hw/hfi1/debugfs.c b/drivers/infiniband/hw/hfi1/debugfs.c
index 2e6e0c516041..852173bf05d0 100644
--- a/drivers/infiniband/hw/hfi1/debugfs.c
+++ b/drivers/infiniband/hw/hfi1/debugfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2015-2017 Intel Corporation.
+ * Copyright(c) 2015-2018 Intel Corporation.
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
@@ -1201,6 +1201,13 @@ static int _fault_stats_seq_show(struct seq_file *s, void *v)
}
hfi1_rcd_put(rcd);
}
+ for_each_possible_cpu(j) {
+ struct hfi1_opcode_stats_perctx *sp =
+ per_cpu_ptr(dd->tx_opstats, j);
+
+ n_packets += sp->stats[i].n_packets;
+ n_bytes += sp->stats[i].n_bytes;
+ }
if (!n_packets && !n_bytes)
return SEQ_SKIP;
if (!ibd->fault_opcode->n_rxfaults[i] &&
diff --git a/drivers/infiniband/hw/hfi1/driver.c b/drivers/infiniband/hw/hfi1/driver.c
index 067b29f35f21..addc68e83606 100644
--- a/drivers/infiniband/hw/hfi1/driver.c
+++ b/drivers/infiniband/hw/hfi1/driver.c
@@ -256,7 +256,12 @@ static void rcv_hdrerr(struct hfi1_ctxtdata *rcd, struct hfi1_pportdata *ppd,
u32 mlid_base;
struct hfi1_ibport *ibp = rcd_to_iport(rcd);
struct hfi1_devdata *dd = ppd->dd;
- struct rvt_dev_info *rdi = &dd->verbs_dev.rdi;
+ struct hfi1_ibdev *verbs_dev = &dd->verbs_dev;
+ struct rvt_dev_info *rdi = &verbs_dev->rdi;
+
+ if ((packet->rhf & RHF_DC_ERR) &&
+ hfi1_dbg_fault_suppress_err(verbs_dev))
+ return;
if (packet->rhf & (RHF_VCRC_ERR | RHF_ICRC_ERR))
return;
@@ -634,9 +639,10 @@ next:
}
}
-static void process_rcv_qp_work(struct hfi1_ctxtdata *rcd)
+static void process_rcv_qp_work(struct hfi1_packet *packet)
{
struct rvt_qp *qp, *nqp;
+ struct hfi1_ctxtdata *rcd = packet->rcd;
/*
* Iterate over all QPs waiting to respond.
@@ -646,7 +652,8 @@ static void process_rcv_qp_work(struct hfi1_ctxtdata *rcd)
list_del_init(&qp->rspwait);
if (qp->r_flags & RVT_R_RSP_NAK) {
qp->r_flags &= ~RVT_R_RSP_NAK;
- hfi1_send_rc_ack(rcd, qp, 0);
+ packet->qp = qp;
+ hfi1_send_rc_ack(packet, 0);
}
if (qp->r_flags & RVT_R_RSP_SEND) {
unsigned long flags;
@@ -667,7 +674,7 @@ static noinline int max_packet_exceeded(struct hfi1_packet *packet, int thread)
if (thread) {
if ((packet->numpkt & (MAX_PKT_RECV_THREAD - 1)) == 0)
/* allow defered processing */
- process_rcv_qp_work(packet->rcd);
+ process_rcv_qp_work(packet);
cond_resched();
return RCV_PKT_OK;
} else {
@@ -809,7 +816,7 @@ int handle_receive_interrupt_nodma_rtail(struct hfi1_ctxtdata *rcd, int thread)
last = RCV_PKT_DONE;
process_rcv_update(last, &packet);
}
- process_rcv_qp_work(rcd);
+ process_rcv_qp_work(&packet);
rcd->head = packet.rhqoff;
bail:
finish_packet(&packet);
@@ -838,7 +845,7 @@ int handle_receive_interrupt_dma_rtail(struct hfi1_ctxtdata *rcd, int thread)
last = RCV_PKT_DONE;
process_rcv_update(last, &packet);
}
- process_rcv_qp_work(rcd);
+ process_rcv_qp_work(&packet);
rcd->head = packet.rhqoff;
bail:
finish_packet(&packet);
@@ -1068,7 +1075,7 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread)
process_rcv_update(last, &packet);
}
- process_rcv_qp_work(rcd);
+ process_rcv_qp_work(&packet);
rcd->head = packet.rhqoff;
bail:
@@ -1438,8 +1445,8 @@ static int hfi1_setup_9B_packet(struct hfi1_packet *packet)
packet->sc = hfi1_9B_get_sc5(hdr, packet->rhf);
packet->pad = ib_bth_get_pad(packet->ohdr);
packet->extra_byte = 0;
- packet->fecn = ib_bth_get_fecn(packet->ohdr);
- packet->becn = ib_bth_get_becn(packet->ohdr);
+ packet->pkey = ib_bth_get_pkey(packet->ohdr);
+ packet->migrated = ib_bth_is_migration(packet->ohdr);
return 0;
drop:
@@ -1492,8 +1499,10 @@ static int hfi1_setup_bypass_packet(struct hfi1_packet *packet)
/* Query commonly used fields from packet header */
packet->opcode = ib_bth_get_opcode(packet->ohdr);
- packet->hlen = hdr_len_by_opcode[packet->opcode] + 8 + grh_len;
- packet->payload = packet->ebuf + packet->hlen - (4 * sizeof(u32));
+ /* hdr_len_by_opcode already has an IB LRH factored in */
+ packet->hlen = hdr_len_by_opcode[packet->opcode] +
+ (LRH_16B_BYTES - LRH_9B_BYTES) + grh_len;
+ packet->payload = packet->ebuf + packet->hlen - LRH_16B_BYTES;
packet->slid = hfi1_16B_get_slid(packet->hdr);
packet->dlid = hfi1_16B_get_dlid(packet->hdr);
if (unlikely(hfi1_is_16B_mcast(packet->dlid)))
@@ -1504,8 +1513,8 @@ static int hfi1_setup_bypass_packet(struct hfi1_packet *packet)
packet->sl = ibp->sc_to_sl[packet->sc];
packet->pad = hfi1_16B_bth_get_pad(packet->ohdr);
packet->extra_byte = SIZE_OF_LT;
- packet->fecn = hfi1_16B_get_fecn(packet->hdr);
- packet->becn = hfi1_16B_get_becn(packet->hdr);
+ packet->pkey = hfi1_16B_get_pkey(packet->hdr);
+ packet->migrated = opa_bth_is_migration(packet->ohdr);
if (hfi1_bypass_ingress_pkt_check(packet))
goto drop;
@@ -1550,19 +1559,7 @@ int process_receive_ib(struct hfi1_packet *packet)
if (hfi1_setup_9B_packet(packet))
return RHF_RCV_CONTINUE;
- trace_hfi1_rcvhdr(packet->rcd->ppd->dd,
- packet->rcd->ctxt,
- rhf_err_flags(packet->rhf),
- RHF_RCV_TYPE_IB,
- packet->hlen,
- packet->tlen,
- packet->updegr,
- rhf_egr_index(packet->rhf));
-
- if (unlikely(
- (hfi1_dbg_fault_suppress_err(&packet->rcd->dd->verbs_dev) &&
- (packet->rhf & RHF_DC_ERR))))
- return RHF_RCV_CONTINUE;
+ trace_hfi1_rcvhdr(packet);
if (unlikely(rhf_err_flags(packet->rhf))) {
handle_eflags(packet);
@@ -1598,6 +1595,8 @@ int process_receive_bypass(struct hfi1_packet *packet)
if (hfi1_setup_bypass_packet(packet))
return RHF_RCV_CONTINUE;
+ trace_hfi1_rcvhdr(packet);
+
if (unlikely(rhf_err_flags(packet->rhf))) {
handle_eflags(packet);
return RHF_RCV_CONTINUE;
diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c
index bd6f03cc5ee0..d9a0f2590294 100644
--- a/drivers/infiniband/hw/hfi1/file_ops.c
+++ b/drivers/infiniband/hw/hfi1/file_ops.c
@@ -196,9 +196,6 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
if (!atomic_inc_not_zero(&dd->user_refcount))
return -ENXIO;
- /* Just take a ref now. Not all opens result in a context assign */
- kobject_get(&dd->kobj);
-
/* The real work is performed later in assign_ctxt() */
fd = kzalloc(sizeof(*fd), GFP_KERNEL);
@@ -208,6 +205,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp)
fd->mm = current->mm;
mmgrab(fd->mm);
fd->dd = dd;
+ kobject_get(&fd->dd->kobj);
fp->private_data = fd;
} else {
fp->private_data = NULL;
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h
index b42c22292597..90bc8c76d2ca 100644
--- a/drivers/infiniband/hw/hfi1/hfi.h
+++ b/drivers/infiniband/hw/hfi1/hfi.h
@@ -341,6 +341,7 @@ struct hfi1_packet {
u32 slid;
u16 tlen;
s16 etail;
+ u16 pkey;
u8 hlen;
u8 numpkt;
u8 rsize;
@@ -351,8 +352,7 @@ struct hfi1_packet {
u8 sc;
u8 sl;
u8 opcode;
- bool becn;
- bool fecn;
+ bool migrated;
};
/* Packet types */
@@ -858,6 +858,13 @@ struct hfi1_pportdata {
struct work_struct linkstate_active_work;
/* Does this port need to prescan for FECNs */
bool cc_prescan;
+ /*
+ * Sample sendWaitCnt & sendWaitVlCnt during link transition
+ * and counter request.
+ */
+ u64 port_vl_xmit_wait_last[C_VL_COUNT + 1];
+ u16 prev_link_width;
+ u64 vl_xmit_flit_cnt[C_VL_COUNT + 1];
};
typedef int (*rhf_rcv_function_ptr)(struct hfi1_packet *packet);
@@ -1779,19 +1786,15 @@ void hfi1_process_ecn_slowpath(struct rvt_qp *qp, struct hfi1_packet *pkt,
static inline bool process_ecn(struct rvt_qp *qp, struct hfi1_packet *pkt,
bool do_cnp)
{
- struct ib_other_headers *ohdr = pkt->ohdr;
-
- u32 bth1;
- bool becn = false;
- bool fecn = false;
+ bool becn;
+ bool fecn;
if (pkt->etype == RHF_RCV_TYPE_BYPASS) {
fecn = hfi1_16B_get_fecn(pkt->hdr);
becn = hfi1_16B_get_becn(pkt->hdr);
} else {
- bth1 = be32_to_cpu(ohdr->bth[1]);
- fecn = bth1 & IB_FECN_SMASK;
- becn = bth1 & IB_BECN_SMASK;
+ fecn = ib_bth_get_fecn(pkt->ohdr);
+ becn = ib_bth_get_becn(pkt->ohdr);
}
if (unlikely(fecn || becn)) {
hfi1_process_ecn_slowpath(qp, pkt, do_cnp);
@@ -1957,6 +1960,7 @@ void hfi1_verbs_unregister_sysfs(struct hfi1_devdata *dd);
int qsfp_dump(struct hfi1_pportdata *ppd, char *buf, int len);
int hfi1_pcie_init(struct pci_dev *pdev, const struct pci_device_id *ent);
+void hfi1_clean_up_interrupts(struct hfi1_devdata *dd);
void hfi1_pcie_cleanup(struct pci_dev *pdev);
int hfi1_pcie_ddinit(struct hfi1_devdata *dd, struct pci_dev *pdev);
void hfi1_pcie_ddcleanup(struct hfi1_devdata *);
@@ -2416,7 +2420,7 @@ static inline void hfi1_make_ib_hdr(struct ib_header *hdr,
static inline void hfi1_make_16b_hdr(struct hfi1_16b_header *hdr,
u32 slid, u32 dlid,
u16 len, u16 pkey,
- u8 becn, u8 fecn, u8 l4,
+ bool becn, bool fecn, u8 l4,
u8 sc)
{
u32 lrh0 = 0;
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c
index 9b128268fb28..33eba2356742 100644
--- a/drivers/infiniband/hw/hfi1/init.c
+++ b/drivers/infiniband/hw/hfi1/init.c
@@ -172,7 +172,7 @@ int hfi1_create_kctxts(struct hfi1_devdata *dd)
u16 i;
int ret;
- dd->rcd = kzalloc_node(dd->num_rcv_contexts * sizeof(*dd->rcd),
+ dd->rcd = kcalloc_node(dd->num_rcv_contexts, sizeof(*dd->rcd),
GFP_KERNEL, dd->node);
if (!dd->rcd)
return -ENOMEM;
@@ -439,15 +439,16 @@ int hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, int numa,
* The resulting value will be rounded down to the closest
* multiple of dd->rcv_entries.group_size.
*/
- rcd->egrbufs.buffers = kzalloc_node(
- rcd->egrbufs.count * sizeof(*rcd->egrbufs.buffers),
- GFP_KERNEL, numa);
+ rcd->egrbufs.buffers =
+ kcalloc_node(rcd->egrbufs.count,
+ sizeof(*rcd->egrbufs.buffers),
+ GFP_KERNEL, numa);
if (!rcd->egrbufs.buffers)
goto bail;
- rcd->egrbufs.rcvtids = kzalloc_node(
- rcd->egrbufs.count *
- sizeof(*rcd->egrbufs.rcvtids),
- GFP_KERNEL, numa);
+ rcd->egrbufs.rcvtids =
+ kcalloc_node(rcd->egrbufs.count,
+ sizeof(*rcd->egrbufs.rcvtids),
+ GFP_KERNEL, numa);
if (!rcd->egrbufs.rcvtids)
goto bail;
rcd->egrbufs.size = eager_buffer_size;
@@ -637,6 +638,15 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd,
ppd->dd = dd;
ppd->hw_pidx = hw_pidx;
ppd->port = port; /* IB port number, not index */
+ ppd->prev_link_width = LINK_WIDTH_DEFAULT;
+ /*
+ * There are C_VL_COUNT number of PortVLXmitWait counters.
+ * Adding 1 to C_VL_COUNT to include the PortXmitWait counter.
+ */
+ for (i = 0; i < C_VL_COUNT + 1; i++) {
+ ppd->port_vl_xmit_wait_last[i] = 0;
+ ppd->vl_xmit_flit_cnt[i] = 0;
+ }
default_pkey_idx = 1;
@@ -1058,8 +1068,9 @@ static void shutdown_device(struct hfi1_devdata *dd)
}
dd->flags &= ~HFI1_INITTED;
- /* mask interrupts, but not errors */
+ /* mask and clean up interrupts, but not errors */
set_intr_state(dd, 0);
+ hfi1_clean_up_interrupts(dd);
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
ppd = dd->pport + pidx;
@@ -1218,6 +1229,7 @@ static void __hfi1_free_devdata(struct kobject *kobj)
free_percpu(dd->rcv_limit);
free_percpu(dd->send_schedule);
free_percpu(dd->tx_opstats);
+ sdma_clean(dd, dd->num_sdma);
rvt_dealloc_device(&dd->verbs_dev.rdi);
}
@@ -1704,6 +1716,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dd_dev_err(dd, "Failed to create /dev devices: %d\n", -j);
if (initfail || ret) {
+ hfi1_clean_up_interrupts(dd);
stop_timers(dd);
flush_workqueue(ib_wq);
for (pidx = 0; pidx < dd->num_pports; ++pidx) {
diff --git a/drivers/infiniband/hw/hfi1/iowait.h b/drivers/infiniband/hw/hfi1/iowait.h
index 591697d85eed..3d9c32c7c340 100644
--- a/drivers/infiniband/hw/hfi1/iowait.h
+++ b/drivers/infiniband/hw/hfi1/iowait.h
@@ -371,4 +371,13 @@ static inline void iowait_starve_find_max(struct iowait *w, u8 *max,
}
}
+/**
+ * iowait_packet_queued() - determine if a packet is already built
+ * @wait: the wait structure
+ */
+static inline bool iowait_packet_queued(struct iowait *wait)
+{
+ return !list_empty(&wait->tx_head);
+}
+
#endif
diff --git a/drivers/infiniband/hw/hfi1/mad.c b/drivers/infiniband/hw/hfi1/mad.c
index 34547a48a445..e9962c65c68f 100644
--- a/drivers/infiniband/hw/hfi1/mad.c
+++ b/drivers/infiniband/hw/hfi1/mad.c
@@ -2649,6 +2649,79 @@ static void a0_portstatus(struct hfi1_pportdata *ppd,
}
}
+/**
+ * tx_link_width - convert link width bitmask to integer
+ * value representing actual link width.
+ * @link_width: width of active link
+ * @return: return index of the bit set in link_width var
+ *
+ * The function convert and return the index of bit set
+ * that indicate the current link width.
+ */
+u16 tx_link_width(u16 link_width)
+{
+ int n = LINK_WIDTH_DEFAULT;
+ u16 tx_width = n;
+
+ while (link_width && n) {
+ if (link_width & (1 << (n - 1))) {
+ tx_width = n;
+ break;
+ }
+ n--;
+ }
+
+ return tx_width;
+}
+
+/**
+ * get_xmit_wait_counters - Convert HFI 's SendWaitCnt/SendWaitVlCnt
+ * counter in unit of TXE cycle times to flit times.
+ * @ppd: info of physical Hfi port
+ * @link_width: width of active link
+ * @link_speed: speed of active link
+ * @vl: represent VL0-VL7, VL15 for PortVLXmitWait counters request
+ * and if vl value is C_VL_COUNT, it represent SendWaitCnt
+ * counter request
+ * @return: return SendWaitCnt/SendWaitVlCnt counter value per vl.
+ *
+ * Convert SendWaitCnt/SendWaitVlCnt counter from TXE cycle times to
+ * flit times. Call this function to samples these counters. This
+ * function will calculate for previous state transition and update
+ * current state at end of function using ppd->prev_link_width and
+ * ppd->port_vl_xmit_wait_last to port_vl_xmit_wait_curr and link_width.
+ */
+u64 get_xmit_wait_counters(struct hfi1_pportdata *ppd,
+ u16 link_width, u16 link_speed, int vl)
+{
+ u64 port_vl_xmit_wait_curr;
+ u64 delta_vl_xmit_wait;
+ u64 xmit_wait_val;
+
+ if (vl > C_VL_COUNT)
+ return 0;
+ if (vl < C_VL_COUNT)
+ port_vl_xmit_wait_curr =
+ read_port_cntr(ppd, C_TX_WAIT_VL, vl);
+ else
+ port_vl_xmit_wait_curr =
+ read_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL);
+
+ xmit_wait_val =
+ port_vl_xmit_wait_curr -
+ ppd->port_vl_xmit_wait_last[vl];
+ delta_vl_xmit_wait =
+ convert_xmit_counter(xmit_wait_val,
+ ppd->prev_link_width,
+ link_speed);
+
+ ppd->vl_xmit_flit_cnt[vl] += delta_vl_xmit_wait;
+ ppd->port_vl_xmit_wait_last[vl] = port_vl_xmit_wait_curr;
+ ppd->prev_link_width = link_width;
+
+ return ppd->vl_xmit_flit_cnt[vl];
+}
+
static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
struct ib_device *ibdev,
u8 port, u32 *resp_len)
@@ -2668,6 +2741,8 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
int vfi;
u64 tmp, tmp2;
+ u16 link_width;
+ u16 link_speed;
response_data_size = sizeof(struct opa_port_status_rsp) +
num_vls * sizeof(struct _vls_pctrs);
@@ -2711,8 +2786,16 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
rsp->port_multicast_rcv_pkts =
cpu_to_be64(read_dev_cntr(dd, C_DC_MC_RCV_PKTS,
CNTR_INVALID_VL));
+ /*
+ * Convert PortXmitWait counter from TXE cycle times
+ * to flit times.
+ */
+ link_width =
+ tx_link_width(ppd->link_width_downgrade_tx_active);
+ link_speed = get_link_speed(ppd->link_speed_active);
rsp->port_xmit_wait =
- cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL));
+ cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
+ link_speed, C_VL_COUNT));
rsp->port_rcv_fecn =
cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN, CNTR_INVALID_VL));
rsp->port_rcv_becn =
@@ -2777,10 +2860,14 @@ static int pma_get_opa_portstatus(struct opa_pma_mad *pmp,
rsp->vls[vfi].port_vl_xmit_pkts =
cpu_to_be64(read_port_cntr(ppd, C_TX_PKT_VL,
idx_from_vl(vl)));
-
+ /*
+ * Convert PortVlXmitWait counter from TXE cycle
+ * times to flit times.
+ */
rsp->vls[vfi].port_vl_xmit_wait =
- cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT_VL,
- idx_from_vl(vl)));
+ cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
+ link_speed,
+ idx_from_vl(vl)));
rsp->vls[vfi].port_vl_rcv_fecn =
cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN_VL,
@@ -2910,6 +2997,8 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
unsigned long vl;
u32 vl_select_mask;
int vfi;
+ u16 link_width;
+ u16 link_speed;
num_ports = be32_to_cpu(pmp->mad_hdr.attr_mod) >> 24;
num_vls = hweight32(be32_to_cpu(req->vl_select_mask));
@@ -2959,8 +3048,16 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
rsp->link_quality_indicator = cpu_to_be32((u32)lq);
pma_get_opa_port_dctrs(ibdev, rsp);
+ /*
+ * Convert PortXmitWait counter from TXE
+ * cycle times to flit times.
+ */
+ link_width =
+ tx_link_width(ppd->link_width_downgrade_tx_active);
+ link_speed = get_link_speed(ppd->link_speed_active);
rsp->port_xmit_wait =
- cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL));
+ cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
+ link_speed, C_VL_COUNT));
rsp->port_rcv_fecn =
cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN, CNTR_INVALID_VL));
rsp->port_rcv_becn =
@@ -2996,9 +3093,14 @@ static int pma_get_opa_datacounters(struct opa_pma_mad *pmp,
cpu_to_be64(read_dev_cntr(dd, C_DC_RX_PKT_VL,
idx_from_vl(vl)));
+ /*
+ * Convert PortVlXmitWait counter from TXE
+ * cycle times to flit times.
+ */
rsp->vls[vfi].port_vl_xmit_wait =
- cpu_to_be64(read_port_cntr(ppd, C_TX_WAIT_VL,
- idx_from_vl(vl)));
+ cpu_to_be64(get_xmit_wait_counters(ppd, link_width,
+ link_speed,
+ idx_from_vl(vl)));
rsp->vls[vfi].port_vl_rcv_fecn =
cpu_to_be64(read_dev_cntr(dd, C_DC_RCV_FCN_VL,
@@ -3416,9 +3518,11 @@ static int pma_set_opa_portstatus(struct opa_pma_mad *pmp,
if (counter_select & CS_PORT_MCAST_RCV_PKTS)
write_dev_cntr(dd, C_DC_MC_RCV_PKTS, CNTR_INVALID_VL, 0);
- if (counter_select & CS_PORT_XMIT_WAIT)
+ if (counter_select & CS_PORT_XMIT_WAIT) {
write_port_cntr(ppd, C_TX_WAIT, CNTR_INVALID_VL, 0);
-
+ ppd->port_vl_xmit_wait_last[C_VL_COUNT] = 0;
+ ppd->vl_xmit_flit_cnt[C_VL_COUNT] = 0;
+ }
/* ignore cs_sw_portCongestion for HFIs */
if (counter_select & CS_PORT_RCV_FECN)
@@ -3491,8 +3595,11 @@ static int pma_set_opa_portstatus(struct opa_pma_mad *pmp,
if (counter_select & CS_PORT_RCV_PKTS)
write_dev_cntr(dd, C_DC_RX_PKT_VL, idx_from_vl(vl), 0);
- if (counter_select & CS_PORT_XMIT_WAIT)
+ if (counter_select & CS_PORT_XMIT_WAIT) {
write_port_cntr(ppd, C_TX_WAIT_VL, idx_from_vl(vl), 0);
+ ppd->port_vl_xmit_wait_last[idx_from_vl(vl)] = 0;
+ ppd->vl_xmit_flit_cnt[idx_from_vl(vl)] = 0;
+ }
/* sw_port_vl_congestion is 0 for HFIs */
if (counter_select & CS_PORT_RCV_FECN)
diff --git a/drivers/infiniband/hw/hfi1/mad.h b/drivers/infiniband/hw/hfi1/mad.h
index c4938f3d97c8..2f48e6953629 100644
--- a/drivers/infiniband/hw/hfi1/mad.h
+++ b/drivers/infiniband/hw/hfi1/mad.h
@@ -180,6 +180,15 @@ struct opa_mad_notice_attr {
#define OPA_VLARB_PREEMPT_MATRIX 3
#define IB_PMA_PORT_COUNTERS_CONG cpu_to_be16(0xFF00)
+#define LINK_SPEED_25G 1
+#define LINK_SPEED_12_5G 2
+#define LINK_WIDTH_DEFAULT 4
+#define DECIMAL_FACTORING 1000
+/*
+ * The default link width is multiplied by 1000
+ * to get accurate value after division.
+ */
+#define FACTOR_LINK_WIDTH (LINK_WIDTH_DEFAULT * DECIMAL_FACTORING)
struct ib_pma_portcounters_cong {
u8 reserved;
@@ -429,5 +438,41 @@ struct sc2vlnt {
void hfi1_event_pkey_change(struct hfi1_devdata *dd, u8 port);
void hfi1_handle_trap_timer(struct timer_list *t);
-
+u16 tx_link_width(u16 link_width);
+u64 get_xmit_wait_counters(struct hfi1_pportdata *ppd, u16 link_width,
+ u16 link_speed, int vl);
+/**
+ * get_link_speed - determine whether 12.5G or 25G speed
+ * @link_speed: the speed of active link
+ * @return: Return 2 if link speed identified as 12.5G
+ * or return 1 if link speed is 25G.
+ *
+ * The function indirectly calculate required link speed
+ * value for convert_xmit_counter function. If the link
+ * speed is 25G, the function return as 1 as it is required
+ * by xmit counter conversion formula :-( 25G / link_speed).
+ * This conversion will provide value 1 if current
+ * link speed is 25G or 2 if 12.5G.This is done to avoid
+ * 12.5 float number conversion.
+ */
+static inline u16 get_link_speed(u16 link_speed)
+{
+ return (link_speed == 1) ?
+ LINK_SPEED_12_5G : LINK_SPEED_25G;
+}
+
+/**
+ * convert_xmit_counter - calculate flit times for given xmit counter
+ * value
+ * @xmit_wait_val: current xmit counter value
+ * @link_width: width of active link
+ * @link_speed: speed of active link
+ * @return: return xmit counter value in flit times.
+ */
+static inline u64 convert_xmit_counter(u64 xmit_wait_val, u16 link_width,
+ u16 link_speed)
+{
+ return (xmit_wait_val * 2 * (FACTOR_LINK_WIDTH / link_width)
+ * link_speed) / DECIMAL_FACTORING;
+}
#endif /* _HFI1_MAD_H */
diff --git a/drivers/infiniband/hw/hfi1/pcie.c b/drivers/infiniband/hw/hfi1/pcie.c
index 8c7e7a60b715..83d66e862207 100644
--- a/drivers/infiniband/hw/hfi1/pcie.c
+++ b/drivers/infiniband/hw/hfi1/pcie.c
@@ -1034,6 +1034,7 @@ int do_pcie_gen3_transition(struct hfi1_devdata *dd)
int do_retry, retry_count = 0;
int intnum = 0;
uint default_pset;
+ uint pset = pcie_pset;
u16 target_vector, target_speed;
u16 lnkctl2, vendor;
u8 div;
@@ -1201,16 +1202,16 @@ retry:
*
* Set Gen3EqPsetReqVec, leave other fields 0.
*/
- if (pcie_pset == UNSET_PSET)
- pcie_pset = default_pset;
- if (pcie_pset > 10) { /* valid range is 0-10, inclusive */
+ if (pset == UNSET_PSET)
+ pset = default_pset;
+ if (pset > 10) { /* valid range is 0-10, inclusive */
dd_dev_err(dd, "%s: Invalid Eq Pset %u, setting to %d\n",
- __func__, pcie_pset, default_pset);
- pcie_pset = default_pset;
+ __func__, pset, default_pset);
+ pset = default_pset;
}
- dd_dev_info(dd, "%s: using EQ Pset %u\n", __func__, pcie_pset);
+ dd_dev_info(dd, "%s: using EQ Pset %u\n", __func__, pset);
pci_write_config_dword(dd->pcidev, PCIE_CFG_REG_PL106,
- ((1 << pcie_pset) <<
+ ((1 << pset) <<
PCIE_CFG_REG_PL106_GEN3_EQ_PSET_REQ_VEC_SHIFT) |
PCIE_CFG_REG_PL106_GEN3_EQ_EVAL2MS_DISABLE_SMASK |
PCIE_CFG_REG_PL106_GEN3_EQ_PHASE23_EXIT_MODE_SMASK);
@@ -1240,10 +1241,10 @@ retry:
/* apply static CTLE tunings */
u8 pcie_dc, pcie_lf, pcie_hf, pcie_bw;
- pcie_dc = ctle_tunings[pcie_pset][0];
- pcie_lf = ctle_tunings[pcie_pset][1];
- pcie_hf = ctle_tunings[pcie_pset][2];
- pcie_bw = ctle_tunings[pcie_pset][3];
+ pcie_dc = ctle_tunings[pset][0];
+ pcie_lf = ctle_tunings[pset][1];
+ pcie_hf = ctle_tunings[pset][2];
+ pcie_bw = ctle_tunings[pset][3];
write_gasket_interrupt(dd, intnum++, 0x0026, 0x0200 | pcie_dc);
write_gasket_interrupt(dd, intnum++, 0x0026, 0x0100 | pcie_lf);
write_gasket_interrupt(dd, intnum++, 0x0026, 0x0000 | pcie_hf);
diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c
index 4c1198bc5e70..40dac4d16eb8 100644
--- a/drivers/infiniband/hw/hfi1/pio.c
+++ b/drivers/infiniband/hw/hfi1/pio.c
@@ -455,8 +455,8 @@ int init_send_contexts(struct hfi1_devdata *dd)
dd->hw_to_sw = kmalloc_array(TXE_NUM_CONTEXTS, sizeof(u8),
GFP_KERNEL);
dd->send_contexts = kcalloc(dd->num_send_contexts,
- sizeof(struct send_context_info),
- GFP_KERNEL);
+ sizeof(struct send_context_info),
+ GFP_KERNEL);
if (!dd->send_contexts || !dd->hw_to_sw) {
kfree(dd->hw_to_sw);
kfree(dd->send_contexts);
@@ -856,8 +856,9 @@ struct send_context *sc_alloc(struct hfi1_devdata *dd, int type,
* so head == tail can mean empty.
*/
sc->sr_size = sci->credits + 1;
- sc->sr = kzalloc_node(sizeof(union pio_shadow_ring) *
- sc->sr_size, GFP_KERNEL, numa);
+ sc->sr = kcalloc_node(sc->sr_size,
+ sizeof(union pio_shadow_ring),
+ GFP_KERNEL, numa);
if (!sc->sr) {
sc_free(sc);
return NULL;
@@ -1958,9 +1959,9 @@ int init_pervl_scs(struct hfi1_devdata *dd)
hfi1_init_ctxt(dd->vld[15].sc);
dd->vld[15].mtu = enum_to_mtu(OPA_MTU_2048);
- dd->kernel_send_context = kzalloc_node(dd->num_send_contexts *
- sizeof(struct send_context *),
- GFP_KERNEL, dd->node);
+ dd->kernel_send_context = kcalloc_node(dd->num_send_contexts,
+ sizeof(struct send_context *),
+ GFP_KERNEL, dd->node);
if (!dd->kernel_send_context)
goto freesc15;
diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c
index 5507910e8b8a..d30dd1a5b0a6 100644
--- a/drivers/infiniband/hw/hfi1/qp.c
+++ b/drivers/infiniband/hw/hfi1/qp.c
@@ -565,7 +565,7 @@ void qp_iter_print(struct seq_file *s, struct rvt_qp_iter *iter)
if (qp->s_ack_queue)
e = &qp->s_ack_queue[qp->s_tail_ack_queue];
seq_printf(s,
- "N %d %s QP %x R %u %s %u %u %u f=%x %u %u %u %u %u %u SPSN %x %x %x %x %x RPSN %x S(%u %u %u %u %u %u %u) R(%u %u %u) RQP %x LID %x SL %u MTU %u %u %u %u %u SDE %p,%u SC %p,%u SCQ %u %u PID %d OS %x %x E %x %x %x RNR %d %s %d\n",
+ "N %d %s QP %x R %u %s %u %u f=%x %u %u %u %u %u %u SPSN %x %x %x %x %x RPSN %x S(%u %u %u %u %u %u %u) R(%u %u %u) RQP %x LID %x SL %u MTU %u %u %u %u %u SDE %p,%u SC %p,%u SCQ %u %u PID %d OS %x %x E %x %x %x RNR %d %s %d\n",
iter->n,
qp_idle(qp) ? "I" : "B",
qp->ibqp.qp_num,
@@ -573,7 +573,6 @@ void qp_iter_print(struct seq_file *s, struct rvt_qp_iter *iter)
qp_type_str[qp->ibqp.qp_type],
qp->state,
wqe ? wqe->wr.opcode : 0,
- qp->s_hdrwords,
qp->s_flags,
iowait_sdma_pending(&priv->s_iowait),
iowait_pio_pending(&priv->s_iowait),
@@ -795,7 +794,6 @@ void notify_error_qp(struct rvt_qp *qp)
}
if (!(qp->s_flags & RVT_S_BUSY)) {
- qp->s_hdrwords = 0;
if (qp->s_rdma_mr) {
rvt_put_mr(qp->s_rdma_mr);
qp->s_rdma_mr = NULL;
diff --git a/drivers/infiniband/hw/hfi1/qp.h b/drivers/infiniband/hw/hfi1/qp.h
index c06d2f8348e0..b2d4cba8d15b 100644
--- a/drivers/infiniband/hw/hfi1/qp.h
+++ b/drivers/infiniband/hw/hfi1/qp.h
@@ -51,12 +51,25 @@
#include <rdma/rdmavt_qp.h>
#include "verbs.h"
#include "sdma.h"
+#include "verbs_txreq.h"
extern unsigned int hfi1_qp_table_size;
extern const struct rvt_operation_params hfi1_post_parms[];
/*
+ * Send if not busy or waiting for I/O and either
+ * a RC response is pending or we can process send work requests.
+ */
+static inline int hfi1_send_ok(struct rvt_qp *qp)
+{
+ return !(qp->s_flags & (RVT_S_BUSY | RVT_S_ANY_WAIT_IO)) &&
+ (verbs_txreq_queued(qp) ||
+ (qp->s_flags & RVT_S_RESP_PENDING) ||
+ !(qp->s_flags & RVT_S_ANY_WAIT_SEND));
+}
+
+/*
* free_ahg - clear ahg from QP
*/
static inline void clear_ahg(struct rvt_qp *qp)
diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c
index 14cc212a21c7..da58046a02ea 100644
--- a/drivers/infiniband/hw/hfi1/rc.c
+++ b/drivers/infiniband/hw/hfi1/rc.c
@@ -226,12 +226,10 @@ normal:
bth2 = mask_psn(qp->s_ack_psn);
}
qp->s_rdma_ack_cnt++;
- qp->s_hdrwords = hwords;
ps->s_txreq->sde = priv->s_sde;
ps->s_txreq->s_cur_size = len;
+ ps->s_txreq->hdr_dwords = hwords;
hfi1_make_ruc_header(qp, ohdr, bth0, bth2, middle, ps);
- /* pbc */
- ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
return 1;
bail:
@@ -385,7 +383,6 @@ int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
: IB_WC_SUCCESS);
if (local_ops)
atomic_dec(&qp->local_ops_pending);
- qp->s_hdrwords = 0;
goto done_free_tx;
}
@@ -688,7 +685,7 @@ no_flow_control:
bth2 |= IB_BTH_REQ_ACK;
}
qp->s_len -= len;
- qp->s_hdrwords = hwords;
+ ps->s_txreq->hdr_dwords = hwords;
ps->s_txreq->sde = priv->s_sde;
ps->s_txreq->ss = ss;
ps->s_txreq->s_cur_size = len;
@@ -699,8 +696,6 @@ no_flow_control:
bth2,
middle,
ps);
- /* pbc */
- ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
return 1;
done_free_tx:
@@ -714,7 +709,6 @@ bail:
bail_no_tx:
ps->s_txreq = NULL;
qp->s_flags &= ~RVT_S_BUSY;
- qp->s_hdrwords = 0;
return 0;
}
@@ -734,14 +728,16 @@ static inline void hfi1_make_bth_aeth(struct rvt_qp *qp,
ohdr->bth[2] = cpu_to_be32(mask_psn(qp->r_ack_psn));
}
-static inline void hfi1_queue_rc_ack(struct rvt_qp *qp, bool is_fecn)
+static inline void hfi1_queue_rc_ack(struct hfi1_packet *packet, bool is_fecn)
{
- struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+ struct rvt_qp *qp = packet->qp;
+ struct hfi1_ibport *ibp;
unsigned long flags;
spin_lock_irqsave(&qp->s_lock, flags);
if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK))
goto unlock;
+ ibp = rcd_to_iport(packet->rcd);
this_cpu_inc(*ibp->rvp.rc_qacks);
qp->s_flags |= RVT_S_ACK_PENDING | RVT_S_RESP_PENDING;
qp->s_nak_state = qp->r_nak_state;
@@ -755,13 +751,14 @@ unlock:
spin_unlock_irqrestore(&qp->s_lock, flags);
}
-static inline void hfi1_make_rc_ack_9B(struct rvt_qp *qp,
+static inline void hfi1_make_rc_ack_9B(struct hfi1_packet *packet,
struct hfi1_opa_header *opa_hdr,
u8 sc5, bool is_fecn,
u64 *pbc_flags, u32 *hwords,
u32 *nwords)
{
- struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+ struct rvt_qp *qp = packet->qp;
+ struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd);
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
struct ib_header *hdr = &opa_hdr->ibh;
struct ib_other_headers *ohdr;
@@ -802,19 +799,20 @@ static inline void hfi1_make_rc_ack_9B(struct rvt_qp *qp,
hfi1_make_bth_aeth(qp, ohdr, bth0, bth1);
}
-static inline void hfi1_make_rc_ack_16B(struct rvt_qp *qp,
+static inline void hfi1_make_rc_ack_16B(struct hfi1_packet *packet,
struct hfi1_opa_header *opa_hdr,
u8 sc5, bool is_fecn,
u64 *pbc_flags, u32 *hwords,
u32 *nwords)
{
- struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+ struct rvt_qp *qp = packet->qp;
+ struct hfi1_ibport *ibp = rcd_to_iport(packet->rcd);
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
struct hfi1_16b_header *hdr = &opa_hdr->opah;
struct ib_other_headers *ohdr;
u32 bth0, bth1 = 0;
u16 len, pkey;
- u8 becn = !!is_fecn;
+ bool becn = is_fecn;
u8 l4 = OPA_16B_L4_IB_LOCAL;
u8 extra_bytes;
@@ -854,7 +852,7 @@ static inline void hfi1_make_rc_ack_16B(struct rvt_qp *qp,
hfi1_make_bth_aeth(qp, ohdr, bth0, bth1);
}
-typedef void (*hfi1_make_rc_ack)(struct rvt_qp *qp,
+typedef void (*hfi1_make_rc_ack)(struct hfi1_packet *packet,
struct hfi1_opa_header *opa_hdr,
u8 sc5, bool is_fecn,
u64 *pbc_flags, u32 *hwords,
@@ -874,9 +872,10 @@ static const hfi1_make_rc_ack hfi1_make_rc_ack_tbl[2] = {
* Note that RDMA reads and atomics are handled in the
* send side QP state and send engine.
*/
-void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,
- struct rvt_qp *qp, bool is_fecn)
+void hfi1_send_rc_ack(struct hfi1_packet *packet, bool is_fecn)
{
+ struct hfi1_ctxtdata *rcd = packet->rcd;
+ struct rvt_qp *qp = packet->qp;
struct hfi1_ibport *ibp = rcd_to_iport(rcd);
struct hfi1_qp_priv *priv = qp->priv;
struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
@@ -893,13 +892,13 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,
/* Don't send ACK or NAK if a RDMA read or atomic is pending. */
if (qp->s_flags & RVT_S_RESP_PENDING) {
- hfi1_queue_rc_ack(qp, is_fecn);
+ hfi1_queue_rc_ack(packet, is_fecn);
return;
}
/* Ensure s_rdma_ack_cnt changes are committed */
if (qp->s_rdma_ack_cnt) {
- hfi1_queue_rc_ack(qp, is_fecn);
+ hfi1_queue_rc_ack(packet, is_fecn);
return;
}
@@ -908,7 +907,7 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,
return;
/* Make the appropriate header */
- hfi1_make_rc_ack_tbl[priv->hdr_type](qp, &opa_hdr, sc5, is_fecn,
+ hfi1_make_rc_ack_tbl[priv->hdr_type](packet, &opa_hdr, sc5, is_fecn,
&pbc_flags, &hwords, &nwords);
plen = 2 /* PBC */ + hwords + nwords;
@@ -922,7 +921,7 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd,
* so that when enough buffer space becomes available,
* the ACK is sent ahead of other outgoing packets.
*/
- hfi1_queue_rc_ack(qp, is_fecn);
+ hfi1_queue_rc_ack(packet, is_fecn);
return;
}
trace_ack_output_ibhdr(dd_from_ibdev(qp->ibqp.device),
@@ -1540,7 +1539,7 @@ static void rc_rcv_resp(struct hfi1_packet *packet)
void *data = packet->payload;
u32 tlen = packet->tlen;
struct rvt_qp *qp = packet->qp;
- struct hfi1_ibport *ibp = to_iport(qp->ibqp.device, qp->port_num);
+ struct hfi1_ibport *ibp;
struct ib_other_headers *ohdr = packet->ohdr;
struct rvt_swqe *wqe;
enum ib_wc_status status;
@@ -1697,6 +1696,7 @@ ack_op_err:
goto ack_err;
ack_seq_err:
+ ibp = rcd_to_iport(rcd);
rdma_seq_err(qp, ibp, psn, rcd);
goto ack_done;
@@ -2037,7 +2037,6 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
struct rvt_qp *qp = packet->qp;
struct hfi1_ibport *ibp = rcd_to_iport(rcd);
struct ib_other_headers *ohdr = packet->ohdr;
- u32 bth0 = be32_to_cpu(ohdr->bth[0]);
u32 opcode = packet->opcode;
u32 hdrsize = packet->hlen;
u32 psn = ib_bth_get_psn(packet->ohdr);
@@ -2235,7 +2234,7 @@ send_last:
wc.port_num = 0;
/* Signal completion event if the solicited bit is set. */
rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
- (bth0 & IB_BTH_SOLICITED) != 0);
+ ib_bth_is_solicited(ohdr));
break;
case OP(RDMA_WRITE_ONLY):
@@ -2479,7 +2478,7 @@ nack_acc:
qp->r_nak_state = IB_NAK_REMOTE_ACCESS_ERROR;
qp->r_ack_psn = qp->r_psn;
send_ack:
- hfi1_send_rc_ack(rcd, qp, is_fecn);
+ hfi1_send_rc_ack(packet, is_fecn);
}
void hfi1_rc_hdrerr(
diff --git a/drivers/infiniband/hw/hfi1/ruc.c b/drivers/infiniband/hw/hfi1/ruc.c
index 13b994738f41..3daa94bdae3a 100644
--- a/drivers/infiniband/hw/hfi1/ruc.c
+++ b/drivers/infiniband/hw/hfi1/ruc.c
@@ -225,19 +225,8 @@ int hfi1_ruc_check_hdr(struct hfi1_ibport *ibp, struct hfi1_packet *packet)
u32 dlid = packet->dlid;
u32 slid = packet->slid;
u32 sl = packet->sl;
- int migrated;
- u32 bth0, bth1;
- u16 pkey;
-
- bth0 = be32_to_cpu(packet->ohdr->bth[0]);
- bth1 = be32_to_cpu(packet->ohdr->bth[1]);
- if (packet->etype == RHF_RCV_TYPE_BYPASS) {
- pkey = hfi1_16B_get_pkey(packet->hdr);
- migrated = bth1 & OPA_BTH_MIG_REQ;
- } else {
- pkey = ib_bth_get_pkey(packet->ohdr);
- migrated = bth0 & IB_BTH_MIG_REQ;
- }
+ bool migrated = packet->migrated;
+ u16 pkey = packet->pkey;
if (qp->s_mig_state == IB_MIG_ARMED && migrated) {
if (!packet->grh) {
@@ -756,19 +745,18 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,
u32 slid;
u16 pkey = hfi1_get_pkey(ibp, qp->s_pkey_index);
u8 l4 = OPA_16B_L4_IB_LOCAL;
- u8 extra_bytes = hfi1_get_16b_padding((qp->s_hdrwords << 2),
- ps->s_txreq->s_cur_size);
+ u8 extra_bytes = hfi1_get_16b_padding(
+ (ps->s_txreq->hdr_dwords << 2),
+ ps->s_txreq->s_cur_size);
u32 nwords = SIZE_OF_CRC + ((ps->s_txreq->s_cur_size +
extra_bytes + SIZE_OF_LT) >> 2);
- u8 becn = 0;
+ bool becn = false;
if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH) &&
hfi1_check_mcast(rdma_ah_get_dlid(&qp->remote_ah_attr))) {
struct ib_grh *grh;
struct ib_global_route *grd =
rdma_ah_retrieve_grh(&qp->remote_ah_attr);
- int hdrwords;
-
/*
* Ensure OPA GIDs are transformed to IB gids
* before creating the GRH.
@@ -777,9 +765,10 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,
grd->sgid_index = 0;
grh = &ps->s_txreq->phdr.hdr.opah.u.l.grh;
l4 = OPA_16B_L4_IB_GLOBAL;
- hdrwords = qp->s_hdrwords - 4;
- qp->s_hdrwords += hfi1_make_grh(ibp, grh, grd,
- hdrwords, nwords);
+ ps->s_txreq->hdr_dwords +=
+ hfi1_make_grh(ibp, grh, grd,
+ ps->s_txreq->hdr_dwords - LRH_16B_DWORDS,
+ nwords);
middle = 0;
}
@@ -798,7 +787,7 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,
if (qp->s_flags & RVT_S_ECN) {
qp->s_flags &= ~RVT_S_ECN;
/* we recently received a FECN, so return a BECN */
- becn = 1;
+ becn = true;
}
hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2);
@@ -813,7 +802,7 @@ static inline void hfi1_make_ruc_header_16B(struct rvt_qp *qp,
slid,
opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr),
16B),
- (qp->s_hdrwords + nwords) >> 1,
+ (ps->s_txreq->hdr_dwords + nwords) >> 1,
pkey, becn, 0, l4, priv->s_sc);
}
@@ -833,13 +822,13 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp,
if (unlikely(rdma_ah_get_ah_flags(&qp->remote_ah_attr) & IB_AH_GRH)) {
struct ib_grh *grh = &ps->s_txreq->phdr.hdr.ibh.u.l.grh;
- int hdrwords = qp->s_hdrwords - 2;
lrh0 = HFI1_LRH_GRH;
- qp->s_hdrwords +=
+ ps->s_txreq->hdr_dwords +=
hfi1_make_grh(ibp, grh,
rdma_ah_read_grh(&qp->remote_ah_attr),
- hdrwords, nwords);
+ ps->s_txreq->hdr_dwords - LRH_9B_DWORDS,
+ nwords);
middle = 0;
}
lrh0 |= (priv->s_sc & 0xf) << 12 |
@@ -865,7 +854,7 @@ static inline void hfi1_make_ruc_header_9B(struct rvt_qp *qp,
hfi1_make_ruc_bth(qp, ohdr, bth0, bth1, bth2);
hfi1_make_ib_hdr(&ps->s_txreq->phdr.hdr.ibh,
lrh0,
- qp->s_hdrwords + nwords,
+ ps->s_txreq->hdr_dwords + nwords,
opa_get_lid(rdma_ah_get_dlid(&qp->remote_ah_attr), 9B),
ppd_from_ibp(ibp)->lid |
rdma_ah_get_path_bits(&qp->remote_ah_attr));
@@ -1030,7 +1019,7 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread)
ps.s_txreq = get_waiting_verbs_txreq(qp);
do {
/* Check for a constructed packet to be sent. */
- if (qp->s_hdrwords != 0) {
+ if (ps.s_txreq) {
spin_unlock_irqrestore(&qp->s_lock, ps.flags);
/*
* If the packet cannot be sent now, return and
@@ -1038,8 +1027,6 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread)
*/
if (hfi1_verbs_send(qp, &ps))
return;
- /* Record that s_ahg is empty. */
- qp->s_hdrwords = 0;
/* allow other tasks to run */
if (schedule_send_yield(qp, &ps))
return;
diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c
index 61c130dbed10..1f203309cf24 100644
--- a/drivers/infiniband/hw/hfi1/sdma.c
+++ b/drivers/infiniband/hw/hfi1/sdma.c
@@ -1275,13 +1275,15 @@ bail:
return -ENOMEM;
}
-/*
- * Clean up allocated memory.
- *
- * This routine is can be called regardless of the success of sdma_init()
+/**
+ * sdma_clean() Clean up allocated memory
+ * @dd: struct hfi1_devdata
+ * @num_engines: num sdma engines
*
+ * This routine can be called regardless of the success of
+ * sdma_init()
*/
-static void sdma_clean(struct hfi1_devdata *dd, size_t num_engines)
+void sdma_clean(struct hfi1_devdata *dd, size_t num_engines)
{
size_t i;
struct sdma_engine *sde;
@@ -1386,7 +1388,8 @@ int sdma_init(struct hfi1_devdata *dd, u8 port)
num_engines, descq_cnt);
/* alloc memory for array of send engines */
- dd->per_sdma = kcalloc(num_engines, sizeof(*dd->per_sdma), GFP_KERNEL);
+ dd->per_sdma = kcalloc_node(num_engines, sizeof(*dd->per_sdma),
+ GFP_KERNEL, dd->node);
if (!dd->per_sdma)
return ret;
@@ -1617,7 +1620,6 @@ void sdma_exit(struct hfi1_devdata *dd)
*/
sdma_finalput(&sde->state);
}
- sdma_clean(dd, dd->num_sdma);
}
/*
diff --git a/drivers/infiniband/hw/hfi1/sdma.h b/drivers/infiniband/hw/hfi1/sdma.h
index 374c59784950..46c775f255d1 100644
--- a/drivers/infiniband/hw/hfi1/sdma.h
+++ b/drivers/infiniband/hw/hfi1/sdma.h
@@ -420,6 +420,7 @@ struct sdma_engine {
int sdma_init(struct hfi1_devdata *dd, u8 port);
void sdma_start(struct hfi1_devdata *dd);
void sdma_exit(struct hfi1_devdata *dd);
+void sdma_clean(struct hfi1_devdata *dd, size_t num_engines);
void sdma_all_running(struct hfi1_devdata *dd);
void sdma_all_idle(struct hfi1_devdata *dd);
void sdma_freeze_notify(struct hfi1_devdata *dd, int go_idle);
diff --git a/drivers/infiniband/hw/hfi1/trace.c b/drivers/infiniband/hw/hfi1/trace.c
index 959a80429ee9..89bd9851065b 100644
--- a/drivers/infiniband/hw/hfi1/trace.c
+++ b/drivers/infiniband/hw/hfi1/trace.c
@@ -138,7 +138,7 @@ static const char *parse_syndrome(u8 syndrome)
}
void hfi1_trace_parse_9b_bth(struct ib_other_headers *ohdr,
- u8 *ack, u8 *becn, u8 *fecn, u8 *mig,
+ u8 *ack, bool *becn, bool *fecn, u8 *mig,
u8 *se, u8 *pad, u8 *opcode, u8 *tver,
u16 *pkey, u32 *psn, u32 *qpn)
{
@@ -184,7 +184,7 @@ void hfi1_trace_parse_9b_hdr(struct ib_header *hdr, bool sc5,
}
void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr,
- u8 *age, u8 *becn, u8 *fecn,
+ u8 *age, bool *becn, bool *fecn,
u8 *l4, u8 *rc, u8 *sc,
u16 *entropy, u16 *len, u16 *pkey,
u32 *dlid, u32 *slid)
@@ -207,7 +207,7 @@ void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr,
#define LRH_16B_PRN "age:%d becn:%d fecn:%d l4:%d " \
"rc:%d sc:%d pkey:0x%.4x entropy:0x%.4x"
const char *hfi1_trace_fmt_lrh(struct trace_seq *p, bool bypass,
- u8 age, u8 becn, u8 fecn, u8 l4,
+ u8 age, bool becn, bool fecn, u8 l4,
u8 lnh, const char *lnh_name, u8 lver,
u8 rc, u8 sc, u8 sl, u16 entropy,
u16 len, u16 pkey, u32 dlid, u32 slid)
@@ -235,7 +235,7 @@ const char *hfi1_trace_fmt_lrh(struct trace_seq *p, bool bypass,
"op:0x%.2x,%s se:%d m:%d pad:%d tver:%d " \
"qpn:0x%.6x a:%d psn:0x%.8x"
const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass,
- u8 ack, u8 becn, u8 fecn, u8 mig,
+ u8 ack, bool becn, bool fecn, u8 mig,
u8 se, u8 pad, u8 opcode, const char *opname,
u8 tver, u16 pkey, u32 psn, u32 qpn)
{
diff --git a/drivers/infiniband/hw/hfi1/trace_ibhdrs.h b/drivers/infiniband/hw/hfi1/trace_ibhdrs.h
index fb631278eccd..2847626d3819 100644
--- a/drivers/infiniband/hw/hfi1/trace_ibhdrs.h
+++ b/drivers/infiniband/hw/hfi1/trace_ibhdrs.h
@@ -101,7 +101,7 @@ u8 hfi1_trace_opa_hdr_len(struct hfi1_opa_header *opah);
u8 hfi1_trace_packet_hdr_len(struct hfi1_packet *packet);
const char *hfi1_trace_get_packet_l4_str(u8 l4);
void hfi1_trace_parse_9b_bth(struct ib_other_headers *ohdr,
- u8 *ack, u8 *becn, u8 *fecn, u8 *mig,
+ u8 *ack, bool *becn, bool *fecn, u8 *mig,
u8 *se, u8 *pad, u8 *opcode, u8 *tver,
u16 *pkey, u32 *psn, u32 *qpn);
void hfi1_trace_parse_9b_hdr(struct ib_header *hdr, bool sc5,
@@ -112,19 +112,19 @@ void hfi1_trace_parse_16b_bth(struct ib_other_headers *ohdr,
u8 *pad, u8 *se, u8 *tver,
u32 *psn, u32 *qpn);
void hfi1_trace_parse_16b_hdr(struct hfi1_16b_header *hdr,
- u8 *age, u8 *becn, u8 *fecn,
+ u8 *age, bool *becn, bool *fecn,
u8 *l4, u8 *rc, u8 *sc,
u16 *entropy, u16 *len, u16 *pkey,
u32 *dlid, u32 *slid);
const char *hfi1_trace_fmt_lrh(struct trace_seq *p, bool bypass,
- u8 age, u8 becn, u8 fecn, u8 l4,
+ u8 age, bool becn, bool fecn, u8 l4,
u8 lnh, const char *lnh_name, u8 lver,
u8 rc, u8 sc, u8 sl, u16 entropy,
u16 len, u16 pkey, u32 dlid, u32 slid);
const char *hfi1_trace_fmt_bth(struct trace_seq *p, bool bypass,
- u8 ack, u8 becn, u8 fecn, u8 mig,
+ u8 ack, bool becn, bool fecn, u8 mig,
u8 se, u8 pad, u8 opcode, const char *opname,
u8 tver, u16 pkey, u32 psn, u32 qpn);
@@ -148,8 +148,8 @@ DECLARE_EVENT_CLASS(hfi1_input_ibhdr_template,
__field(u8, etype)
__field(u8, ack)
__field(u8, age)
- __field(u8, becn)
- __field(u8, fecn)
+ __field(bool, becn)
+ __field(bool, fecn)
__field(u8, l2)
__field(u8, l4)
__field(u8, lnh)
@@ -290,8 +290,8 @@ DECLARE_EVENT_CLASS(hfi1_output_ibhdr_template,
__field(u8, hdr_type)
__field(u8, ack)
__field(u8, age)
- __field(u8, becn)
- __field(u8, fecn)
+ __field(bool, becn)
+ __field(bool, fecn)
__field(u8, l4)
__field(u8, lnh)
__field(u8, lver)
diff --git a/drivers/infiniband/hw/hfi1/trace_rx.h b/drivers/infiniband/hw/hfi1/trace_rx.h
index 4d487fee105d..7eceb57e0415 100644
--- a/drivers/infiniband/hw/hfi1/trace_rx.h
+++ b/drivers/infiniband/hw/hfi1/trace_rx.h
@@ -63,17 +63,9 @@ __print_symbolic(type, \
#define TRACE_SYSTEM hfi1_rx
TRACE_EVENT(hfi1_rcvhdr,
- TP_PROTO(struct hfi1_devdata *dd,
- u32 ctxt,
- u64 eflags,
- u32 etype,
- u32 hlen,
- u32 tlen,
- u32 updegr,
- u32 etail
- ),
- TP_ARGS(dd, ctxt, eflags, etype, hlen, tlen, updegr, etail),
- TP_STRUCT__entry(DD_DEV_ENTRY(dd)
+ TP_PROTO(struct hfi1_packet *packet),
+ TP_ARGS(packet),
+ TP_STRUCT__entry(DD_DEV_ENTRY(packet->rcd->dd)
__field(u64, eflags)
__field(u32, ctxt)
__field(u32, etype)
@@ -82,14 +74,14 @@ TRACE_EVENT(hfi1_rcvhdr,
__field(u32, updegr)
__field(u32, etail)
),
- TP_fast_assign(DD_DEV_ASSIGN(dd);
- __entry->eflags = eflags;
- __entry->ctxt = ctxt;
- __entry->etype = etype;
- __entry->hlen = hlen;
- __entry->tlen = tlen;
- __entry->updegr = updegr;
- __entry->etail = etail;
+ TP_fast_assign(DD_DEV_ASSIGN(packet->rcd->dd);
+ __entry->eflags = rhf_err_flags(packet->rhf);
+ __entry->ctxt = packet->rcd->ctxt;
+ __entry->etype = packet->etype;
+ __entry->hlen = packet->hlen;
+ __entry->tlen = packet->tlen;
+ __entry->updegr = packet->updegr;
+ __entry->etail = rhf_egr_index(packet->rhf);
),
TP_printk(
"[%s] ctxt %d eflags 0x%llx etype %d,%s hlen %d tlen %d updegr %d etail %d",
diff --git a/drivers/infiniband/hw/hfi1/uc.c b/drivers/infiniband/hw/hfi1/uc.c
index 132b63e787d1..9d7a3110c14c 100644
--- a/drivers/infiniband/hw/hfi1/uc.c
+++ b/drivers/infiniband/hw/hfi1/uc.c
@@ -144,7 +144,6 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
: IB_WC_SUCCESS);
if (local_ops)
atomic_dec(&qp->local_ops_pending);
- qp->s_hdrwords = 0;
goto done_free_tx;
}
/*
@@ -267,14 +266,12 @@ int hfi1_make_uc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
break;
}
qp->s_len -= len;
- qp->s_hdrwords = hwords;
+ ps->s_txreq->hdr_dwords = hwords;
ps->s_txreq->sde = priv->s_sde;
ps->s_txreq->ss = &qp->s_sge;
ps->s_txreq->s_cur_size = len;
hfi1_make_ruc_header(qp, ohdr, bth0 | (qp->s_state << 24),
mask_psn(qp->s_psn++), middle, ps);
- /* pbc */
- ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
return 1;
done_free_tx:
@@ -288,7 +285,6 @@ bail:
bail_no_tx:
ps->s_txreq = NULL;
qp->s_flags &= ~RVT_S_BUSY;
- qp->s_hdrwords = 0;
return 0;
}
@@ -480,8 +476,7 @@ last_imm:
wc.port_num = 0;
/* Signal completion event if the solicited bit is set. */
rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
- (ohdr->bth[0] &
- cpu_to_be32(IB_BTH_SOLICITED)) != 0);
+ ib_bth_is_solicited(ohdr));
break;
case OP(RDMA_WRITE_FIRST):
diff --git a/drivers/infiniband/hw/hfi1/ud.c b/drivers/infiniband/hw/hfi1/ud.c
index deb184574395..bcf3b0bebac8 100644
--- a/drivers/infiniband/hw/hfi1/ud.c
+++ b/drivers/infiniband/hw/hfi1/ud.c
@@ -340,15 +340,16 @@ void hfi1_make_ud_req_9B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
extra_bytes = -wqe->length & 3;
nwords = ((wqe->length + extra_bytes) >> 2) + SIZE_OF_CRC;
/* header size in dwords LRH+BTH+DETH = (8+12+8)/4. */
- qp->s_hdrwords = 7;
+ ps->s_txreq->hdr_dwords = 7;
if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM)
- qp->s_hdrwords++;
+ ps->s_txreq->hdr_dwords++;
if (rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH) {
grh = &ps->s_txreq->phdr.hdr.ibh.u.l.grh;
- qp->s_hdrwords += hfi1_make_grh(ibp, grh,
- rdma_ah_read_grh(ah_attr),
- qp->s_hdrwords - 2, nwords);
+ ps->s_txreq->hdr_dwords +=
+ hfi1_make_grh(ibp, grh, rdma_ah_read_grh(ah_attr),
+ ps->s_txreq->hdr_dwords - LRH_9B_DWORDS,
+ nwords);
lrh0 = HFI1_LRH_GRH;
ohdr = &ps->s_txreq->phdr.hdr.ibh.u.l.oth;
} else {
@@ -381,7 +382,7 @@ void hfi1_make_ud_req_9B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
}
}
hfi1_make_bth_deth(qp, wqe, ohdr, &pkey, extra_bytes, false);
- len = qp->s_hdrwords + nwords;
+ len = ps->s_txreq->hdr_dwords + nwords;
/* Setup the packet */
ps->s_txreq->phdr.hdr.hdr_type = HFI1_PKT_TYPE_9B;
@@ -405,12 +406,12 @@ void hfi1_make_ud_req_16B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
ppd = ppd_from_ibp(ibp);
ah_attr = &ibah_to_rvtah(wqe->ud_wr.ah)->attr;
/* header size in dwords 16B LRH+BTH+DETH = (16+12+8)/4. */
- qp->s_hdrwords = 9;
+ ps->s_txreq->hdr_dwords = 9;
if (wqe->wr.opcode == IB_WR_SEND_WITH_IMM)
- qp->s_hdrwords++;
+ ps->s_txreq->hdr_dwords++;
/* SW provides space for CRC and LT for bypass packets. */
- extra_bytes = hfi1_get_16b_padding((qp->s_hdrwords << 2),
+ extra_bytes = hfi1_get_16b_padding((ps->s_txreq->hdr_dwords << 2),
wqe->length);
nwords = ((wqe->length + extra_bytes + SIZE_OF_LT) >> 2) + SIZE_OF_CRC;
@@ -428,8 +429,10 @@ void hfi1_make_ud_req_16B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
grd->sgid_index = 0;
}
grh = &ps->s_txreq->phdr.hdr.opah.u.l.grh;
- qp->s_hdrwords += hfi1_make_grh(ibp, grh, grd,
- qp->s_hdrwords - 4, nwords);
+ ps->s_txreq->hdr_dwords += hfi1_make_grh(
+ ibp, grh, grd,
+ ps->s_txreq->hdr_dwords - LRH_16B_DWORDS,
+ nwords);
ohdr = &ps->s_txreq->phdr.hdr.opah.u.l.oth;
l4 = OPA_16B_L4_IB_GLOBAL;
} else {
@@ -452,7 +455,7 @@ void hfi1_make_ud_req_16B(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
hfi1_make_bth_deth(qp, wqe, ohdr, &pkey, extra_bytes, true);
/* Convert dwords to flits */
- len = (qp->s_hdrwords + nwords) >> 1;
+ len = (ps->s_txreq->hdr_dwords + nwords) >> 1;
/* Setup the packet */
ps->s_txreq->phdr.hdr.hdr_type = HFI1_PKT_TYPE_16B;
@@ -562,8 +565,6 @@ int hfi1_make_ud_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps)
priv->s_ahg->ahgcount = 0;
priv->s_ahg->ahgidx = 0;
priv->s_ahg->tx_flags = 0;
- /* pbc */
- ps->s_txreq->hdr_dwords = qp->s_hdrwords + 2;
return 1;
@@ -578,7 +579,6 @@ bail:
bail_no_tx:
ps->s_txreq = NULL;
qp->s_flags &= ~RVT_S_BUSY;
- qp->s_hdrwords = 0;
return 0;
}
@@ -649,7 +649,8 @@ void return_cnp_16B(struct hfi1_ibport *ibp, struct rvt_qp *qp,
struct ib_grh *grh = &hdr.u.l.grh;
grh->version_tclass_flow = old_grh->version_tclass_flow;
- grh->paylen = cpu_to_be16((hwords - 4 + nwords) << 2);
+ grh->paylen = cpu_to_be16(
+ (hwords - LRH_16B_DWORDS + nwords) << 2);
grh->hop_limit = 0xff;
grh->sgid = old_grh->dgid;
grh->dgid = old_grh->sgid;
@@ -703,7 +704,8 @@ void return_cnp(struct hfi1_ibport *ibp, struct rvt_qp *qp, u32 remote_qpn,
struct ib_grh *grh = &hdr.u.l.grh;
grh->version_tclass_flow = old_grh->version_tclass_flow;
- grh->paylen = cpu_to_be16((hwords - 2 + SIZE_OF_CRC) << 2);
+ grh->paylen = cpu_to_be16(
+ (hwords - LRH_9B_DWORDS + SIZE_OF_CRC) << 2);
grh->hop_limit = 0xff;
grh->sgid = old_grh->dgid;
grh->dgid = old_grh->sgid;
@@ -1046,8 +1048,7 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
wc.port_num = qp->port_num;
/* Signal completion event if the solicited bit is set. */
rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
- (ohdr->bth[0] &
- cpu_to_be32(IB_BTH_SOLICITED)) != 0);
+ ib_bth_is_solicited(ohdr));
return;
drop:
diff --git a/drivers/infiniband/hw/hfi1/verbs.c b/drivers/infiniband/hw/hfi1/verbs.c
index b8776a362a91..471d55c50066 100644
--- a/drivers/infiniband/hw/hfi1/verbs.c
+++ b/drivers/infiniband/hw/hfi1/verbs.c
@@ -835,7 +835,7 @@ static int build_verbs_tx_desc(
{
int ret = 0;
struct hfi1_sdma_header *phdr = &tx->phdr;
- u16 hdrbytes = tx->hdr_dwords << 2;
+ u16 hdrbytes = (tx->hdr_dwords + sizeof(pbc) / 4) << 2;
u8 extra_bytes = 0;
if (tx->phdr.hdr.hdr_type) {
@@ -901,7 +901,7 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
{
struct hfi1_qp_priv *priv = qp->priv;
struct hfi1_ahg_info *ahg_info = priv->s_ahg;
- u32 hdrwords = qp->s_hdrwords;
+ u32 hdrwords = ps->s_txreq->hdr_dwords;
u32 len = ps->s_txreq->s_cur_size;
u32 plen;
struct hfi1_ibdev *dev = ps->dev;
@@ -919,7 +919,7 @@ int hfi1_verbs_send_dma(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
} else {
dwords = (len + 3) >> 2;
}
- plen = hdrwords + dwords + 2;
+ plen = hdrwords + dwords + sizeof(pbc) / 4;
tx = ps->s_txreq;
if (!sdma_txreq_built(&tx->txreq)) {
@@ -1038,7 +1038,7 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
u64 pbc)
{
struct hfi1_qp_priv *priv = qp->priv;
- u32 hdrwords = qp->s_hdrwords;
+ u32 hdrwords = ps->s_txreq->hdr_dwords;
struct rvt_sge_state *ss = ps->s_txreq->ss;
u32 len = ps->s_txreq->s_cur_size;
u32 dwords;
@@ -1064,7 +1064,7 @@ int hfi1_verbs_send_pio(struct rvt_qp *qp, struct hfi1_pkt_state *ps,
dwords = (len + 3) >> 2;
hdr = (u32 *)&ps->s_txreq->phdr.hdr.ibh;
}
- plen = hdrwords + dwords + 2;
+ plen = hdrwords + dwords + sizeof(pbc) / 4;
/* only RC/UC use complete */
switch (qp->ibqp.qp_type) {
diff --git a/drivers/infiniband/hw/hfi1/verbs.h b/drivers/infiniband/hw/hfi1/verbs.h
index 87d1285a3340..2d787b8346ca 100644
--- a/drivers/infiniband/hw/hfi1/verbs.h
+++ b/drivers/infiniband/hw/hfi1/verbs.h
@@ -105,6 +105,11 @@ enum {
HFI1_HAS_GRH = (1 << 0),
};
+#define LRH_16B_BYTES (FIELD_SIZEOF(struct hfi1_16b_header, lrh))
+#define LRH_16B_DWORDS (LRH_16B_BYTES / sizeof(u32))
+#define LRH_9B_BYTES (FIELD_SIZEOF(struct ib_header, lrh))
+#define LRH_9B_DWORDS (LRH_9B_BYTES / sizeof(u32))
+
struct hfi1_16b_header {
u32 lrh[4];
union {
@@ -246,17 +251,6 @@ static inline struct rvt_qp *iowait_to_qp(struct iowait *s_iowait)
}
/*
- * Send if not busy or waiting for I/O and either
- * a RC response is pending or we can process send work requests.
- */
-static inline int hfi1_send_ok(struct rvt_qp *qp)
-{
- return !(qp->s_flags & (RVT_S_BUSY | RVT_S_ANY_WAIT_IO)) &&
- (qp->s_hdrwords || (qp->s_flags & RVT_S_RESP_PENDING) ||
- !(qp->s_flags & RVT_S_ANY_WAIT_SEND));
-}
-
-/*
* This must be called with s_lock held.
*/
void hfi1_bad_pkey(struct hfi1_ibport *ibp, u32 key, u32 sl,
@@ -369,8 +363,7 @@ void hfi1_do_send(struct rvt_qp *qp, bool in_thread);
void hfi1_send_complete(struct rvt_qp *qp, struct rvt_swqe *wqe,
enum ib_wc_status status);
-void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, struct rvt_qp *qp,
- bool is_fecn);
+void hfi1_send_rc_ack(struct hfi1_packet *packet, bool is_fecn);
int hfi1_make_rc_req(struct rvt_qp *qp, struct hfi1_pkt_state *ps);
@@ -416,6 +409,11 @@ static inline void cacheless_memcpy(void *dst, void *src, size_t n)
__copy_user_nocache(dst, (void __user *)src, n, 0);
}
+static inline bool opa_bth_is_migration(struct ib_other_headers *ohdr)
+{
+ return ohdr->bth[1] & cpu_to_be32(OPA_BTH_MIG_REQ);
+}
+
extern const enum ib_wc_opcode ib_hfi1_wc_opcode[];
extern const u8 hdr_len_by_opcode[];
diff --git a/drivers/infiniband/hw/hfi1/verbs_txreq.h b/drivers/infiniband/hw/hfi1/verbs_txreq.h
index cec7a4b34d16..729244c3086c 100644
--- a/drivers/infiniband/hw/hfi1/verbs_txreq.h
+++ b/drivers/infiniband/hw/hfi1/verbs_txreq.h
@@ -113,6 +113,13 @@ static inline struct verbs_txreq *get_waiting_verbs_txreq(struct rvt_qp *qp)
return NULL;
}
+static inline bool verbs_txreq_queued(struct rvt_qp *qp)
+{
+ struct hfi1_qp_priv *priv = qp->priv;
+
+ return iowait_packet_queued(&priv->s_iowait);
+}
+
void hfi1_put_txreq(struct verbs_txreq *tx);
int verbs_txreq_init(struct hfi1_ibdev *dev);
void verbs_txreq_exit(struct hfi1_ibdev *dev);
diff --git a/drivers/infiniband/hw/hns/hns_roce_common.h b/drivers/infiniband/hw/hns/hns_roce_common.h
index dd67fafd0c40..319cb74aebaf 100644
--- a/drivers/infiniband/hw/hns/hns_roce_common.h
+++ b/drivers/infiniband/hw/hns/hns_roce_common.h
@@ -43,15 +43,15 @@
__raw_writel((__force u32)cpu_to_le32(value), (addr))
#define roce_get_field(origin, mask, shift) \
- (((origin) & (mask)) >> (shift))
+ (((le32_to_cpu(origin)) & (mask)) >> (shift))
#define roce_get_bit(origin, shift) \
roce_get_field((origin), (1ul << (shift)), (shift))
#define roce_set_field(origin, mask, shift, val) \
do { \
- (origin) &= (~(mask)); \
- (origin) |= (((u32)(val) << (shift)) & (mask)); \
+ (origin) &= ~cpu_to_le32(mask); \
+ (origin) |= cpu_to_le32(((u32)(val) << (shift)) & (mask)); \
} while (0)
#define roce_set_bit(origin, shift, val) \
diff --git a/drivers/infiniband/hw/hns/hns_roce_device.h b/drivers/infiniband/hw/hns/hns_roce_device.h
index 42c3b5a2d441..165a09b314f6 100644
--- a/drivers/infiniband/hw/hns/hns_roce_device.h
+++ b/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -345,8 +345,8 @@ struct hns_roce_cq {
struct hns_roce_cq_buf hr_buf;
spinlock_t lock;
struct ib_umem *umem;
- void (*comp)(struct hns_roce_cq *);
- void (*event)(struct hns_roce_cq *, enum hns_roce_event);
+ void (*comp)(struct hns_roce_cq *cq);
+ void (*event)(struct hns_roce_cq *cq, enum hns_roce_event event_type);
struct hns_roce_uar *uar;
u32 cq_depth;
@@ -466,7 +466,7 @@ struct hns_roce_qp {
struct ib_qp ibqp;
struct hns_roce_buf hr_buf;
struct hns_roce_wq rq;
- __le64 doorbell_qpn;
+ u32 doorbell_qpn;
__le32 sq_signal_bits;
u32 sq_next_wqe;
int sq_max_wqes_per_wr;
@@ -486,8 +486,8 @@ struct hns_roce_qp {
u32 atomic_rd_en;
u32 pkey_index;
u32 qkey;
- void (*event)(struct hns_roce_qp *,
- enum hns_roce_event);
+ void (*event)(struct hns_roce_qp *qp,
+ enum hns_roce_event event_type);
unsigned long qpn;
atomic_t refcount;
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
index 21ca9fa7c9d1..da13bd7c3ca9 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.c
@@ -195,23 +195,47 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
memcpy(&ud_sq_wqe->dgid[0], &ah->av.dgid[0], GID_LEN);
- ud_sq_wqe->va0_l = (u32)wr->sg_list[0].addr;
- ud_sq_wqe->va0_h = (wr->sg_list[0].addr) >> 32;
- ud_sq_wqe->l_key0 = wr->sg_list[0].lkey;
-
- ud_sq_wqe->va1_l = (u32)wr->sg_list[1].addr;
- ud_sq_wqe->va1_h = (wr->sg_list[1].addr) >> 32;
- ud_sq_wqe->l_key1 = wr->sg_list[1].lkey;
+ ud_sq_wqe->va0_l =
+ cpu_to_le32((u32)wr->sg_list[0].addr);
+ ud_sq_wqe->va0_h =
+ cpu_to_le32((wr->sg_list[0].addr) >> 32);
+ ud_sq_wqe->l_key0 =
+ cpu_to_le32(wr->sg_list[0].lkey);
+
+ ud_sq_wqe->va1_l =
+ cpu_to_le32((u32)wr->sg_list[1].addr);
+ ud_sq_wqe->va1_h =
+ cpu_to_le32((wr->sg_list[1].addr) >> 32);
+ ud_sq_wqe->l_key1 =
+ cpu_to_le32(wr->sg_list[1].lkey);
ind++;
} else if (ibqp->qp_type == IB_QPT_RC) {
+ u32 tmp_len = 0;
+
ctrl = wqe;
memset(ctrl, 0, sizeof(struct hns_roce_wqe_ctrl_seg));
for (i = 0; i < wr->num_sge; i++)
- ctrl->msg_length += wr->sg_list[i].length;
+ tmp_len += wr->sg_list[i].length;
+
+ ctrl->msg_length =
+ cpu_to_le32(le32_to_cpu(ctrl->msg_length) + tmp_len);
ctrl->sgl_pa_h = 0;
ctrl->flag = 0;
- ctrl->imm_data = send_ieth(wr);
+
+ switch (wr->opcode) {
+ case IB_WR_SEND_WITH_IMM:
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ ctrl->imm_data = wr->ex.imm_data;
+ break;
+ case IB_WR_SEND_WITH_INV:
+ ctrl->inv_key =
+ cpu_to_le32(wr->ex.invalidate_rkey);
+ break;
+ default:
+ ctrl->imm_data = 0;
+ break;
+ }
/*Ctrl field, ctrl set type: sig, solic, imm, fence */
/* SO wait for conforming application scenarios */
@@ -258,8 +282,8 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
dseg = wqe;
if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) {
- if (ctrl->msg_length >
- hr_dev->caps.max_sq_inline) {
+ if (le32_to_cpu(ctrl->msg_length) >
+ hr_dev->caps.max_sq_inline) {
ret = -EINVAL;
*bad_wr = wr;
dev_err(dev, "inline len(1-%d)=%d, illegal",
@@ -273,7 +297,7 @@ static int hns_roce_v1_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
wr->sg_list[i].length);
wqe += wr->sg_list[i].length;
}
- ctrl->flag |= HNS_ROCE_WQE_INLINE;
+ ctrl->flag |= cpu_to_le32(HNS_ROCE_WQE_INLINE);
} else {
/*sqe num is two */
for (i = 0; i < wr->num_sge; i++)
@@ -306,8 +330,8 @@ out:
SQ_DOORBELL_U32_8_QPN_S, qp->doorbell_qpn);
roce_set_bit(sq_db.u32_8, SQ_DOORBELL_HW_SYNC_S, 1);
- doorbell[0] = sq_db.u32_4;
- doorbell[1] = sq_db.u32_8;
+ doorbell[0] = le32_to_cpu(sq_db.u32_4);
+ doorbell[1] = le32_to_cpu(sq_db.u32_8);
hns_roce_write64_k(doorbell, qp->sq.db_reg_l);
qp->sq_next_wqe = ind;
@@ -403,8 +427,8 @@ out:
roce_set_bit(rq_db.u32_8, RQ_DOORBELL_U32_8_HW_SYNC_S,
1);
- doorbell[0] = rq_db.u32_4;
- doorbell[1] = rq_db.u32_8;
+ doorbell[0] = le32_to_cpu(rq_db.u32_4);
+ doorbell[1] = le32_to_cpu(rq_db.u32_8);
hns_roce_write64_k(doorbell, hr_qp->rq.db_reg_l);
}
@@ -2261,7 +2285,7 @@ static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq,
CQE_BYTE_4_WQE_INDEX_M,
CQE_BYTE_4_WQE_INDEX_S)&
((*cur_qp)->sq.wqe_cnt-1));
- switch (sq_wqe->flag & HNS_ROCE_WQE_OPCODE_MASK) {
+ switch (le32_to_cpu(sq_wqe->flag) & HNS_ROCE_WQE_OPCODE_MASK) {
case HNS_ROCE_WQE_OPCODE_SEND:
wc->opcode = IB_WC_SEND;
break;
@@ -2282,7 +2306,7 @@ static int hns_roce_v1_poll_one(struct hns_roce_cq *hr_cq,
wc->status = IB_WC_GENERAL_ERR;
break;
}
- wc->wc_flags = (sq_wqe->flag & HNS_ROCE_WQE_IMM ?
+ wc->wc_flags = (le32_to_cpu(sq_wqe->flag) & HNS_ROCE_WQE_IMM ?
IB_WC_WITH_IMM : 0);
wq = &(*cur_qp)->sq;
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
index b44ddd239060..e9a2717ea7cd 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v1.h
@@ -200,14 +200,14 @@
#define HNS_ROCE_AEQE_EVENT_CE_EVENT_CEQE_CEQN_M GENMASK(4, 0)
struct hns_roce_cq_context {
- u32 cqc_byte_4;
- u32 cq_bt_l;
- u32 cqc_byte_12;
- u32 cur_cqe_ba0_l;
- u32 cqc_byte_20;
- u32 cqe_tptr_addr_l;
- u32 cur_cqe_ba1_l;
- u32 cqc_byte_32;
+ __le32 cqc_byte_4;
+ __le32 cq_bt_l;
+ __le32 cqc_byte_12;
+ __le32 cur_cqe_ba0_l;
+ __le32 cqc_byte_20;
+ __le32 cqe_tptr_addr_l;
+ __le32 cur_cqe_ba1_l;
+ __le32 cqc_byte_32;
};
#define CQ_CONTEXT_CQC_BYTE_4_CQC_STATE_S 0
@@ -257,17 +257,17 @@ struct hns_roce_cq_context {
(((1UL << 16) - 1) << CQ_CONTEXT_CQC_BYTE_32_CQ_CONS_IDX_S)
struct hns_roce_cqe {
- u32 cqe_byte_4;
+ __le32 cqe_byte_4;
union {
- u32 r_key;
- u32 immediate_data;
+ __le32 r_key;
+ __be32 immediate_data;
};
- u32 byte_cnt;
- u32 cqe_byte_16;
- u32 cqe_byte_20;
- u32 s_mac_l;
- u32 cqe_byte_28;
- u32 reserved;
+ __le32 byte_cnt;
+ __le32 cqe_byte_16;
+ __le32 cqe_byte_20;
+ __le32 s_mac_l;
+ __le32 cqe_byte_28;
+ __le32 reserved;
};
#define CQE_BYTE_4_OWNER_S 7
@@ -308,22 +308,22 @@ struct hns_roce_cqe {
#define CQ_DB_REQ_NOT (1 << 16)
struct hns_roce_v1_mpt_entry {
- u32 mpt_byte_4;
- u32 pbl_addr_l;
- u32 mpt_byte_12;
- u32 virt_addr_l;
- u32 virt_addr_h;
- u32 length;
- u32 mpt_byte_28;
- u32 pa0_l;
- u32 mpt_byte_36;
- u32 mpt_byte_40;
- u32 mpt_byte_44;
- u32 mpt_byte_48;
- u32 pa4_l;
- u32 mpt_byte_56;
- u32 mpt_byte_60;
- u32 mpt_byte_64;
+ __le32 mpt_byte_4;
+ __le32 pbl_addr_l;
+ __le32 mpt_byte_12;
+ __le32 virt_addr_l;
+ __le32 virt_addr_h;
+ __le32 length;
+ __le32 mpt_byte_28;
+ __le32 pa0_l;
+ __le32 mpt_byte_36;
+ __le32 mpt_byte_40;
+ __le32 mpt_byte_44;
+ __le32 mpt_byte_48;
+ __le32 pa4_l;
+ __le32 mpt_byte_56;
+ __le32 mpt_byte_60;
+ __le32 mpt_byte_64;
};
#define MPT_BYTE_4_KEY_STATE_S 0
@@ -408,30 +408,32 @@ struct hns_roce_v1_mpt_entry {
(((1UL << 8) - 1) << MPT_BYTE_64_L_KEY_IDX_H_S)
struct hns_roce_wqe_ctrl_seg {
- __be32 sgl_pa_h;
- __be32 flag;
- __be32 imm_data;
- __be32 msg_length;
+ __le32 sgl_pa_h;
+ __le32 flag;
+ union {
+ __be32 imm_data;
+ __le32 inv_key;
+ };
+ __le32 msg_length;
};
struct hns_roce_wqe_data_seg {
- __be64 addr;
- __be32 lkey;
- __be32 len;
+ __le64 addr;
+ __le32 lkey;
+ __le32 len;
};
struct hns_roce_wqe_raddr_seg {
- __be32 rkey;
- __be32 len;/* reserved */
- __be64 raddr;
+ __le32 rkey;
+ __le32 len;/* reserved */
+ __le64 raddr;
};
struct hns_roce_rq_wqe_ctrl {
-
- u32 rwqe_byte_4;
- u32 rocee_sgl_ba_l;
- u32 rwqe_byte_12;
- u32 reserved[5];
+ __le32 rwqe_byte_4;
+ __le32 rocee_sgl_ba_l;
+ __le32 rwqe_byte_12;
+ __le32 reserved[5];
};
#define RQ_WQE_CTRL_RWQE_BYTE_12_RWQE_SGE_NUM_S 16
@@ -443,31 +445,31 @@ struct hns_roce_rq_wqe_ctrl {
#define GID_LEN 16
struct hns_roce_ud_send_wqe {
- u32 dmac_h;
- u32 u32_8;
- u32 immediate_data;
+ __le32 dmac_h;
+ __le32 u32_8;
+ __le32 immediate_data;
- u32 u32_16;
+ __le32 u32_16;
union {
unsigned char dgid[GID_LEN];
struct {
- u32 u32_20;
- u32 u32_24;
- u32 u32_28;
- u32 u32_32;
+ __le32 u32_20;
+ __le32 u32_24;
+ __le32 u32_28;
+ __le32 u32_32;
};
};
- u32 u32_36;
- u32 u32_40;
+ __le32 u32_36;
+ __le32 u32_40;
- u32 va0_l;
- u32 va0_h;
- u32 l_key0;
+ __le32 va0_l;
+ __le32 va0_h;
+ __le32 l_key0;
- u32 va1_l;
- u32 va1_h;
- u32 l_key1;
+ __le32 va1_l;
+ __le32 va1_h;
+ __le32 l_key1;
};
#define UD_SEND_WQE_U32_4_DMAC_0_S 0
@@ -535,16 +537,16 @@ struct hns_roce_ud_send_wqe {
(((1UL << 8) - 1) << UD_SEND_WQE_U32_40_TRAFFIC_CLASS_S)
struct hns_roce_sqp_context {
- u32 qp1c_bytes_4;
- u32 sq_rq_bt_l;
- u32 qp1c_bytes_12;
- u32 qp1c_bytes_16;
- u32 qp1c_bytes_20;
- u32 cur_rq_wqe_ba_l;
- u32 qp1c_bytes_28;
- u32 qp1c_bytes_32;
- u32 cur_sq_wqe_ba_l;
- u32 qp1c_bytes_40;
+ __le32 qp1c_bytes_4;
+ __le32 sq_rq_bt_l;
+ __le32 qp1c_bytes_12;
+ __le32 qp1c_bytes_16;
+ __le32 qp1c_bytes_20;
+ __le32 cur_rq_wqe_ba_l;
+ __le32 qp1c_bytes_28;
+ __le32 qp1c_bytes_32;
+ __le32 cur_sq_wqe_ba_l;
+ __le32 qp1c_bytes_40;
};
#define QP1C_BYTES_4_QP_STATE_S 0
@@ -626,64 +628,64 @@ struct hns_roce_sqp_context {
#define HNS_ROCE_WQE_OPCODE_MASK (15<<16)
struct hns_roce_qp_context {
- u32 qpc_bytes_4;
- u32 qpc_bytes_8;
- u32 qpc_bytes_12;
- u32 qpc_bytes_16;
- u32 sq_rq_bt_l;
- u32 qpc_bytes_24;
- u32 irrl_ba_l;
- u32 qpc_bytes_32;
- u32 qpc_bytes_36;
- u32 dmac_l;
- u32 qpc_bytes_44;
- u32 qpc_bytes_48;
- u8 dgid[16];
- u32 qpc_bytes_68;
- u32 cur_rq_wqe_ba_l;
- u32 qpc_bytes_76;
- u32 rx_rnr_time;
- u32 qpc_bytes_84;
- u32 qpc_bytes_88;
+ __le32 qpc_bytes_4;
+ __le32 qpc_bytes_8;
+ __le32 qpc_bytes_12;
+ __le32 qpc_bytes_16;
+ __le32 sq_rq_bt_l;
+ __le32 qpc_bytes_24;
+ __le32 irrl_ba_l;
+ __le32 qpc_bytes_32;
+ __le32 qpc_bytes_36;
+ __le32 dmac_l;
+ __le32 qpc_bytes_44;
+ __le32 qpc_bytes_48;
+ u8 dgid[16];
+ __le32 qpc_bytes_68;
+ __le32 cur_rq_wqe_ba_l;
+ __le32 qpc_bytes_76;
+ __le32 rx_rnr_time;
+ __le32 qpc_bytes_84;
+ __le32 qpc_bytes_88;
union {
- u32 rx_sge_len;
- u32 dma_length;
+ __le32 rx_sge_len;
+ __le32 dma_length;
};
union {
- u32 rx_sge_num;
- u32 rx_send_pktn;
- u32 r_key;
+ __le32 rx_sge_num;
+ __le32 rx_send_pktn;
+ __le32 r_key;
};
- u32 va_l;
- u32 va_h;
- u32 qpc_bytes_108;
- u32 qpc_bytes_112;
- u32 rx_cur_sq_wqe_ba_l;
- u32 qpc_bytes_120;
- u32 qpc_bytes_124;
- u32 qpc_bytes_128;
- u32 qpc_bytes_132;
- u32 qpc_bytes_136;
- u32 qpc_bytes_140;
- u32 qpc_bytes_144;
- u32 qpc_bytes_148;
+ __le32 va_l;
+ __le32 va_h;
+ __le32 qpc_bytes_108;
+ __le32 qpc_bytes_112;
+ __le32 rx_cur_sq_wqe_ba_l;
+ __le32 qpc_bytes_120;
+ __le32 qpc_bytes_124;
+ __le32 qpc_bytes_128;
+ __le32 qpc_bytes_132;
+ __le32 qpc_bytes_136;
+ __le32 qpc_bytes_140;
+ __le32 qpc_bytes_144;
+ __le32 qpc_bytes_148;
union {
- u32 rnr_retry;
- u32 ack_time;
+ __le32 rnr_retry;
+ __le32 ack_time;
};
- u32 qpc_bytes_156;
- u32 pkt_use_len;
- u32 qpc_bytes_164;
- u32 qpc_bytes_168;
+ __le32 qpc_bytes_156;
+ __le32 pkt_use_len;
+ __le32 qpc_bytes_164;
+ __le32 qpc_bytes_168;
union {
- u32 sge_use_len;
- u32 pa_use_len;
+ __le32 sge_use_len;
+ __le32 pa_use_len;
};
- u32 qpc_bytes_176;
- u32 qpc_bytes_180;
- u32 tx_cur_sq_wqe_ba_l;
- u32 qpc_bytes_188;
- u32 rvd21;
+ __le32 qpc_bytes_176;
+ __le32 qpc_bytes_180;
+ __le32 tx_cur_sq_wqe_ba_l;
+ __le32 qpc_bytes_188;
+ __le32 rvd21;
};
#define QP_CONTEXT_QPC_BYTES_4_TRANSPORT_SERVICE_TYPE_S 0
@@ -996,8 +998,8 @@ struct hns_roce_qp_context {
#define HCR_GO_BIT 15
struct hns_roce_rq_db {
- u32 u32_4;
- u32 u32_8;
+ __le32 u32_4;
+ __le32 u32_8;
};
#define RQ_DOORBELL_U32_4_RQ_HEAD_S 0
@@ -1013,8 +1015,8 @@ struct hns_roce_rq_db {
#define RQ_DOORBELL_U32_8_HW_SYNC_S 31
struct hns_roce_sq_db {
- u32 u32_4;
- u32 u32_8;
+ __le32 u32_4;
+ __le32 u32_8;
};
#define SQ_DOORBELL_U32_4_SQ_HEAD_S 0
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
index 256fe110107a..db2ff352d75f 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -63,7 +63,8 @@ static int set_rwqe_data_seg(struct ib_qp *ibqp, struct ib_send_wr *wr,
int i;
if (wr->send_flags & IB_SEND_INLINE && wr->num_sge) {
- if (rc_sq_wqe->msg_len > hr_dev->caps.max_sq_inline) {
+ if (le32_to_cpu(rc_sq_wqe->msg_len) >
+ hr_dev->caps.max_sq_inline) {
*bad_wr = wr;
dev_err(hr_dev->dev, "inline len(1-%d)=%d, illegal",
rc_sq_wqe->msg_len, hr_dev->caps.max_sq_inline);
@@ -136,6 +137,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
unsigned long flags;
unsigned int ind;
void *wqe = NULL;
+ u32 tmp_len = 0;
bool loopback;
int ret = 0;
u8 *smac;
@@ -218,9 +220,20 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
HNS_ROCE_V2_WQE_OP_SEND);
for (i = 0; i < wr->num_sge; i++)
- ud_sq_wqe->msg_len += wr->sg_list[i].length;
+ tmp_len += wr->sg_list[i].length;
- ud_sq_wqe->immtdata = send_ieth(wr);
+ ud_sq_wqe->msg_len =
+ cpu_to_le32(le32_to_cpu(ud_sq_wqe->msg_len) + tmp_len);
+
+ switch (wr->opcode) {
+ case IB_WR_SEND_WITH_IMM:
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ ud_sq_wqe->immtdata = wr->ex.imm_data;
+ break;
+ default:
+ ud_sq_wqe->immtdata = 0;
+ break;
+ }
/* Set sig attr */
roce_set_bit(ud_sq_wqe->byte_4,
@@ -254,8 +267,8 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
V2_UD_SEND_WQE_BYTE_24_UDPSPN_M,
V2_UD_SEND_WQE_BYTE_24_UDPSPN_S, 0);
ud_sq_wqe->qkey =
- cpu_to_be32(ud_wr(wr)->remote_qkey & 0x80000000) ?
- qp->qkey : ud_wr(wr)->remote_qkey;
+ cpu_to_le32(ud_wr(wr)->remote_qkey & 0x80000000 ?
+ qp->qkey : ud_wr(wr)->remote_qkey);
roce_set_field(ud_sq_wqe->byte_32,
V2_UD_SEND_WQE_BYTE_32_DQPN_M,
V2_UD_SEND_WQE_BYTE_32_DQPN_S,
@@ -264,7 +277,7 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
roce_set_field(ud_sq_wqe->byte_36,
V2_UD_SEND_WQE_BYTE_36_VLAN_M,
V2_UD_SEND_WQE_BYTE_36_VLAN_S,
- ah->av.vlan);
+ le16_to_cpu(ah->av.vlan));
roce_set_field(ud_sq_wqe->byte_36,
V2_UD_SEND_WQE_BYTE_36_HOPLIMIT_M,
V2_UD_SEND_WQE_BYTE_36_HOPLIMIT_S,
@@ -283,8 +296,8 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
roce_set_field(ud_sq_wqe->byte_40,
V2_UD_SEND_WQE_BYTE_40_SL_M,
V2_UD_SEND_WQE_BYTE_40_SL_S,
- ah->av.sl_tclass_flowlabel >>
- HNS_ROCE_SL_SHIFT);
+ le32_to_cpu(ah->av.sl_tclass_flowlabel) >>
+ HNS_ROCE_SL_SHIFT);
roce_set_field(ud_sq_wqe->byte_40,
V2_UD_SEND_WQE_BYTE_40_PORTN_M,
V2_UD_SEND_WQE_BYTE_40_PORTN_S,
@@ -311,9 +324,24 @@ static int hns_roce_v2_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
rc_sq_wqe = wqe;
memset(rc_sq_wqe, 0, sizeof(*rc_sq_wqe));
for (i = 0; i < wr->num_sge; i++)
- rc_sq_wqe->msg_len += wr->sg_list[i].length;
+ tmp_len += wr->sg_list[i].length;
+
+ rc_sq_wqe->msg_len =
+ cpu_to_le32(le32_to_cpu(rc_sq_wqe->msg_len) + tmp_len);
- rc_sq_wqe->inv_key_immtdata = send_ieth(wr);
+ switch (wr->opcode) {
+ case IB_WR_SEND_WITH_IMM:
+ case IB_WR_RDMA_WRITE_WITH_IMM:
+ rc_sq_wqe->immtdata = wr->ex.imm_data;
+ break;
+ case IB_WR_SEND_WITH_INV:
+ rc_sq_wqe->inv_key =
+ cpu_to_le32(wr->ex.invalidate_rkey);
+ break;
+ default:
+ rc_sq_wqe->immtdata = 0;
+ break;
+ }
roce_set_bit(rc_sq_wqe->byte_4,
V2_RC_SEND_WQE_BYTE_4_FENCE_S,
@@ -451,7 +479,7 @@ out:
roce_set_field(sq_db.parameter, V2_DB_PARAMETER_SL_M,
V2_DB_PARAMETER_SL_S, qp->sl);
- hns_roce_write64_k((__be32 *)&sq_db, qp->sq.db_reg_l);
+ hns_roce_write64_k((__le32 *)&sq_db, qp->sq.db_reg_l);
qp->sq_next_wqe = ind;
qp->next_sge = sge_ind;
@@ -513,7 +541,7 @@ static int hns_roce_v2_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
}
if (i < hr_qp->rq.max_gs) {
- dseg[i].lkey = cpu_to_be32(HNS_ROCE_INVALID_LKEY);
+ dseg[i].lkey = cpu_to_le32(HNS_ROCE_INVALID_LKEY);
dseg[i].addr = 0;
}
@@ -546,7 +574,7 @@ out:
roce_set_field(rq_db.parameter, V2_DB_PARAMETER_CONS_IDX_M,
V2_DB_PARAMETER_CONS_IDX_S, hr_qp->rq.head);
- hns_roce_write64_k((__be32 *)&rq_db, hr_qp->rq.db_reg_l);
+ hns_roce_write64_k((__le32 *)&rq_db, hr_qp->rq.db_reg_l);
}
spin_unlock_irqrestore(&hr_qp->rq.lock, flags);
@@ -2123,10 +2151,10 @@ static void set_access_flags(struct hns_roce_qp *hr_qp,
u8 dest_rd_atomic;
u32 access_flags;
- dest_rd_atomic = !!(attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) ?
+ dest_rd_atomic = (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) ?
attr->max_dest_rd_atomic : hr_qp->resp_depth;
- access_flags = !!(attr_mask & IB_QP_ACCESS_FLAGS) ?
+ access_flags = (attr_mask & IB_QP_ACCESS_FLAGS) ?
attr->qp_access_flags : hr_qp->atomic_rd_en;
if (!dest_rd_atomic)
diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
index 960df095392a..2bf8a47e3de3 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
@@ -224,22 +224,22 @@ enum hns_roce_sgid_type {
};
struct hns_roce_v2_cq_context {
- u32 byte_4_pg_ceqn;
- u32 byte_8_cqn;
- u32 cqe_cur_blk_addr;
- u32 byte_16_hop_addr;
- u32 cqe_nxt_blk_addr;
- u32 byte_24_pgsz_addr;
- u32 byte_28_cq_pi;
- u32 byte_32_cq_ci;
- u32 cqe_ba;
- u32 byte_40_cqe_ba;
- u32 byte_44_db_record;
- u32 db_record_addr;
- u32 byte_52_cqe_cnt;
- u32 byte_56_cqe_period_maxcnt;
- u32 cqe_report_timer;
- u32 byte_64_se_cqe_idx;
+ __le32 byte_4_pg_ceqn;
+ __le32 byte_8_cqn;
+ __le32 cqe_cur_blk_addr;
+ __le32 byte_16_hop_addr;
+ __le32 cqe_nxt_blk_addr;
+ __le32 byte_24_pgsz_addr;
+ __le32 byte_28_cq_pi;
+ __le32 byte_32_cq_ci;
+ __le32 cqe_ba;
+ __le32 byte_40_cqe_ba;
+ __le32 byte_44_db_record;
+ __le32 db_record_addr;
+ __le32 byte_52_cqe_cnt;
+ __le32 byte_56_cqe_period_maxcnt;
+ __le32 cqe_report_timer;
+ __le32 byte_64_se_cqe_idx;
};
#define HNS_ROCE_V2_CQ_DEFAULT_BURST_NUM 0x0
#define HNS_ROCE_V2_CQ_DEFAULT_INTERVAL 0x0
@@ -328,66 +328,66 @@ enum hns_roce_v2_qp_state {
};
struct hns_roce_v2_qp_context {
- u32 byte_4_sqpn_tst;
- u32 wqe_sge_ba;
- u32 byte_12_sq_hop;
- u32 byte_16_buf_ba_pg_sz;
- u32 byte_20_smac_sgid_idx;
- u32 byte_24_mtu_tc;
- u32 byte_28_at_fl;
+ __le32 byte_4_sqpn_tst;
+ __le32 wqe_sge_ba;
+ __le32 byte_12_sq_hop;
+ __le32 byte_16_buf_ba_pg_sz;
+ __le32 byte_20_smac_sgid_idx;
+ __le32 byte_24_mtu_tc;
+ __le32 byte_28_at_fl;
u8 dgid[GID_LEN_V2];
- u32 dmac;
- u32 byte_52_udpspn_dmac;
- u32 byte_56_dqpn_err;
- u32 byte_60_qpst_mapid;
- u32 qkey_xrcd;
- u32 byte_68_rq_db;
- u32 rq_db_record_addr;
- u32 byte_76_srqn_op_en;
- u32 byte_80_rnr_rx_cqn;
- u32 byte_84_rq_ci_pi;
- u32 rq_cur_blk_addr;
- u32 byte_92_srq_info;
- u32 byte_96_rx_reqmsn;
- u32 rq_nxt_blk_addr;
- u32 byte_104_rq_sge;
- u32 byte_108_rx_reqepsn;
- u32 rq_rnr_timer;
- u32 rx_msg_len;
- u32 rx_rkey_pkt_info;
- u64 rx_va;
- u32 byte_132_trrl;
- u32 trrl_ba;
- u32 byte_140_raq;
- u32 byte_144_raq;
- u32 byte_148_raq;
- u32 byte_152_raq;
- u32 byte_156_raq;
- u32 byte_160_sq_ci_pi;
- u32 sq_cur_blk_addr;
- u32 byte_168_irrl_idx;
- u32 byte_172_sq_psn;
- u32 byte_176_msg_pktn;
- u32 sq_cur_sge_blk_addr;
- u32 byte_184_irrl_idx;
- u32 cur_sge_offset;
- u32 byte_192_ext_sge;
- u32 byte_196_sq_psn;
- u32 byte_200_sq_max;
- u32 irrl_ba;
- u32 byte_208_irrl;
- u32 byte_212_lsn;
- u32 sq_timer;
- u32 byte_220_retry_psn_msn;
- u32 byte_224_retry_msg;
- u32 rx_sq_cur_blk_addr;
- u32 byte_232_irrl_sge;
- u32 irrl_cur_sge_offset;
- u32 byte_240_irrl_tail;
- u32 byte_244_rnr_rxack;
- u32 byte_248_ack_psn;
- u32 byte_252_err_txcqn;
- u32 byte_256_sqflush_rqcqe;
+ __le32 dmac;
+ __le32 byte_52_udpspn_dmac;
+ __le32 byte_56_dqpn_err;
+ __le32 byte_60_qpst_mapid;
+ __le32 qkey_xrcd;
+ __le32 byte_68_rq_db;
+ __le32 rq_db_record_addr;
+ __le32 byte_76_srqn_op_en;
+ __le32 byte_80_rnr_rx_cqn;
+ __le32 byte_84_rq_ci_pi;
+ __le32 rq_cur_blk_addr;
+ __le32 byte_92_srq_info;
+ __le32 byte_96_rx_reqmsn;
+ __le32 rq_nxt_blk_addr;
+ __le32 byte_104_rq_sge;
+ __le32 byte_108_rx_reqepsn;
+ __le32 rq_rnr_timer;
+ __le32 rx_msg_len;
+ __le32 rx_rkey_pkt_info;
+ __le64 rx_va;
+ __le32 byte_132_trrl;
+ __le32 trrl_ba;
+ __le32 byte_140_raq;
+ __le32 byte_144_raq;
+ __le32 byte_148_raq;
+ __le32 byte_152_raq;
+ __le32 byte_156_raq;
+ __le32 byte_160_sq_ci_pi;
+ __le32 sq_cur_blk_addr;
+ __le32 byte_168_irrl_idx;
+ __le32 byte_172_sq_psn;
+ __le32 byte_176_msg_pktn;
+ __le32 sq_cur_sge_blk_addr;
+ __le32 byte_184_irrl_idx;
+ __le32 cur_sge_offset;
+ __le32 byte_192_ext_sge;
+ __le32 byte_196_sq_psn;
+ __le32 byte_200_sq_max;
+ __le32 irrl_ba;
+ __le32 byte_208_irrl;
+ __le32 byte_212_lsn;
+ __le32 sq_timer;
+ __le32 byte_220_retry_psn_msn;
+ __le32 byte_224_retry_msg;
+ __le32 rx_sq_cur_blk_addr;
+ __le32 byte_232_irrl_sge;
+ __le32 irrl_cur_sge_offset;
+ __le32 byte_240_irrl_tail;
+ __le32 byte_244_rnr_rxack;
+ __le32 byte_248_ack_psn;
+ __le32 byte_252_err_txcqn;
+ __le32 byte_256_sqflush_rqcqe;
};
#define V2_QPC_BYTE_4_TST_S 0
@@ -761,17 +761,17 @@ struct hns_roce_v2_qp_context {
#define V2_QPC_BYTE_256_SQ_FLUSH_IDX_M GENMASK(31, 16)
struct hns_roce_v2_cqe {
- u32 byte_4;
+ __le32 byte_4;
union {
__le32 rkey;
__be32 immtdata;
};
- u32 byte_12;
- u32 byte_16;
- u32 byte_cnt;
+ __le32 byte_12;
+ __le32 byte_16;
+ __le32 byte_cnt;
u8 smac[4];
- u32 byte_28;
- u32 byte_32;
+ __le32 byte_28;
+ __le32 byte_32;
};
#define V2_CQE_BYTE_4_OPCODE_S 0
@@ -901,8 +901,8 @@ struct hns_roce_v2_mpt_entry {
#define V2_DB_PARAMETER_SL_M GENMASK(18, 16)
struct hns_roce_v2_cq_db {
- u32 byte_4;
- u32 parameter;
+ __le32 byte_4;
+ __le32 parameter;
};
#define V2_CQ_DB_BYTE_4_TAG_S 0
@@ -920,18 +920,18 @@ struct hns_roce_v2_cq_db {
#define V2_CQ_DB_PARAMETER_NOTIFY_S 24
struct hns_roce_v2_ud_send_wqe {
- u32 byte_4;
- u32 msg_len;
- u32 immtdata;
- u32 byte_16;
- u32 byte_20;
- u32 byte_24;
- u32 qkey;
- u32 byte_32;
- u32 byte_36;
- u32 byte_40;
- u32 dmac;
- u32 byte_48;
+ __le32 byte_4;
+ __le32 msg_len;
+ __be32 immtdata;
+ __le32 byte_16;
+ __le32 byte_20;
+ __le32 byte_24;
+ __le32 qkey;
+ __le32 byte_32;
+ __le32 byte_36;
+ __le32 byte_40;
+ __le32 dmac;
+ __le32 byte_48;
u8 dgid[GID_LEN_V2];
};
@@ -1004,13 +1004,16 @@ struct hns_roce_v2_ud_send_wqe {
#define V2_UD_SEND_WQE_BYTE_48_SMAC_INDX_M GENMASK(31, 24)
struct hns_roce_v2_rc_send_wqe {
- u32 byte_4;
- u32 msg_len;
- u32 inv_key_immtdata;
- u32 byte_16;
- u32 byte_20;
- u32 rkey;
- u64 va;
+ __le32 byte_4;
+ __le32 msg_len;
+ union {
+ __le32 inv_key;
+ __be32 immtdata;
+ };
+ __le32 byte_16;
+ __le32 byte_20;
+ __le32 rkey;
+ __le64 va;
};
#define V2_RC_SEND_WQE_BYTE_4_OPCODE_S 0
@@ -1038,14 +1041,14 @@ struct hns_roce_v2_rc_send_wqe {
#define V2_RC_SEND_WQE_BYTE_20_MSG_START_SGE_IDX_M GENMASK(23, 0)
struct hns_roce_v2_wqe_data_seg {
- __be32 len;
- __be32 lkey;
- __be64 addr;
+ __le32 len;
+ __le32 lkey;
+ __le64 addr;
};
struct hns_roce_v2_db {
- u32 byte_4;
- u32 parameter;
+ __le32 byte_4;
+ __le32 parameter;
};
struct hns_roce_query_version {
@@ -1105,12 +1108,12 @@ struct hns_roce_pf_res {
#define PF_RES_DATA_5_PF_EQC_BT_NUM_M GENMASK(25, 16)
struct hns_roce_vf_res_a {
- u32 vf_id;
- u32 vf_qpc_bt_idx_num;
- u32 vf_srqc_bt_idx_num;
- u32 vf_cqc_bt_idx_num;
- u32 vf_mpt_bt_idx_num;
- u32 vf_eqc_bt_idx_num;
+ __le32 vf_id;
+ __le32 vf_qpc_bt_idx_num;
+ __le32 vf_srqc_bt_idx_num;
+ __le32 vf_cqc_bt_idx_num;
+ __le32 vf_mpt_bt_idx_num;
+ __le32 vf_eqc_bt_idx_num;
};
#define VF_RES_A_DATA_1_VF_QPC_BT_IDX_S 0
@@ -1144,11 +1147,11 @@ struct hns_roce_vf_res_a {
#define VF_RES_A_DATA_5_VF_EQC_NUM_M GENMASK(25, 16)
struct hns_roce_vf_res_b {
- u32 rsv0;
- u32 vf_smac_idx_num;
- u32 vf_sgid_idx_num;
- u32 vf_qid_idx_sl_num;
- u32 rsv[2];
+ __le32 rsv0;
+ __le32 vf_smac_idx_num;
+ __le32 vf_sgid_idx_num;
+ __le32 vf_qid_idx_sl_num;
+ __le32 rsv[2];
};
#define VF_RES_B_DATA_0_VF_ID_S 0
@@ -1180,11 +1183,11 @@ struct hns_roce_vf_res_b {
#define ROCEE_VF_SGID_CFG4_SGID_TYPE_M GENMASK(1, 0)
struct hns_roce_cfg_bt_attr {
- u32 vf_qpc_cfg;
- u32 vf_srqc_cfg;
- u32 vf_cqc_cfg;
- u32 vf_mpt_cfg;
- u32 rsv[2];
+ __le32 vf_qpc_cfg;
+ __le32 vf_srqc_cfg;
+ __le32 vf_cqc_cfg;
+ __le32 vf_mpt_cfg;
+ __le32 rsv[2];
};
#define CFG_BT_ATTR_DATA_0_VF_QPC_BA_PGSZ_S 0
@@ -1224,11 +1227,11 @@ struct hns_roce_cfg_bt_attr {
#define CFG_BT_ATTR_DATA_3_VF_MPT_HOPNUM_M GENMASK(9, 8)
struct hns_roce_cmq_desc {
- u16 opcode;
- u16 flag;
- u16 retval;
- u16 rsv;
- u32 data[6];
+ __le16 opcode;
+ __le16 flag;
+ __le16 retval;
+ __le16 rsv;
+ __le32 data[6];
};
#define HNS_ROCE_V2_GO_BIT_TIMEOUT_MSECS 10000
@@ -1274,18 +1277,18 @@ struct hns_roce_v2_priv {
};
struct hns_roce_eq_context {
- u32 byte_4;
- u32 byte_8;
- u32 byte_12;
- u32 eqe_report_timer;
- u32 eqe_ba0;
- u32 eqe_ba1;
- u32 byte_28;
- u32 byte_32;
- u32 byte_36;
- u32 nxt_eqe_ba0;
- u32 nxt_eqe_ba1;
- u32 rsv[5];
+ __le32 byte_4;
+ __le32 byte_8;
+ __le32 byte_12;
+ __le32 eqe_report_timer;
+ __le32 eqe_ba0;
+ __le32 eqe_ba1;
+ __le32 byte_28;
+ __le32 byte_32;
+ __le32 byte_36;
+ __le32 nxt_eqe_ba0;
+ __le32 nxt_eqe_ba1;
+ __le32 rsv[5];
};
#define HNS_ROCE_AEQ_DEFAULT_BURST_NUM 0x0
diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c
index aa0c242ddc50..eb9a69fc7bec 100644
--- a/drivers/infiniband/hw/hns/hns_roce_main.c
+++ b/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -200,7 +200,7 @@ static int hns_roce_query_device(struct ib_device *ib_dev,
memset(props, 0, sizeof(*props));
- props->sys_image_guid = hr_dev->sys_image_guid;
+ props->sys_image_guid = cpu_to_be32(hr_dev->sys_image_guid);
props->max_mr_size = (u64)(~(0ULL));
props->page_size_cap = hr_dev->caps.page_size_cap;
props->vendor_id = hr_dev->vendor_id;
@@ -636,7 +636,6 @@ err_unmap_dmpt:
hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtpt_table);
err_unmap_mtt:
- hns_roce_cleanup_hem_table(hr_dev, &hr_dev->mr_table.mtt_table);
if (hns_roce_check_whether_mhop(hr_dev, HEM_TYPE_CQE))
hns_roce_cleanup_hem_table(hr_dev,
&hr_dev->mr_table.mtt_cqe_table);
diff --git a/drivers/infiniband/hw/hns/hns_roce_qp.c b/drivers/infiniband/hw/hns/hns_roce_qp.c
index 4414cea9ef56..088973a05882 100644
--- a/drivers/infiniband/hw/hns/hns_roce_qp.c
+++ b/drivers/infiniband/hw/hns/hns_roce_qp.c
@@ -512,9 +512,9 @@ static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
hr_qp->ibqp.qp_type = init_attr->qp_type;
if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
- hr_qp->sq_signal_bits = IB_SIGNAL_ALL_WR;
+ hr_qp->sq_signal_bits = cpu_to_le32(IB_SIGNAL_ALL_WR);
else
- hr_qp->sq_signal_bits = IB_SIGNAL_REQ_WR;
+ hr_qp->sq_signal_bits = cpu_to_le32(IB_SIGNAL_REQ_WR);
ret = hns_roce_set_rq_size(hr_dev, &init_attr->cap, !!ib_pd->uobject,
!!init_attr->srq, hr_qp);
@@ -937,20 +937,6 @@ void hns_roce_unlock_cqs(struct hns_roce_cq *send_cq,
}
EXPORT_SYMBOL_GPL(hns_roce_unlock_cqs);
-__be32 send_ieth(struct ib_send_wr *wr)
-{
- switch (wr->opcode) {
- case IB_WR_SEND_WITH_IMM:
- case IB_WR_RDMA_WRITE_WITH_IMM:
- return cpu_to_le32(wr->ex.imm_data);
- case IB_WR_SEND_WITH_INV:
- return cpu_to_le32(wr->ex.invalidate_rkey);
- default:
- return 0;
- }
-}
-EXPORT_SYMBOL_GPL(send_ieth);
-
static void *get_wqe(struct hns_roce_qp *hr_qp, int offset)
{
diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c
index a9c3378bca38..db4bf97c0e15 100644
--- a/drivers/infiniband/hw/qedr/main.c
+++ b/drivers/infiniband/hw/qedr/main.c
@@ -430,59 +430,16 @@ static void qedr_remove_sysfiles(struct qedr_dev *dev)
static void qedr_pci_set_atomic(struct qedr_dev *dev, struct pci_dev *pdev)
{
- struct pci_dev *bridge;
- u32 ctl2, cap2;
- u16 flags;
- int rc;
-
- bridge = pdev->bus->self;
- if (!bridge)
- goto disable;
-
- /* Check atomic routing support all the way to root complex */
- while (bridge->bus->parent) {
- rc = pcie_capability_read_word(bridge, PCI_EXP_FLAGS, &flags);
- if (rc || ((flags & PCI_EXP_FLAGS_VERS) < 2))
- goto disable;
-
- rc = pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap2);
- if (rc)
- goto disable;
+ int rc = pci_enable_atomic_ops_to_root(pdev,
+ PCI_EXP_DEVCAP2_ATOMIC_COMP64);
- rc = pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, &ctl2);
- if (rc)
- goto disable;
-
- if (!(cap2 & PCI_EXP_DEVCAP2_ATOMIC_ROUTE) ||
- (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK))
- goto disable;
- bridge = bridge->bus->parent->self;
+ if (rc) {
+ dev->atomic_cap = IB_ATOMIC_NONE;
+ DP_DEBUG(dev, QEDR_MSG_INIT, "Atomic capability disabled\n");
+ } else {
+ dev->atomic_cap = IB_ATOMIC_GLOB;
+ DP_DEBUG(dev, QEDR_MSG_INIT, "Atomic capability enabled\n");
}
-
- rc = pcie_capability_read_word(bridge, PCI_EXP_FLAGS, &flags);
- if (rc || ((flags & PCI_EXP_FLAGS_VERS) < 2))
- goto disable;
-
- rc = pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap2);
- if (rc || !(cap2 & PCI_EXP_DEVCAP2_ATOMIC_COMP64))
- goto disable;
-
- /* Set atomic operations */
- pcie_capability_set_word(pdev, PCI_EXP_DEVCTL2,
- PCI_EXP_DEVCTL2_ATOMIC_REQ);
- dev->atomic_cap = IB_ATOMIC_GLOB;
-
- DP_DEBUG(dev, QEDR_MSG_INIT, "Atomic capability enabled\n");
-
- return;
-
-disable:
- pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL2,
- PCI_EXP_DEVCTL2_ATOMIC_REQ);
- dev->atomic_cap = IB_ATOMIC_NONE;
-
- DP_DEBUG(dev, QEDR_MSG_INIT, "Atomic capability disabled\n");
-
}
static const struct qed_rdma_ops *qed_ops;
diff --git a/drivers/infiniband/hw/qib/qib_rc.c b/drivers/infiniband/hw/qib/qib_rc.c
index cfddff45413f..c9955d48c50f 100644
--- a/drivers/infiniband/hw/qib/qib_rc.c
+++ b/drivers/infiniband/hw/qib/qib_rc.c
@@ -1913,8 +1913,7 @@ send_last:
wc.port_num = 0;
/* Signal completion event if the solicited bit is set. */
rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
- (ohdr->bth[0] &
- cpu_to_be32(IB_BTH_SOLICITED)) != 0);
+ ib_bth_is_solicited(ohdr));
break;
case OP(RDMA_WRITE_FIRST):
diff --git a/drivers/infiniband/hw/qib/qib_uc.c b/drivers/infiniband/hw/qib/qib_uc.c
index 70c58b88192c..840eec6ebc33 100644
--- a/drivers/infiniband/hw/qib/qib_uc.c
+++ b/drivers/infiniband/hw/qib/qib_uc.c
@@ -401,8 +401,7 @@ last_imm:
wc.port_num = 0;
/* Signal completion event if the solicited bit is set. */
rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
- (ohdr->bth[0] &
- cpu_to_be32(IB_BTH_SOLICITED)) != 0);
+ ib_bth_is_solicited(ohdr));
break;
case OP(RDMA_WRITE_FIRST):
diff --git a/drivers/infiniband/hw/qib/qib_ud.c b/drivers/infiniband/hw/qib/qib_ud.c
index 386c3c4da0c7..3e4ff77260c2 100644
--- a/drivers/infiniband/hw/qib/qib_ud.c
+++ b/drivers/infiniband/hw/qib/qib_ud.c
@@ -579,8 +579,7 @@ void qib_ud_rcv(struct qib_ibport *ibp, struct ib_header *hdr,
wc.port_num = qp->port_num;
/* Signal completion event if the solicited bit is set. */
rvt_cq_enter(ibcq_to_rvtcq(qp->ibqp.recv_cq), &wc,
- (ohdr->bth[0] &
- cpu_to_be32(IB_BTH_SOLICITED)) != 0);
+ ib_bth_is_solicited(ohdr));
return;
drop:
diff --git a/drivers/infiniband/sw/rxe/rxe_av.c b/drivers/infiniband/sw/rxe/rxe_av.c
index 1cc9e2e1365d..7522d1af3ae2 100644
--- a/drivers/infiniband/sw/rxe/rxe_av.c
+++ b/drivers/infiniband/sw/rxe/rxe_av.c
@@ -52,28 +52,24 @@ int rxe_av_chk_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr)
return 0;
}
-int rxe_av_from_attr(struct rxe_dev *rxe, u8 port_num,
- struct rxe_av *av, struct rdma_ah_attr *attr)
+void rxe_av_from_attr(u8 port_num, struct rxe_av *av,
+ struct rdma_ah_attr *attr)
{
memset(av, 0, sizeof(*av));
memcpy(&av->grh, rdma_ah_read_grh(attr),
sizeof(*rdma_ah_read_grh(attr)));
av->port_num = port_num;
- return 0;
}
-int rxe_av_to_attr(struct rxe_dev *rxe, struct rxe_av *av,
- struct rdma_ah_attr *attr)
+void rxe_av_to_attr(struct rxe_av *av, struct rdma_ah_attr *attr)
{
attr->type = RDMA_AH_ATTR_TYPE_ROCE;
memcpy(rdma_ah_retrieve_grh(attr), &av->grh, sizeof(av->grh));
rdma_ah_set_ah_flags(attr, IB_AH_GRH);
rdma_ah_set_port_num(attr, av->port_num);
- return 0;
}
-int rxe_av_fill_ip_info(struct rxe_dev *rxe,
- struct rxe_av *av,
+void rxe_av_fill_ip_info(struct rxe_av *av,
struct rdma_ah_attr *attr,
struct ib_gid_attr *sgid_attr,
union ib_gid *sgid)
@@ -81,8 +77,6 @@ int rxe_av_fill_ip_info(struct rxe_dev *rxe,
rdma_gid2ip(&av->sgid_addr._sockaddr, sgid);
rdma_gid2ip(&av->dgid_addr._sockaddr, &rdma_ah_read_grh(attr)->dgid);
av->network_type = ib_gid_to_network_type(sgid_attr->gid_type, sgid);
-
- return 0;
}
struct rxe_av *rxe_get_av(struct rxe_pkt_info *pkt)
diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
index 96c3a6c5c4b5..4ef75d5b729b 100644
--- a/drivers/infiniband/sw/rxe/rxe_loc.h
+++ b/drivers/infiniband/sw/rxe/rxe_loc.h
@@ -38,14 +38,12 @@
int rxe_av_chk_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr);
-int rxe_av_from_attr(struct rxe_dev *rxe, u8 port_num,
- struct rxe_av *av, struct rdma_ah_attr *attr);
+void rxe_av_from_attr(u8 port_num, struct rxe_av *av,
+ struct rdma_ah_attr *attr);
-int rxe_av_to_attr(struct rxe_dev *rxe, struct rxe_av *av,
- struct rdma_ah_attr *attr);
+void rxe_av_to_attr(struct rxe_av *av, struct rdma_ah_attr *attr);
-int rxe_av_fill_ip_info(struct rxe_dev *rxe,
- struct rxe_av *av,
+void rxe_av_fill_ip_info(struct rxe_av *av,
struct rdma_ah_attr *attr,
struct ib_gid_attr *sgid_attr,
union ib_gid *sgid);
diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
index 137d6c0c49d4..2fcf1cab7678 100644
--- a/drivers/infiniband/sw/rxe/rxe_qp.c
+++ b/drivers/infiniband/sw/rxe/rxe_qp.c
@@ -633,9 +633,8 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask,
ib_get_cached_gid(&rxe->ib_dev, 1,
rdma_ah_read_grh(&attr->ah_attr)->sgid_index,
&sgid, &sgid_attr);
- rxe_av_from_attr(rxe, attr->port_num, &qp->pri_av,
- &attr->ah_attr);
- rxe_av_fill_ip_info(rxe, &qp->pri_av, &attr->ah_attr,
+ rxe_av_from_attr(attr->port_num, &qp->pri_av, &attr->ah_attr);
+ rxe_av_fill_ip_info(&qp->pri_av, &attr->ah_attr,
&sgid_attr, &sgid);
if (sgid_attr.ndev)
dev_put(sgid_attr.ndev);
@@ -648,9 +647,9 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask,
ib_get_cached_gid(&rxe->ib_dev, 1, sgid_index,
&sgid, &sgid_attr);
- rxe_av_from_attr(rxe, attr->alt_port_num, &qp->alt_av,
+ rxe_av_from_attr(attr->alt_port_num, &qp->alt_av,
&attr->alt_ah_attr);
- rxe_av_fill_ip_info(rxe, &qp->alt_av, &attr->alt_ah_attr,
+ rxe_av_fill_ip_info(&qp->alt_av, &attr->alt_ah_attr,
&sgid_attr, &sgid);
if (sgid_attr.ndev)
dev_put(sgid_attr.ndev);
@@ -765,8 +764,6 @@ int rxe_qp_from_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask,
/* called by the query qp verb */
int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask)
{
- struct rxe_dev *rxe = to_rdev(qp->ibqp.device);
-
*attr = qp->attr;
attr->rq_psn = qp->resp.psn;
@@ -781,8 +778,8 @@ int rxe_qp_to_attr(struct rxe_qp *qp, struct ib_qp_attr *attr, int mask)
attr->cap.max_recv_sge = qp->rq.max_sge;
}
- rxe_av_to_attr(rxe, &qp->pri_av, &attr->ah_attr);
- rxe_av_to_attr(rxe, &qp->alt_av, &attr->alt_ah_attr);
+ rxe_av_to_attr(&qp->pri_av, &attr->ah_attr);
+ rxe_av_to_attr(&qp->alt_av, &attr->alt_ah_attr);
if (qp->req.state == QP_STATE_DRAIN) {
attr->sq_draining = 1;
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 7210a784abb4..f4bab2cd0ec2 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -271,13 +271,12 @@ static int rxe_init_av(struct rxe_dev *rxe, struct rdma_ah_attr *attr,
return err;
}
- err = rxe_av_from_attr(rxe, rdma_ah_get_port_num(attr), av, attr);
- if (!err)
- err = rxe_av_fill_ip_info(rxe, av, attr, &sgid_attr, &sgid);
+ rxe_av_from_attr(rdma_ah_get_port_num(attr), av, attr);
+ rxe_av_fill_ip_info(av, attr, &sgid_attr, &sgid);
if (sgid_attr.ndev)
dev_put(sgid_attr.ndev);
- return err;
+ return 0;
}
static struct ib_ah *rxe_create_ah(struct ib_pd *ibpd,
@@ -335,12 +334,11 @@ static int rxe_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
static int rxe_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr)
{
- struct rxe_dev *rxe = to_rdev(ibah->device);
struct rxe_ah *ah = to_rah(ibah);
memset(attr, 0, sizeof(*attr));
attr->type = ibah->type;
- rxe_av_to_attr(rxe, &ah->av, attr);
+ rxe_av_to_attr(&ah->av, attr);
return 0;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 5930c7d9a8fb..161ba8c76285 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -2306,6 +2306,9 @@ static struct net_device *ipoib_add_port(const char *format,
priv->ca, ipoib_event);
ib_register_event_handler(&priv->event_handler);
+ /* call event handler to ensure pkey in sync */
+ queue_work(ipoib_workqueue, &priv->flush_heavy);
+
result = register_netdev(priv->dev);
if (result) {
pr_warn("%s: couldn't register ipoib port %d; error %d\n",
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 97baf88d9505..fba4ec168bd5 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -527,7 +527,8 @@ static void amd_iommu_report_page_fault(u16 devid, u16 domain_id,
struct iommu_dev_data *dev_data = NULL;
struct pci_dev *pdev;
- pdev = pci_get_bus_and_slot(PCI_BUS_NUM(devid), devid & 0xff);
+ pdev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(devid),
+ devid & 0xff);
if (pdev)
dev_data = get_dev_data(&pdev->dev);
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 6fe2d0346073..4e4a615bf13f 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -1697,8 +1697,8 @@ static int iommu_init_pci(struct amd_iommu *iommu)
u32 range, misc, low, high;
int ret;
- iommu->dev = pci_get_bus_and_slot(PCI_BUS_NUM(iommu->devid),
- iommu->devid & 0xff);
+ iommu->dev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(iommu->devid),
+ iommu->devid & 0xff);
if (!iommu->dev)
return -ENODEV;
@@ -1764,8 +1764,9 @@ static int iommu_init_pci(struct amd_iommu *iommu)
if (is_rd890_iommu(iommu->dev)) {
int i, j;
- iommu->root_pdev = pci_get_bus_and_slot(iommu->dev->bus->number,
- PCI_DEVFN(0, 0));
+ iommu->root_pdev =
+ pci_get_domain_bus_and_slot(0, iommu->dev->bus->number,
+ PCI_DEVFN(0, 0));
/*
* Some rd890 systems may not be fully reconfigured by the
diff --git a/drivers/iommu/amd_iommu_v2.c b/drivers/iommu/amd_iommu_v2.c
index df72493a0f13..1d0b53a04a08 100644
--- a/drivers/iommu/amd_iommu_v2.c
+++ b/drivers/iommu/amd_iommu_v2.c
@@ -565,7 +565,8 @@ static int ppr_notifier(struct notifier_block *nb, unsigned long e, void *data)
finish = (iommu_fault->tag >> 9) & 1;
devid = iommu_fault->device_id;
- pdev = pci_get_bus_and_slot(PCI_BUS_NUM(devid), devid & 0xff);
+ pdev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(devid),
+ devid & 0xff);
if (!pdev)
return -ENODEV;
dev_data = get_dev_data(&pdev->dev);
diff --git a/drivers/irqchip/irq-i8259.c b/drivers/irqchip/irq-i8259.c
index 7aafbb091b67..b0d4aab1a58c 100644
--- a/drivers/irqchip/irq-i8259.c
+++ b/drivers/irqchip/irq-i8259.c
@@ -289,14 +289,14 @@ static struct resource pic1_io_resource = {
.name = "pic1",
.start = PIC_MASTER_CMD,
.end = PIC_MASTER_IMR,
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
};
static struct resource pic2_io_resource = {
.name = "pic2",
.start = PIC_SLAVE_CMD,
.end = PIC_SLAVE_IMR,
- .flags = IORESOURCE_BUSY
+ .flags = IORESOURCE_IO | IORESOURCE_BUSY
};
static int i8259A_irq_domain_map(struct irq_domain *d, unsigned int virq,
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index e8b29fc532e1..08849e33c567 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -1799,7 +1799,7 @@ static int powerbook_sleep_grackle(void)
struct adb_request req;
struct pci_dev *grackle;
- grackle = pci_get_bus_and_slot(0, 0);
+ grackle = pci_get_domain_bus_and_slot(0, 0, 0);
if (!grackle)
return -ENODEV;
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index edfe99b22d56..145e12bfb819 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -80,11 +80,11 @@ config MEDIA_SDR_SUPPORT
config MEDIA_CEC_SUPPORT
bool "HDMI CEC support"
---help---
- Enable support for HDMI CEC (Consumer Electronics Control),
- which is an optional HDMI feature.
+ Enable support for HDMI CEC (Consumer Electronics Control),
+ which is an optional HDMI feature.
- Say Y when you have an HDMI receiver, transmitter or a USB CEC
- adapter that supports HDMI CEC.
+ Say Y when you have an HDMI receiver, transmitter or a USB CEC
+ adapter that supports HDMI CEC.
source "drivers/media/cec/Kconfig"
@@ -144,6 +144,18 @@ config DVB_CORE
default y
select CRC32
+config DVB_MMAP
+ bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
+ depends on DVB_CORE
+ default n
+ help
+ This option enables DVB experimental memory-mapped API, with
+ reduces the number of context switches to read DVB buffers, as
+ the buffers can use mmap() syscalls.
+
+ Support for it is experimental. Use with care. If unsure,
+ say N.
+
config DVB_NET
bool "DVB Network Support"
default (NET && INET)
diff --git a/drivers/media/cec/cec-adap.c b/drivers/media/cec/cec-adap.c
index 98f88c43f62c..2b1e540587d6 100644
--- a/drivers/media/cec/cec-adap.c
+++ b/drivers/media/cec/cec-adap.c
@@ -540,7 +540,7 @@ void cec_transmit_done_ts(struct cec_adapter *adap, u8 status,
unsigned int attempts_made = arb_lost_cnt + nack_cnt +
low_drive_cnt + error_cnt;
- dprintk(2, "%s: status %02x\n", __func__, status);
+ dprintk(2, "%s: status 0x%02x\n", __func__, status);
if (attempts_made < 1)
attempts_made = 1;
@@ -1788,9 +1788,6 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
int la_idx = cec_log_addr2idx(adap, dest_laddr);
bool from_unregistered = init_laddr == 0xf;
struct cec_msg tx_cec_msg = { };
-#ifdef CONFIG_MEDIA_CEC_RC
- int scancode;
-#endif
dprintk(2, "%s: %*ph\n", __func__, msg->len, msg->msg);
@@ -1886,9 +1883,11 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
*/
case 0x60:
if (msg->len == 2)
- scancode = msg->msg[2];
+ rc_keydown(adap->rc, RC_PROTO_CEC,
+ msg->msg[2], 0);
else
- scancode = msg->msg[2] << 8 | msg->msg[3];
+ rc_keydown(adap->rc, RC_PROTO_CEC,
+ msg->msg[2] << 8 | msg->msg[3], 0);
break;
/*
* Other function messages that are not handled.
@@ -1901,54 +1900,11 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
*/
case 0x56: case 0x57:
case 0x67: case 0x68: case 0x69: case 0x6a:
- scancode = -1;
break;
default:
- scancode = msg->msg[2];
- break;
- }
-
- /* Was repeating, but keypress timed out */
- if (adap->rc_repeating && !adap->rc->keypressed) {
- adap->rc_repeating = false;
- adap->rc_last_scancode = -1;
- }
- /* Different keypress from last time, ends repeat mode */
- if (adap->rc_last_scancode != scancode) {
- rc_keyup(adap->rc);
- adap->rc_repeating = false;
- }
- /* We can't handle this scancode */
- if (scancode < 0) {
- adap->rc_last_scancode = scancode;
- break;
- }
-
- /* Send key press */
- rc_keydown(adap->rc, RC_PROTO_CEC, scancode, 0);
-
- /* When in repeating mode, we're done */
- if (adap->rc_repeating)
- break;
-
- /*
- * We are not repeating, but the new scancode is
- * the same as the last one, and this second key press is
- * within 550 ms (the 'Follower Safety Timeout') from the
- * previous key press, so we now enable the repeating mode.
- */
- if (adap->rc_last_scancode == scancode &&
- msg->rx_ts - adap->rc_last_keypress < 550 * NSEC_PER_MSEC) {
- adap->rc_repeating = true;
+ rc_keydown(adap->rc, RC_PROTO_CEC, msg->msg[2], 0);
break;
}
- /*
- * Not in repeating mode, so avoid triggering repeat mode
- * by calling keyup.
- */
- rc_keyup(adap->rc);
- adap->rc_last_scancode = scancode;
- adap->rc_last_keypress = msg->rx_ts;
#endif
break;
@@ -1958,8 +1914,6 @@ static int cec_receive_notify(struct cec_adapter *adap, struct cec_msg *msg,
break;
#ifdef CONFIG_MEDIA_CEC_RC
rc_keyup(adap->rc);
- adap->rc_repeating = false;
- adap->rc_last_scancode = -1;
#endif
break;
@@ -2053,6 +2007,29 @@ void cec_monitor_all_cnt_dec(struct cec_adapter *adap)
WARN_ON(call_op(adap, adap_monitor_all_enable, 0));
}
+/*
+ * Helper functions to keep track of the 'monitor pin' use count.
+ *
+ * These functions are called with adap->lock held.
+ */
+int cec_monitor_pin_cnt_inc(struct cec_adapter *adap)
+{
+ int ret = 0;
+
+ if (adap->monitor_pin_cnt == 0)
+ ret = call_op(adap, adap_monitor_pin_enable, 1);
+ if (ret == 0)
+ adap->monitor_pin_cnt++;
+ return ret;
+}
+
+void cec_monitor_pin_cnt_dec(struct cec_adapter *adap)
+{
+ adap->monitor_pin_cnt--;
+ if (adap->monitor_pin_cnt == 0)
+ WARN_ON(call_op(adap, adap_monitor_pin_enable, 0));
+}
+
#ifdef CONFIG_DEBUG_FS
/*
* Log the current state of the CEC adapter.
diff --git a/drivers/media/cec/cec-api.c b/drivers/media/cec/cec-api.c
index 9d6c496f756c..ecc89d9a279b 100644
--- a/drivers/media/cec/cec-api.c
+++ b/drivers/media/cec/cec-api.c
@@ -46,12 +46,11 @@ static inline struct cec_devnode *cec_devnode_data(struct file *filp)
static __poll_t cec_poll(struct file *filp,
struct poll_table_struct *poll)
{
- struct cec_devnode *devnode = cec_devnode_data(filp);
struct cec_fh *fh = filp->private_data;
struct cec_adapter *adap = fh->adap;
__poll_t res = 0;
- if (!devnode->registered)
+ if (!cec_is_registered(adap))
return POLLERR | POLLHUP;
mutex_lock(&adap->lock);
if (adap->is_configured &&
@@ -354,6 +353,7 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
u32 mode;
u8 mode_initiator;
u8 mode_follower;
+ bool send_pin_event = false;
long err = 0;
if (copy_from_user(&mode, parg, sizeof(mode)))
@@ -433,6 +433,19 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
}
}
+ if (!err) {
+ bool old_mon_pin = fh->mode_follower == CEC_MODE_MONITOR_PIN;
+ bool new_mon_pin = mode_follower == CEC_MODE_MONITOR_PIN;
+
+ if (old_mon_pin != new_mon_pin) {
+ send_pin_event = new_mon_pin;
+ if (new_mon_pin)
+ err = cec_monitor_pin_cnt_inc(adap);
+ else
+ cec_monitor_pin_cnt_dec(adap);
+ }
+ }
+
if (err) {
mutex_unlock(&adap->lock);
return err;
@@ -440,11 +453,9 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
if (fh->mode_follower == CEC_MODE_FOLLOWER)
adap->follower_cnt--;
- if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
- adap->monitor_pin_cnt--;
if (mode_follower == CEC_MODE_FOLLOWER)
adap->follower_cnt++;
- if (mode_follower == CEC_MODE_MONITOR_PIN) {
+ if (send_pin_event) {
struct cec_event ev = {
.flags = CEC_EVENT_FL_INITIAL_STATE,
};
@@ -452,7 +463,6 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
ev.event = adap->cec_pin_is_high ? CEC_EVENT_PIN_CEC_HIGH :
CEC_EVENT_PIN_CEC_LOW;
cec_queue_event_fh(fh, &ev, 0);
- adap->monitor_pin_cnt++;
}
if (mode_follower == CEC_MODE_EXCL_FOLLOWER ||
mode_follower == CEC_MODE_EXCL_FOLLOWER_PASSTHRU) {
@@ -475,13 +485,12 @@ static long cec_s_mode(struct cec_adapter *adap, struct cec_fh *fh,
static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
- struct cec_devnode *devnode = cec_devnode_data(filp);
struct cec_fh *fh = filp->private_data;
struct cec_adapter *adap = fh->adap;
bool block = !(filp->f_flags & O_NONBLOCK);
void __user *parg = (void __user *)arg;
- if (!devnode->registered)
+ if (!cec_is_registered(adap))
return -ENODEV;
switch (cmd) {
@@ -608,16 +617,15 @@ static int cec_release(struct inode *inode, struct file *filp)
if (fh->mode_follower == CEC_MODE_FOLLOWER)
adap->follower_cnt--;
if (fh->mode_follower == CEC_MODE_MONITOR_PIN)
- adap->monitor_pin_cnt--;
+ cec_monitor_pin_cnt_dec(adap);
if (fh->mode_follower == CEC_MODE_MONITOR_ALL)
cec_monitor_all_cnt_dec(adap);
mutex_unlock(&adap->lock);
mutex_lock(&devnode->lock);
list_del(&fh->list);
- if (list_empty(&devnode->fhs) &&
- !adap->needs_hpd &&
- adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
+ if (cec_is_registered(adap) && list_empty(&devnode->fhs) &&
+ !adap->needs_hpd && adap->phys_addr == CEC_PHYS_ADDR_INVALID) {
WARN_ON(adap->ops->adap_enable(adap, false));
}
mutex_unlock(&devnode->lock);
diff --git a/drivers/media/cec/cec-core.c b/drivers/media/cec/cec-core.c
index 5870da6a567f..a9f9525db9ae 100644
--- a/drivers/media/cec/cec-core.c
+++ b/drivers/media/cec/cec-core.c
@@ -160,8 +160,9 @@ clr_bit:
* This function can safely be called if the device node has never been
* registered or has already been unregistered.
*/
-static void cec_devnode_unregister(struct cec_devnode *devnode)
+static void cec_devnode_unregister(struct cec_adapter *adap)
{
+ struct cec_devnode *devnode = &adap->devnode;
struct cec_fh *fh;
mutex_lock(&devnode->lock);
@@ -179,6 +180,11 @@ static void cec_devnode_unregister(struct cec_devnode *devnode)
devnode->unregistered = true;
mutex_unlock(&devnode->lock);
+ mutex_lock(&adap->lock);
+ __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
+ __cec_s_log_addrs(adap, NULL, false);
+ mutex_unlock(&adap->lock);
+
cdev_device_del(&devnode->cdev, &devnode->dev);
put_device(&devnode->dev);
}
@@ -192,7 +198,7 @@ static void cec_cec_notify(struct cec_adapter *adap, u16 pa)
void cec_register_cec_notifier(struct cec_adapter *adap,
struct cec_notifier *notifier)
{
- if (WARN_ON(!adap->devnode.registered))
+ if (WARN_ON(!cec_is_registered(adap)))
return;
adap->notifier = notifier;
@@ -280,7 +286,6 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
adap->rc->priv = adap;
adap->rc->map_name = RC_MAP_CEC;
adap->rc->timeout = MS_TO_NS(100);
- adap->rc_last_scancode = -1;
#endif
return adap;
}
@@ -312,17 +317,6 @@ int cec_register_adapter(struct cec_adapter *adap,
adap->rc = NULL;
return res;
}
- /*
- * The REP_DELAY for CEC is really the time between the initial
- * 'User Control Pressed' message and the second. The first
- * keypress is always seen as non-repeating, the second
- * (provided it has the same UI Command) will start the 'Press
- * and Hold' (aka repeat) behavior. By setting REP_DELAY to the
- * same value as REP_PERIOD the expected CEC behavior is
- * reproduced.
- */
- adap->rc->input_dev->rep[REP_DELAY] =
- adap->rc->input_dev->rep[REP_PERIOD];
}
#endif
@@ -373,7 +367,7 @@ void cec_unregister_adapter(struct cec_adapter *adap)
if (adap->notifier)
cec_notifier_unregister(adap->notifier);
#endif
- cec_devnode_unregister(&adap->devnode);
+ cec_devnode_unregister(adap);
}
EXPORT_SYMBOL_GPL(cec_unregister_adapter);
@@ -381,9 +375,6 @@ void cec_delete_adapter(struct cec_adapter *adap)
{
if (IS_ERR_OR_NULL(adap))
return;
- mutex_lock(&adap->lock);
- __cec_s_phys_addr(adap, CEC_PHYS_ADDR_INVALID, false);
- mutex_unlock(&adap->lock);
kthread_stop(adap->kthread);
if (adap->kthread_config)
kthread_stop(adap->kthread_config);
diff --git a/drivers/media/cec/cec-priv.h b/drivers/media/cec/cec-priv.h
index 70767a7900f2..daf597643af8 100644
--- a/drivers/media/cec/cec-priv.h
+++ b/drivers/media/cec/cec-priv.h
@@ -40,6 +40,8 @@ void cec_put_device(struct cec_devnode *devnode);
/* cec-adap.c */
int cec_monitor_all_cnt_inc(struct cec_adapter *adap);
void cec_monitor_all_cnt_dec(struct cec_adapter *adap);
+int cec_monitor_pin_cnt_inc(struct cec_adapter *adap);
+void cec_monitor_pin_cnt_dec(struct cec_adapter *adap);
int cec_adap_status(struct seq_file *file, void *priv);
int cec_thread_func(void *_adap);
void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block);
diff --git a/drivers/media/common/Kconfig b/drivers/media/common/Kconfig
index 326df0ad75c0..0cb7d819a5d2 100644
--- a/drivers/media/common/Kconfig
+++ b/drivers/media/common/Kconfig
@@ -16,6 +16,7 @@ config CYPRESS_FIRMWARE
tristate "Cypress firmware helper routines"
depends on USB
+source "drivers/media/common/videobuf2/Kconfig"
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 2d1b0a025084..e7bc17abbbbc 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1,4 +1,4 @@
-obj-y += b2c2/ saa7146/ siano/ v4l2-tpg/
+obj-y += b2c2/ saa7146/ siano/ v4l2-tpg/ videobuf2/
obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
obj-$(CONFIG_CYPRESS_FIRMWARE) += cypress_firmware.o
diff --git a/drivers/media/common/b2c2/Makefile b/drivers/media/common/b2c2/Makefile
index 73df4a334eda..aa2dc2434ee5 100644
--- a/drivers/media/common/b2c2/Makefile
+++ b/drivers/media/common/b2c2/Makefile
@@ -4,6 +4,5 @@ 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/common/b2c2/flexcop-common.h b/drivers/media/common/b2c2/flexcop-common.h
index b7e5e4c17acb..f944c59cf495 100644
--- a/drivers/media/common/b2c2/flexcop-common.h
+++ b/drivers/media/common/b2c2/flexcop-common.h
@@ -13,10 +13,10 @@
#include "flexcop-reg.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dvb_frontend.h"
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dvb_frontend.h>
#define FC_MAX_FEED 256
diff --git a/drivers/media/common/saa7146/saa7146_video.c b/drivers/media/common/saa7146/saa7146_video.c
index 2b631eaa65b3..0dfa0c09d646 100644
--- a/drivers/media/common/saa7146/saa7146_video.c
+++ b/drivers/media/common/saa7146/saa7146_video.c
@@ -4,6 +4,7 @@
#include <media/v4l2-event.h>
#include <media/v4l2-ctrls.h>
#include <linux/module.h>
+#include <linux/kernel.h>
static int max_memory = 32;
@@ -86,13 +87,11 @@ static struct saa7146_format formats[] = {
due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped
(like V4L2_PIX_FMT_YUYV) ... 8-( */
-static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
-
struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc)
{
- int i, j = NUM_FORMATS;
+ int i;
- for (i = 0; i < j; i++) {
+ for (i = 0; i < ARRAY_SIZE(formats); i++) {
if (formats[i].pixelformat == fourcc) {
return formats+i;
}
@@ -524,7 +523,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuf
static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
{
- if (f->index >= NUM_FORMATS)
+ if (f->index >= ARRAY_SIZE(formats))
return -EINVAL;
strlcpy((char *)f->description, formats[f->index].name,
sizeof(f->description));
@@ -1002,9 +1001,9 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
.vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
.vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
- .vidioc_overlay = vidioc_overlay,
- .vidioc_g_fbuf = vidioc_g_fbuf,
- .vidioc_s_fbuf = vidioc_s_fbuf,
+ .vidioc_overlay = vidioc_overlay,
+ .vidioc_g_fbuf = vidioc_g_fbuf,
+ .vidioc_s_fbuf = vidioc_s_fbuf,
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
@@ -1013,7 +1012,7 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
.vidioc_s_std = vidioc_s_std,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_parm = vidioc_g_parm,
+ .vidioc_g_parm = vidioc_g_parm,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
diff --git a/drivers/media/common/siano/Makefile b/drivers/media/common/siano/Makefile
index 88e2b7ffc537..b33022e0be56 100644
--- a/drivers/media/common/siano/Makefile
+++ b/drivers/media/common/siano/Makefile
@@ -11,7 +11,3 @@ endif
ifeq ($(CONFIG_SMS_SIANO_DEBUGFS),y)
smsdvb-objs += smsdvb-debugfs.o
endif
-
-ccflags-y += -Idrivers/media/dvb-core
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
-
diff --git a/drivers/media/common/siano/smsdvb-debugfs.c b/drivers/media/common/siano/smsdvb-debugfs.c
index 0c0878bcf251..403645fe9079 100644
--- a/drivers/media/common/siano/smsdvb-debugfs.c
+++ b/drivers/media/common/siano/smsdvb-debugfs.c
@@ -1,21 +1,6 @@
-/***********************************************************************
- *
- * Copyright(c) 2013 Mauro Carvalho Chehab
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- ***********************************************************************/
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright(c) 2013 Mauro Carvalho Chehab
#include "smscoreapi.h"
@@ -26,10 +11,10 @@
#include <linux/spinlock.h>
#include <linux/usb.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
#include "smsdvb.h"
diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c
index affde1426b7a..c0faad1ba428 100644
--- a/drivers/media/common/siano/smsdvb-main.c
+++ b/drivers/media/common/siano/smsdvb-main.c
@@ -26,10 +26,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <linux/init.h>
#include <asm/div64.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
#include "sms-cards.h"
@@ -271,7 +271,7 @@ static void smsdvb_update_per_slices(struct smsdvb_client_t *client,
c->post_bit_count.stat[0].uvalue += p->ber_bit_count;
/* Legacy PER/BER */
- tmp = p->ets_packets * 65535;
+ tmp = p->ets_packets * 65535ULL;
if (p->ts_packets + p->ets_packets)
do_div(tmp, p->ts_packets + p->ets_packets);
client->legacy_per = tmp;
diff --git a/drivers/media/common/siano/smsir.c b/drivers/media/common/siano/smsir.c
index e77bb0c95e69..56db0a944421 100644
--- a/drivers/media/common/siano/smsir.c
+++ b/drivers/media/common/siano/smsir.c
@@ -1,28 +1,13 @@
-/****************************************************************
-
- Siano Mobile Silicon, Inc.
- MDTV receiver kernel modules.
- Copyright (C) 2006-2009, Uri Shkolnik
-
- Copyright (c) 2010 - Mauro Carvalho Chehab
- - Ported the driver to use rc-core
- - IR raw event decoding is now done at rc-core
- - Code almost re-written
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- ****************************************************************/
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Siano Mobile Silicon, Inc.
+// MDTV receiver kernel modules.
+// Copyright (C) 2006-2009, Uri Shkolnik
+//
+// Copyright (c) 2010 - Mauro Carvalho Chehab
+// - Ported the driver to use rc-core
+// - IR raw event decoding is now done at rc-core
+// - Code almost re-written
#include "smscoreapi.h"
diff --git a/drivers/media/common/siano/smsir.h b/drivers/media/common/siano/smsir.h
index d9abd96ef48b..b2c54c256e86 100644
--- a/drivers/media/common/siano/smsir.h
+++ b/drivers/media/common/siano/smsir.h
@@ -1,28 +1,15 @@
-/****************************************************************
-
-Siano Mobile Silicon, Inc.
-MDTV receiver kernel modules.
-Copyright (C) 2006-2009, Uri Shkolnik
-
- Copyright (c) 2010 - Mauro Carvalho Chehab
- - Ported the driver to use rc-core
- - IR raw event decoding is now done at rc-core
- - Code almost re-written
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-****************************************************************/
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Siano Mobile Silicon, Inc.
+ * MDTV receiver kernel modules.
+ * Copyright (C) 2006-2009, Uri Shkolnik
+ *
+ * Copyright (c) 2010 - Mauro Carvalho Chehab
+ * - Ported the driver to use rc-core
+ * - IR raw event decoding is now done at rc-core
+ * - Code almost re-written
+ */
#ifndef __SMS_IR_H__
#define __SMS_IR_H__
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c
index 5b5f95c38fe1..43180204fab2 100644
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c
@@ -36,10 +36,10 @@
*/
#include <linux/videodev2.h>
-#include <media/v4l2-tpg-colors.h>
+#include <media/tpg/v4l2-tpg.h>
/* sRGB colors with range [0-255] */
-const struct color tpg_colors[TPG_COLOR_MAX] = {
+const struct tpg_rbg_color8 tpg_colors[TPG_COLOR_MAX] = {
/*
* Colors to test colorspace conversion: converting these colors
* to other colorspaces will never lead to out-of-gamut colors.
@@ -597,7 +597,7 @@ const unsigned short tpg_linear_to_rec709[255 * 16 + 1] = {
};
/* Generated table */
-const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_SMPTE2084 + 1][TPG_COLOR_CSC_BLACK + 1] = {
+const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_SMPTE2084 + 1][TPG_COLOR_CSC_BLACK + 1] = {
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][0] = { 2939, 2939, 2939 },
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][1] = { 2953, 2963, 586 },
[V4L2_COLORSPACE_SMPTE170M][V4L2_XFER_FUNC_709][2] = { 0, 2967, 2937 },
@@ -1392,7 +1392,7 @@ int main(int argc, char **argv)
printf("\n};\n\n");
printf("/* Generated table */\n");
- printf("const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_SMPTE2084 + 1][TPG_COLOR_CSC_BLACK + 1] = {\n");
+ printf("const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1][V4L2_XFER_FUNC_SMPTE2084 + 1][TPG_COLOR_CSC_BLACK + 1] = {\n");
for (c = 0; c <= V4L2_COLORSPACE_DCI_P3; c++) {
for (x = 1; x <= V4L2_XFER_FUNC_SMPTE2084; x++) {
for (i = 0; i <= TPG_COLOR_CSC_BLACK; i++) {
diff --git a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
index f96968c11312..2b3d4ac4dfd4 100644
--- a/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
+++ b/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
@@ -21,7 +21,7 @@
*/
#include <linux/module.h>
-#include <media/v4l2-tpg.h>
+#include <media/tpg/v4l2-tpg.h>
/* Must remain in sync with enum tpg_pattern */
const char * const tpg_pattern_strings[] = {
diff --git a/drivers/media/common/videobuf2/Kconfig b/drivers/media/common/videobuf2/Kconfig
new file mode 100644
index 000000000000..5df05250de94
--- /dev/null
+++ b/drivers/media/common/videobuf2/Kconfig
@@ -0,0 +1,31 @@
+# Used by drivers that need Videobuf2 modules
+config VIDEOBUF2_CORE
+ select DMA_SHARED_BUFFER
+ tristate
+
+config VIDEOBUF2_MEMOPS
+ tristate
+ select FRAME_VECTOR
+
+config VIDEOBUF2_DMA_CONTIG
+ tristate
+ depends on HAS_DMA
+ select VIDEOBUF2_CORE
+ select VIDEOBUF2_MEMOPS
+ select DMA_SHARED_BUFFER
+
+config VIDEOBUF2_VMALLOC
+ tristate
+ select VIDEOBUF2_CORE
+ select VIDEOBUF2_MEMOPS
+ select DMA_SHARED_BUFFER
+
+config VIDEOBUF2_DMA_SG
+ tristate
+ depends on HAS_DMA
+ select VIDEOBUF2_CORE
+ select VIDEOBUF2_MEMOPS
+
+config VIDEOBUF2_DVB
+ tristate
+ select VIDEOBUF2_CORE
diff --git a/drivers/media/common/videobuf2/Makefile b/drivers/media/common/videobuf2/Makefile
new file mode 100644
index 000000000000..19de5ccda20b
--- /dev/null
+++ b/drivers/media/common/videobuf2/Makefile
@@ -0,0 +1,7 @@
+
+obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.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_VIDEOBUF2_DVB) += videobuf2-dvb.o
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c
index 0d9f772d6d03..9a84c7092714 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/common/videobuf2/videobuf2-core.c
@@ -14,6 +14,8 @@
* the Free Software Foundation.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -32,10 +34,10 @@
static int debug;
module_param(debug, int, 0644);
-#define dprintk(level, fmt, arg...) \
- do { \
- if (debug >= level) \
- pr_info("vb2-core: %s: " fmt, __func__, ## arg); \
+#define dprintk(level, fmt, arg...) \
+ do { \
+ if (debug >= level) \
+ pr_info("%s: " fmt, __func__, ## arg); \
} while (0)
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -332,6 +334,10 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory,
struct vb2_buffer *vb;
int ret;
+ /* Ensure that q->num_buffers+num_buffers is below VB2_MAX_FRAME */
+ num_buffers = min_t(unsigned int, num_buffers,
+ VB2_MAX_FRAME - q->num_buffers);
+
for (buffer = 0; buffer < num_buffers; ++buffer) {
/* Allocate videobuf buffer structures */
vb = kzalloc(q->buf_struct_size, GFP_KERNEL);
@@ -460,12 +466,12 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
q->cnt_wait_prepare != q->cnt_wait_finish;
if (unbalanced || debug) {
- pr_info("vb2: counters for queue %p:%s\n", q,
+ pr_info("counters for queue %p:%s\n", q,
unbalanced ? " UNBALANCED!" : "");
- pr_info("vb2: setup: %u start_streaming: %u stop_streaming: %u\n",
+ pr_info(" setup: %u start_streaming: %u stop_streaming: %u\n",
q->cnt_queue_setup, q->cnt_start_streaming,
q->cnt_stop_streaming);
- pr_info("vb2: wait_prepare: %u wait_finish: %u\n",
+ pr_info(" wait_prepare: %u wait_finish: %u\n",
q->cnt_wait_prepare, q->cnt_wait_finish);
}
q->cnt_queue_setup = 0;
@@ -486,23 +492,23 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
vb->cnt_buf_init != vb->cnt_buf_cleanup;
if (unbalanced || debug) {
- pr_info("vb2: counters for queue %p, buffer %d:%s\n",
+ pr_info(" counters for queue %p, buffer %d:%s\n",
q, buffer, unbalanced ? " UNBALANCED!" : "");
- pr_info("vb2: buf_init: %u buf_cleanup: %u buf_prepare: %u buf_finish: %u\n",
+ pr_info(" buf_init: %u buf_cleanup: %u buf_prepare: %u buf_finish: %u\n",
vb->cnt_buf_init, vb->cnt_buf_cleanup,
vb->cnt_buf_prepare, vb->cnt_buf_finish);
- pr_info("vb2: buf_queue: %u buf_done: %u\n",
+ pr_info(" buf_queue: %u buf_done: %u\n",
vb->cnt_buf_queue, vb->cnt_buf_done);
- pr_info("vb2: alloc: %u put: %u prepare: %u finish: %u mmap: %u\n",
+ pr_info(" alloc: %u put: %u prepare: %u finish: %u mmap: %u\n",
vb->cnt_mem_alloc, vb->cnt_mem_put,
vb->cnt_mem_prepare, vb->cnt_mem_finish,
vb->cnt_mem_mmap);
- pr_info("vb2: get_userptr: %u put_userptr: %u\n",
+ pr_info(" get_userptr: %u put_userptr: %u\n",
vb->cnt_mem_get_userptr, vb->cnt_mem_put_userptr);
- pr_info("vb2: attach_dmabuf: %u detach_dmabuf: %u map_dmabuf: %u unmap_dmabuf: %u\n",
+ pr_info(" attach_dmabuf: %u detach_dmabuf: %u map_dmabuf: %u unmap_dmabuf: %u\n",
vb->cnt_mem_attach_dmabuf, vb->cnt_mem_detach_dmabuf,
vb->cnt_mem_map_dmabuf, vb->cnt_mem_unmap_dmabuf);
- pr_info("vb2: get_dmabuf: %u num_users: %u vaddr: %u cookie: %u\n",
+ pr_info(" get_dmabuf: %u num_users: %u vaddr: %u cookie: %u\n",
vb->cnt_mem_get_dmabuf,
vb->cnt_mem_num_users,
vb->cnt_mem_vaddr,
@@ -520,7 +526,7 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
q->num_buffers -= buffers;
if (!q->num_buffers) {
- q->memory = 0;
+ q->memory = VB2_MEMORY_UNKNOWN;
INIT_LIST_HEAD(&q->queued_list);
}
return 0;
@@ -662,7 +668,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
return -EBUSY;
}
- if (*count == 0 || q->num_buffers != 0 || q->memory != memory) {
+ if (*count == 0 || q->num_buffers != 0 ||
+ (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) {
/*
* We already have buffers allocated, so first check if they
* are not in use and can be freed.
@@ -696,8 +703,9 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
/*
* Make sure the requested values and current defaults are sane.
*/
- num_buffers = min_t(unsigned int, *count, VB2_MAX_FRAME);
- num_buffers = max_t(unsigned int, num_buffers, q->min_buffers_needed);
+ WARN_ON(q->min_buffers_needed > VB2_MAX_FRAME);
+ num_buffers = max_t(unsigned int, *count, q->min_buffers_needed);
+ num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME);
memset(q->alloc_devs, 0, sizeof(q->alloc_devs));
q->memory = memory;
@@ -1650,8 +1658,11 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
*/
if (WARN_ON(atomic_read(&q->owned_by_drv_count))) {
for (i = 0; i < q->num_buffers; ++i)
- if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE)
+ if (q->bufs[i]->state == VB2_BUF_STATE_ACTIVE) {
+ pr_warn("driver bug: stop_streaming operation is leaving buf %p in active state\n",
+ q->bufs[i]);
vb2_buffer_done(q->bufs[i], VB2_BUF_STATE_ERROR);
+ }
/* Must be zero now */
WARN_ON(atomic_read(&q->owned_by_drv_count));
}
@@ -1994,6 +2005,8 @@ int vb2_core_queue_init(struct vb2_queue *q)
mutex_init(&q->mmap_lock);
init_waitqueue_head(&q->done_wq);
+ q->memory = VB2_MEMORY_UNKNOWN;
+
if (q->buf_struct_size == 0)
q->buf_struct_size = sizeof(struct vb2_buffer);
@@ -2522,7 +2535,7 @@ static int vb2_thread(void *data)
break;
call_void_qop(q, wait_finish, q);
if (copy_timestamp)
- vb->timestamp = ktime_get_ns();;
+ vb->timestamp = ktime_get_ns();
if (!threadio->stop)
ret = vb2_core_qbuf(q, vb->index, NULL);
call_void_qop(q, wait_prepare, q);
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
index a9806ba6116d..f1178f6f434d 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c
@@ -434,8 +434,10 @@ static void vb2_dc_put_userptr(void *buf_priv)
pages = frame_vector_pages(buf->vec);
/* sgt should exist only if vector contains pages... */
BUG_ON(IS_ERR(pages));
- for (i = 0; i < frame_vector_count(buf->vec); i++)
- set_page_dirty_lock(pages[i]);
+ if (buf->dma_dir == DMA_FROM_DEVICE ||
+ buf->dma_dir == DMA_BIDIRECTIONAL)
+ for (i = 0; i < frame_vector_count(buf->vec); i++)
+ set_page_dirty_lock(pages[i]);
sg_free_table(sgt);
kfree(sgt);
}
diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
index 6808231a6bdc..753ed3138dcc 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-sg.c
+++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c
@@ -292,11 +292,10 @@ static void vb2_dma_sg_put_userptr(void *buf_priv)
if (buf->vaddr)
vm_unmap_ram(buf->vaddr, buf->num_pages);
sg_free_table(buf->dma_sgt);
- while (--i >= 0) {
- if (buf->dma_dir == DMA_FROM_DEVICE ||
- buf->dma_dir == DMA_BIDIRECTIONAL)
+ if (buf->dma_dir == DMA_FROM_DEVICE ||
+ buf->dma_dir == DMA_BIDIRECTIONAL)
+ while (--i >= 0)
set_page_dirty_lock(buf->pages[i]);
- }
vb2_destroy_framevec(buf->vec);
kfree(buf);
}
diff --git a/drivers/media/v4l2-core/videobuf2-dvb.c b/drivers/media/common/videobuf2/videobuf2-dvb.c
index 9f38b4218c0d..9f38b4218c0d 100644
--- a/drivers/media/v4l2-core/videobuf2-dvb.c
+++ b/drivers/media/common/videobuf2/videobuf2-dvb.c
diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/common/videobuf2/videobuf2-memops.c
index 89e51989332b..89e51989332b 100644
--- a/drivers/media/v4l2-core/videobuf2-memops.c
+++ b/drivers/media/common/videobuf2/videobuf2-memops.c
diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c
index a49f7eb98c2e..d9a487aab99c 100644
--- a/drivers/media/v4l2-core/videobuf2-v4l2.c
+++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c
@@ -434,6 +434,8 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb,
} else {
/* Zero any output buffer flags as this is a capture buffer */
vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS;
+ /* Zero last flag, this is a signal from driver to userspace */
+ vbuf->flags &= ~V4L2_BUF_FLAG_LAST;
}
return 0;
diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c
index 3a7c80cd1a17..3a7c80cd1a17 100644
--- a/drivers/media/v4l2-core/videobuf2-vmalloc.c
+++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c
diff --git a/drivers/media/dvb-core/Kconfig b/drivers/media/dvb-core/Kconfig
index eeef94a0c84e..f004aea352e0 100644
--- a/drivers/media/dvb-core/Kconfig
+++ b/drivers/media/dvb-core/Kconfig
@@ -40,3 +40,16 @@ config DVB_DEMUX_SECTION_LOSS_LOG
be very verbose.
If you are unsure about this, say N here.
+
+config DVB_ULE_DEBUG
+ bool "Enable DVB net ULE packet debug messages"
+ depends on DVB_CORE
+ default n
+ help
+ Enable extra log messages meant to detect problems while
+ handling DVB network ULE packet loss inside the Kernel.
+
+ Should not be enabled on normal cases, as logs can
+ be very verbose.
+
+ If you are unsure about this, say N here.
diff --git a/drivers/media/dvb-core/Makefile b/drivers/media/dvb-core/Makefile
index 47e2e391bfb8..3a105d82019a 100644
--- a/drivers/media/dvb-core/Makefile
+++ b/drivers/media/dvb-core/Makefile
@@ -4,9 +4,10 @@
#
dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
+dvb-vb2-$(CONFIG_DVB_MMSP) := dvb_vb2.o
-dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \
- dvb_ca_en50221.o dvb_frontend.o \
- $(dvb-net-y) dvb_ringbuffer.o dvb_math.o
+dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \
+ dvb_ca_en50221.o dvb_frontend.o \
+ $(dvb-net-y) dvb_ringbuffer.o $(dvb-vb2-y) dvb_math.o
obj-$(CONFIG_DVB_CORE) += dvb-core.o
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index 3fe0eb740a6d..bc198f84b9cd 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -27,7 +27,8 @@
#include <linux/ioctl.h>
#include <linux/wait.h>
#include <linux/uaccess.h>
-#include "dmxdev.h"
+#include <media/dmxdev.h>
+#include <media/dvb_vb2.h>
static int debug;
@@ -127,6 +128,11 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct dmxdev *dmxdev = dvbdev->priv;
struct dmx_frontend *front;
+#ifndef DVB_MMAP
+ bool need_ringbuffer = false;
+#else
+ const bool need_ringbuffer = true;
+#endif
dprintk("%s\n", __func__);
@@ -138,14 +144,19 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
return -ENODEV;
}
+#ifndef DVB_MMAP
+ if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+ need_ringbuffer = true;
+#else
if ((file->f_flags & O_ACCMODE) == O_RDWR) {
if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
mutex_unlock(&dmxdev->mutex);
return -EOPNOTSUPP;
}
}
+#endif
- if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+ if (need_ringbuffer) {
void *mem;
if (!dvbdev->readers) {
@@ -158,6 +169,8 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
return -ENOMEM;
}
dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
+ dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",
+ file->f_flags & O_NONBLOCK);
dvbdev->readers--;
}
@@ -187,6 +200,11 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev = file->private_data;
struct dmxdev *dmxdev = dvbdev->priv;
+#ifndef DVB_MMAP
+ bool need_ringbuffer = false;
+#else
+ const bool need_ringbuffer = true;
+#endif
mutex_lock(&dmxdev->mutex);
@@ -195,7 +213,15 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
dmxdev->demux->connect_frontend(dmxdev->demux,
dmxdev->dvr_orig_fe);
}
- if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+#ifndef DVB_MMAP
+ if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+ need_ringbuffer = true;
+#endif
+
+ if (need_ringbuffer) {
+ if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
+ dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx);
+ dvb_vb2_release(&dmxdev->dvr_vb2_ctx);
dvbdev->readers++;
if (dmxdev->dvr_buffer.data) {
void *mem = dmxdev->dvr_buffer.data;
@@ -359,7 +385,8 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
struct dmxdev_filter *dmxdevfilter = filter->priv;
int ret;
- if (dmxdevfilter->buffer.error) {
+ if (!dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx) &&
+ dmxdevfilter->buffer.error) {
wake_up(&dmxdevfilter->buffer.queue);
return 0;
}
@@ -370,11 +397,19 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
}
del_timer(&dmxdevfilter->timer);
dprintk("section callback %*ph\n", 6, buffer1);
- ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1,
- buffer1_len);
- if (ret == buffer1_len) {
- ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2,
- buffer2_len);
+ if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {
+ ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
+ buffer1, buffer1_len);
+ if (ret == buffer1_len)
+ ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
+ buffer2, buffer2_len);
+ } else {
+ ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
+ buffer1, buffer1_len);
+ if (ret == buffer1_len) {
+ ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
+ buffer2, buffer2_len);
+ }
}
if (ret < 0)
dmxdevfilter->buffer.error = ret;
@@ -391,6 +426,9 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
{
struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer;
+#ifdef DVB_MMAP
+ struct dvb_vb2_ctx *ctx;
+#endif
int ret;
spin_lock(&dmxdevfilter->dev->lock);
@@ -399,19 +437,34 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
return 0;
}
- if (dmxdevfilter->params.pes.output == DMX_OUT_TAP
- || dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP)
+ if (dmxdevfilter->params.pes.output == DMX_OUT_TAP ||
+ dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) {
buffer = &dmxdevfilter->buffer;
- else
+#ifdef DVB_MMAP
+ ctx = &dmxdevfilter->vb2_ctx;
+#endif
+ } else {
buffer = &dmxdevfilter->dev->dvr_buffer;
- if (buffer->error) {
- spin_unlock(&dmxdevfilter->dev->lock);
- wake_up(&buffer->queue);
- return 0;
+#ifdef DVB_MMAP
+ ctx = &dmxdevfilter->dev->dvr_vb2_ctx;
+#endif
+ }
+
+ if (dvb_vb2_is_streaming(ctx)) {
+ ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len);
+ if (ret == buffer1_len)
+ ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len);
+ } else {
+ if (buffer->error) {
+ spin_unlock(&dmxdevfilter->dev->lock);
+ wake_up(&buffer->queue);
+ return 0;
+ }
+ ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
+ if (ret == buffer1_len)
+ ret = dvb_dmxdev_buffer_write(buffer,
+ buffer2, buffer2_len);
}
- ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len);
- if (ret == buffer1_len)
- ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len);
if (ret < 0)
buffer->error = ret;
spin_unlock(&dmxdevfilter->dev->lock);
@@ -750,6 +803,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
file->private_data = dmxdevfilter;
dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
+ dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter",
+ file->f_flags & O_NONBLOCK);
dmxdevfilter->type = DMXDEV_TYPE_NONE;
dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
timer_setup(&dmxdevfilter->timer, dvb_dmxdev_filter_timeout, 0);
@@ -765,6 +820,10 @@ static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev,
{
mutex_lock(&dmxdev->mutex);
mutex_lock(&dmxdevfilter->mutex);
+ if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx))
+ dvb_vb2_stream_off(&dmxdevfilter->vb2_ctx);
+ dvb_vb2_release(&dmxdevfilter->vb2_ctx);
+
dvb_dmxdev_filter_stop(dmxdevfilter);
dvb_dmxdev_filter_reset(dmxdevfilter);
@@ -1052,6 +1111,54 @@ static int dvb_demux_do_ioctl(struct file *file,
mutex_unlock(&dmxdevfilter->mutex);
break;
+#ifdef DVB_MMAP
+ case DMX_REQBUFS:
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ERESTARTSYS;
+ }
+ ret = dvb_vb2_reqbufs(&dmxdevfilter->vb2_ctx, parg);
+ mutex_unlock(&dmxdevfilter->mutex);
+ break;
+
+ case DMX_QUERYBUF:
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ERESTARTSYS;
+ }
+ ret = dvb_vb2_querybuf(&dmxdevfilter->vb2_ctx, parg);
+ mutex_unlock(&dmxdevfilter->mutex);
+ break;
+
+ case DMX_EXPBUF:
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ERESTARTSYS;
+ }
+ ret = dvb_vb2_expbuf(&dmxdevfilter->vb2_ctx, parg);
+ mutex_unlock(&dmxdevfilter->mutex);
+ break;
+
+ case DMX_QBUF:
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ERESTARTSYS;
+ }
+ ret = dvb_vb2_qbuf(&dmxdevfilter->vb2_ctx, parg);
+ if (ret == 0 && !dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx))
+ ret = dvb_vb2_stream_on(&dmxdevfilter->vb2_ctx);
+ mutex_unlock(&dmxdevfilter->mutex);
+ break;
+
+ case DMX_DQBUF:
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ERESTARTSYS;
+ }
+ ret = dvb_vb2_dqbuf(&dmxdevfilter->vb2_ctx, parg);
+ mutex_unlock(&dmxdevfilter->mutex);
+ break;
+#endif
default:
ret = -EINVAL;
break;
@@ -1073,6 +1180,8 @@ static __poll_t dvb_demux_poll(struct file *file, poll_table *wait)
if ((!dmxdevfilter) || dmxdevfilter->dev->exit)
return POLLERR;
+ if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx))
+ return dvb_vb2_poll(&dmxdevfilter->vb2_ctx, file, wait);
poll_wait(file, &dmxdevfilter->buffer.queue, wait);
@@ -1090,11 +1199,33 @@ static __poll_t dvb_demux_poll(struct file *file, poll_table *wait)
return mask;
}
-static int dvb_demux_release(struct inode *inode, struct file *file)
+#ifdef DVB_MMAP
+static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)
{
struct dmxdev_filter *dmxdevfilter = file->private_data;
struct dmxdev *dmxdev = dmxdevfilter->dev;
+ int ret;
+
+ if (mutex_lock_interruptible(&dmxdev->mutex))
+ return -ERESTARTSYS;
+
+ if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ERESTARTSYS;
+ }
+ ret = dvb_vb2_mmap(&dmxdevfilter->vb2_ctx, vma);
+
+ mutex_unlock(&dmxdevfilter->mutex);
+ mutex_unlock(&dmxdev->mutex);
+ return ret;
+}
+#endif
+
+static int dvb_demux_release(struct inode *inode, struct file *file)
+{
+ struct dmxdev_filter *dmxdevfilter = file->private_data;
+ struct dmxdev *dmxdev = dmxdevfilter->dev;
int ret;
ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
@@ -1118,6 +1249,9 @@ static const struct file_operations dvb_demux_fops = {
.release = dvb_demux_release,
.poll = dvb_demux_poll,
.llseek = default_llseek,
+#ifdef DVB_MMAP
+ .mmap = dvb_demux_mmap,
+#endif
};
static const struct dvb_device dvbdev_demux = {
@@ -1146,6 +1280,29 @@ static int dvb_dvr_do_ioctl(struct file *file,
ret = dvb_dvr_set_buffer_size(dmxdev, arg);
break;
+#ifdef DVB_MMAP
+ case DMX_REQBUFS:
+ ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg);
+ break;
+
+ case DMX_QUERYBUF:
+ ret = dvb_vb2_querybuf(&dmxdev->dvr_vb2_ctx, parg);
+ break;
+
+ case DMX_EXPBUF:
+ ret = dvb_vb2_expbuf(&dmxdev->dvr_vb2_ctx, parg);
+ break;
+
+ case DMX_QBUF:
+ ret = dvb_vb2_qbuf(&dmxdev->dvr_vb2_ctx, parg);
+ if (ret == 0 && !dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
+ ret = dvb_vb2_stream_on(&dmxdev->dvr_vb2_ctx);
+ break;
+
+ case DMX_DQBUF:
+ ret = dvb_vb2_dqbuf(&dmxdev->dvr_vb2_ctx, parg);
+ break;
+#endif
default:
ret = -EINVAL;
break;
@@ -1165,15 +1322,26 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
struct dvb_device *dvbdev = file->private_data;
struct dmxdev *dmxdev = dvbdev->priv;
__poll_t mask = 0;
+#ifndef DVB_MMAP
+ bool need_ringbuffer = false;
+#else
+ const bool need_ringbuffer = true;
+#endif
dprintk("%s\n", __func__);
if (dmxdev->exit)
return POLLERR;
+ if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
+ return dvb_vb2_poll(&dmxdev->dvr_vb2_ctx, file, wait);
poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
- if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+#ifndef DVB_MMAP
+ if ((file->f_flags & O_ACCMODE) == O_RDONLY)
+ need_ringbuffer = true;
+#endif
+ if (need_ringbuffer) {
if (dmxdev->dvr_buffer.error)
mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR);
@@ -1185,6 +1353,25 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
return mask;
}
+#ifdef DVB_MMAP
+static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ struct dmxdev *dmxdev = dvbdev->priv;
+ int ret;
+
+ if (dmxdev->exit)
+ return -ENODEV;
+
+ if (mutex_lock_interruptible(&dmxdev->mutex))
+ return -ERESTARTSYS;
+
+ ret = dvb_vb2_mmap(&dmxdev->dvr_vb2_ctx, vma);
+ mutex_unlock(&dmxdev->mutex);
+ return ret;
+}
+#endif
+
static const struct file_operations dvb_dvr_fops = {
.owner = THIS_MODULE,
.read = dvb_dvr_read,
@@ -1194,6 +1381,9 @@ static const struct file_operations dvb_dvr_fops = {
.release = dvb_dvr_release,
.poll = dvb_dvr_poll,
.llseek = default_llseek,
+#ifdef DVB_MMAP
+ .mmap = dvb_dvr_mmap,
+#endif
};
static const struct dvb_device dvbdev_dvr = {
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c
index 3f6c8bd8f869..b462ebc0c544 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb-core/dvb_ca_en50221.c
@@ -37,8 +37,8 @@
#include <linux/sched/signal.h>
#include <linux/kthread.h>
-#include "dvb_ca_en50221.h"
-#include "dvb_ringbuffer.h"
+#include <media/dvb_ca_en50221.h>
+#include <media/dvb_ringbuffer.h>
static int dvb_ca_en50221_debug;
@@ -786,7 +786,7 @@ exit:
* @ca: CA instance.
* @slot: Slot to write to.
* @buf: The data in this buffer is treated as a complete link-level packet to
- * be written.
+ * be written.
* @bytes_write: Size of ebuf.
*
* return: Number of bytes written, or < 0 on error.
@@ -1473,6 +1473,9 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
return -EFAULT;
buf += 2;
count -= 2;
+
+ if (slot >= ca->slot_count)
+ return -EINVAL;
sl = &ca->slot_info[slot];
/* check if the slot is actually running */
diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c
index acade7543b82..210eed0269b0 100644
--- a/drivers/media/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb-core/dvb_demux.c
@@ -30,7 +30,7 @@
#include <linux/uaccess.h>
#include <asm/div64.h>
-#include "dvb_demux.h"
+#include <media/dvb_demux.h>
static int dvb_demux_tscheck;
module_param(dvb_demux_tscheck, int, 0644);
@@ -119,7 +119,8 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
ccok = ((feed->cc + 1) & 0x0f) == cc;
feed->cc = cc;
if (!ccok)
- dprintk("missed packet!\n");
+ dprintk("missed packet: %d instead of %d!\n",
+ cc, (feed->cc + 1) & 0x0f);
#endif
if (buf[1] & 0x40) // PUSI ?
@@ -188,7 +189,7 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
if (sec->secbufp < sec->tsfeedp) {
- int i, n = sec->tsfeedp - sec->secbufp;
+ int n = sec->tsfeedp - sec->secbufp;
/*
* Section padding is done with 0xff bytes entirely.
@@ -196,12 +197,9 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed)
* but just first and last.
*/
if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) {
- dprintk("dvb_demux.c section ts padding loss: %d/%d\n",
+ dprintk("section ts padding loss: %d/%d\n",
n, sec->tsfeedp);
- dprintk("dvb_demux.c pad data:");
- for (i = 0; i < n; i++)
- pr_cont(" %02x", sec->secbuf[i]);
- pr_cont("\n");
+ dprintk("pad data: %*ph\n", n, sec->secbuf);
}
}
#endif
@@ -240,9 +238,9 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) {
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
- dprintk("dvb_demux.c section buffer full loss: %d/%d\n",
- sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
- DMX_MAX_SECFEED_SIZE);
+ dprintk("section buffer full loss: %d/%d\n",
+ sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE,
+ DMX_MAX_SECFEED_SIZE);
#endif
len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp;
}
@@ -275,7 +273,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
dvb_dmx_swfilter_section_feed(feed);
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
else
- dprintk("dvb_demux.c pusi not seen, discarding section data\n");
+ dprintk("pusi not seen, discarding section data\n");
#endif
sec->secbufp += seclen; /* secbufp and secbuf moving together is */
sec->secbuf += seclen; /* redundant but saves pointer arithmetic */
@@ -310,8 +308,12 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
if (!ccok || dc_i) {
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
- dprintk("dvb_demux.c discontinuity detected %d bytes lost\n",
- count);
+ if (dc_i)
+ dprintk("%d frame with disconnect indicator\n",
+ cc);
+ else
+ dprintk("discontinuity: %d instead of %d. %d bytes lost\n",
+ cc, (feed->cc + 1) & 0x0f, count + 4);
/*
* those bytes under sume circumstances will again be reported
* in the following dvb_dmx_swfilter_section_new
@@ -320,6 +322,9 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
/*
* Discontinuity detected. Reset pusi_seen to
* stop feeding of suspicious data until next PUSI=1 arrives
+ *
+ * FIXME: does it make sense if the MPEG-TS is the one
+ * reporting discontinuity?
*/
feed->pusi_seen = false;
dvb_dmx_swfilter_section_new(feed);
@@ -343,8 +348,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
}
#ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG
else if (count > 0)
- dprintk("dvb_demux.c PUSI=1 but %d bytes lost\n",
- count);
+ dprintk("PUSI=1 but %d bytes lost\n", count);
#endif
} else {
/* PUSI=0 (is not set), no section boundary */
@@ -414,9 +418,10 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
1024);
speed_timedelta = ktime_ms_delta(cur_time,
demux->speed_last_time);
- dprintk("TS speed %llu Kbits/sec \n",
- div64_u64(speed_bytes,
- speed_timedelta));
+ if (speed_timedelta)
+ dprintk("TS speed %llu Kbits/sec \n",
+ div64_u64(speed_bytes,
+ speed_timedelta));
}
demux->speed_last_time = cur_time;
@@ -441,8 +446,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
if ((buf[3] & 0xf) != demux->cnt_storage[pid]) {
dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
- pid, demux->cnt_storage[pid],
- buf[3] & 0xf);
+ pid, demux->cnt_storage[pid],
+ buf[3] & 0xf);
demux->cnt_storage[pid] = buf[3] & 0xf;
}
}
diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c
index 48e16fd003a7..87fc1bcae5ae 100644
--- a/drivers/media/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb-core/dvb_frontend.c
@@ -40,10 +40,11 @@
#include <linux/jiffies.h>
#include <linux/kthread.h>
#include <linux/ktime.h>
+#include <linux/compat.h>
#include <asm/processor.h>
-#include "dvb_frontend.h"
-#include "dvbdev.h"
+#include <media/dvb_frontend.h>
+#include <media/dvbdev.h>
#include <linux/dvb/version.h>
static int dvb_frontend_debug;
@@ -150,8 +151,7 @@ static void __dvb_frontend_free(struct dvb_frontend *fe)
dvb_frontend_invoke_release(fe, fe->ops.release);
- if (fepriv)
- kfree(fepriv);
+ kfree(fepriv);
}
static void dvb_frontend_free(struct kref *ref)
@@ -982,6 +982,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
}
c->stream_id = NO_STREAM_ID_FILTER;
+ c->scrambling_sequence_index = 0;/* default sequence */
switch (c->delivery_system) {
case SYS_DVBS:
@@ -1072,6 +1073,7 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
_DTV_CMD(DTV_STREAM_ID, 1, 0),
_DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0),
+ _DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, 1, 0),
_DTV_CMD(DTV_LNA, 1, 0),
/* Get */
@@ -1417,6 +1419,11 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
tvp->u.data = c->stream_id;
break;
+ /* Physical layer scrambling support */
+ case DTV_SCRAMBLING_SEQUENCE_INDEX:
+ tvp->u.data = c->scrambling_sequence_index;
+ break;
+
/* ATSC-MH */
case DTV_ATSCMH_FIC_VER:
tvp->u.data = fe->dtv_property_cache.atscmh_fic_ver;
@@ -1900,6 +1907,11 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
c->stream_id = data;
break;
+ /* Physical layer scrambling support */
+ case DTV_SCRAMBLING_SEQUENCE_INDEX:
+ c->scrambling_sequence_index = data;
+ break;
+
/* ATSC-MH */
case DTV_ATSCMH_PARADE_ID:
fe->dtv_property_cache.atscmh_parade_id = data;
@@ -1923,7 +1935,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
return r;
}
-static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg)
+static int dvb_frontend_do_ioctl(struct file *file, unsigned int cmd,
+ void *parg)
{
struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv;
@@ -1966,6 +1979,156 @@ static int dvb_frontend_ioctl(struct file *file, unsigned int cmd, void *parg)
return err;
}
+static long dvb_frontend_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct dvb_device *dvbdev = file->private_data;
+
+ if (!dvbdev)
+ return -ENODEV;
+
+ return dvb_usercopy(file, cmd, arg, dvb_frontend_do_ioctl);
+}
+
+#ifdef CONFIG_COMPAT
+struct compat_dtv_property {
+ __u32 cmd;
+ __u32 reserved[3];
+ union {
+ __u32 data;
+ struct dtv_fe_stats st;
+ struct {
+ __u8 data[32];
+ __u32 len;
+ __u32 reserved1[3];
+ compat_uptr_t reserved2;
+ } buffer;
+ } u;
+ int result;
+} __attribute__ ((packed));
+
+struct compat_dtv_properties {
+ __u32 num;
+ compat_uptr_t props;
+};
+
+#define COMPAT_FE_SET_PROPERTY _IOW('o', 82, struct compat_dtv_properties)
+#define COMPAT_FE_GET_PROPERTY _IOR('o', 83, struct compat_dtv_properties)
+
+static int dvb_frontend_handle_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ struct dvb_frontend *fe = dvbdev->priv;
+ struct dvb_frontend_private *fepriv = fe->frontend_priv;
+ int i, err = 0;
+
+ if (cmd == COMPAT_FE_SET_PROPERTY) {
+ struct compat_dtv_properties prop, *tvps = NULL;
+ struct compat_dtv_property *tvp = NULL;
+
+ if (copy_from_user(&prop, compat_ptr(arg), sizeof(prop)))
+ return -EFAULT;
+
+ tvps = &prop;
+
+ /*
+ * Put an arbitrary limit on the number of messages that can
+ * be sent at once
+ */
+ if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
+ return -EINVAL;
+
+ tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp));
+ if (IS_ERR(tvp))
+ return PTR_ERR(tvp);
+
+ for (i = 0; i < tvps->num; i++) {
+ err = dtv_property_process_set(fe, file,
+ (tvp + i)->cmd,
+ (tvp + i)->u.data);
+ if (err < 0) {
+ kfree(tvp);
+ return err;
+ }
+ }
+ kfree(tvp);
+ } else if (cmd == COMPAT_FE_GET_PROPERTY) {
+ struct compat_dtv_properties prop, *tvps = NULL;
+ struct compat_dtv_property *tvp = NULL;
+ struct dtv_frontend_properties getp = fe->dtv_property_cache;
+
+ if (copy_from_user(&prop, compat_ptr(arg), sizeof(prop)))
+ return -EFAULT;
+
+ tvps = &prop;
+
+ /*
+ * Put an arbitrary limit on the number of messages that can
+ * be sent at once
+ */
+ if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
+ return -EINVAL;
+
+ tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp));
+ if (IS_ERR(tvp))
+ return PTR_ERR(tvp);
+
+ /*
+ * Let's use our own copy of property cache, in order to
+ * avoid mangling with DTV zigzag logic, as drivers might
+ * return crap, if they don't check if the data is available
+ * before updating the properties cache.
+ */
+ if (fepriv->state != FESTATE_IDLE) {
+ err = dtv_get_frontend(fe, &getp, NULL);
+ if (err < 0) {
+ kfree(tvp);
+ return err;
+ }
+ }
+ for (i = 0; i < tvps->num; i++) {
+ err = dtv_property_process_get(
+ fe, &getp, (struct dtv_property *)tvp + i, file);
+ if (err < 0) {
+ kfree(tvp);
+ return err;
+ }
+ }
+
+ if (copy_to_user((void __user *)compat_ptr(tvps->props), tvp,
+ tvps->num * sizeof(struct compat_dtv_property))) {
+ kfree(tvp);
+ return -EFAULT;
+ }
+ kfree(tvp);
+ }
+
+ return err;
+}
+
+static long dvb_frontend_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct dvb_device *dvbdev = file->private_data;
+ struct dvb_frontend *fe = dvbdev->priv;
+ struct dvb_frontend_private *fepriv = fe->frontend_priv;
+ int err;
+
+ if (cmd == COMPAT_FE_SET_PROPERTY || cmd == COMPAT_FE_GET_PROPERTY) {
+ if (down_interruptible(&fepriv->sem))
+ return -ERESTARTSYS;
+
+ err = dvb_frontend_handle_compat_ioctl(file, cmd, arg);
+
+ up(&fepriv->sem);
+ return err;
+ }
+
+ return dvb_frontend_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+}
+#endif
+
static int dtv_set_frontend(struct dvb_frontend *fe)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
@@ -2110,7 +2273,7 @@ static int dvb_frontend_handle_ioctl(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 i, err;
+ int i, err = -ENOTSUPP;
dev_dbg(fe->dvb->device, "%s:\n", __func__);
@@ -2145,6 +2308,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
}
}
kfree(tvp);
+ err = 0;
break;
}
case FE_GET_PROPERTY: {
@@ -2196,6 +2360,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
return -EFAULT;
}
kfree(tvp);
+ err = 0;
break;
}
@@ -2647,7 +2812,10 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
static const struct file_operations dvb_frontend_fops = {
.owner = THIS_MODULE,
- .unlocked_ioctl = dvb_generic_ioctl,
+ .unlocked_ioctl = dvb_frontend_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = dvb_frontend_compat_ioctl,
+#endif
.poll = dvb_frontend_poll,
.open = dvb_frontend_open,
.release = dvb_frontend_release,
@@ -2715,7 +2883,6 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
.name = fe->ops.info.name,
#endif
- .kernel_ioctl = dvb_frontend_ioctl
};
dev_dbg(dvb->device, "%s:\n", __func__);
diff --git a/drivers/media/dvb-core/dvb_math.c b/drivers/media/dvb-core/dvb_math.c
index a2e1810dd83a..dc90564d7f34 100644
--- a/drivers/media/dvb-core/dvb_math.c
+++ b/drivers/media/dvb-core/dvb_math.c
@@ -19,7 +19,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/bug.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
static const unsigned short logtable[256] = {
0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7,
diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c
index c018e3c06d5d..b6c7eec863b9 100644
--- a/drivers/media/dvb-core/dvb_net.c
+++ b/drivers/media/dvb-core/dvb_net.c
@@ -38,7 +38,7 @@
* Competence Center for Advanced Satellite Communications.
* Bugfixes and robustness improvements.
* Filtering on dest MAC addresses, if present (D-Bit = 0)
- * ULE_DEBUG compile-time option.
+ * DVB_ULE_DEBUG compile-time option.
* Apr 2006: cp v3: Bugfixes and compliency with RFC 4326 (ULE) by
* Christian Praehauser <cpraehaus@cosy.sbg.ac.at>,
* Paris Lodron University of Salzburg.
@@ -64,8 +64,8 @@
#include <linux/mutex.h>
#include <linux/sched.h>
-#include "dvb_demux.h"
-#include "dvb_net.h"
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
{
@@ -78,15 +78,18 @@ static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
#define DVB_NET_MULTICAST_MAX 10
-#undef ULE_DEBUG
-
-#ifdef ULE_DEBUG
+#ifdef DVB_ULE_DEBUG
+/*
+ * The code inside DVB_ULE_DEBUG keeps a history of the
+ * last 100 TS cells processed.
+ */
+static unsigned char ule_hist[100*TS_SZ] = { 0 };
+static unsigned char *ule_where = ule_hist, ule_dump;
static void hexdump(const unsigned char *buf, unsigned short len)
{
print_hex_dump_debug("", DUMP_PREFIX_OFFSET, 16, 1, buf, len, true);
}
-
#endif
struct dvb_net_priv {
@@ -280,11 +283,9 @@ static int handle_ule_extensions( struct dvb_net_priv *p )
if (l < 0)
return l; /* Stop extension header processing and discard SNDU. */
total_ext_len += l;
-#ifdef ULE_DEBUG
pr_debug("ule_next_hdr=%p, ule_sndu_type=%i, l=%i, total_ext_len=%i\n",
p->ule_next_hdr, (int)p->ule_sndu_type,
l, total_ext_len);
-#endif
} while (p->ule_sndu_type < ETH_P_802_3_MIN);
@@ -320,29 +321,21 @@ struct dvb_net_ule_handle {
const u8 *ts, *ts_end, *from_where;
u8 ts_remain, how_much, new_ts;
bool error;
-#ifdef ULE_DEBUG
- /*
- * The code inside ULE_DEBUG keeps a history of the
- * last 100 TS cells processed.
- */
- static unsigned char ule_hist[100*TS_SZ];
- static unsigned char *ule_where = ule_hist, ule_dump;
-#endif
};
static int dvb_net_ule_new_ts_cell(struct dvb_net_ule_handle *h)
{
/* We are about to process a new TS cell. */
-#ifdef ULE_DEBUG
- if (h->ule_where >= &h->ule_hist[100*TS_SZ])
- h->ule_where = h->ule_hist;
- memcpy(h->ule_where, h->ts, TS_SZ);
- if (h->ule_dump) {
- hexdump(h->ule_where, TS_SZ);
- h->ule_dump = 0;
+#ifdef DVB_ULE_DEBUG
+ if (ule_where >= &ule_hist[100*TS_SZ])
+ ule_where = ule_hist;
+ memcpy(ule_where, h->ts, TS_SZ);
+ if (ule_dump) {
+ hexdump(ule_where, TS_SZ);
+ ule_dump = 0;
}
- h->ule_where += TS_SZ;
+ ule_where += TS_SZ;
#endif
/*
@@ -660,6 +653,7 @@ static int dvb_net_ule_should_drop(struct dvb_net_ule_handle *h)
static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
+ struct kvec iov[3],
u32 ule_crc, u32 expected_crc)
{
u8 dest_addr[ETH_ALEN];
@@ -672,22 +666,22 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
h->ts_remain > 2 ?
*(unsigned short *)h->from_where : 0);
- #ifdef ULE_DEBUG
+ #ifdef DVB_ULE_DEBUG
hexdump(iov[0].iov_base, iov[0].iov_len);
hexdump(iov[1].iov_base, iov[1].iov_len);
hexdump(iov[2].iov_base, iov[2].iov_len);
- if (h->ule_where == h->ule_hist) {
- hexdump(&h->ule_hist[98*TS_SZ], TS_SZ);
- hexdump(&h->ule_hist[99*TS_SZ], TS_SZ);
- } else if (h->ule_where == &h->ule_hist[TS_SZ]) {
- hexdump(&h->ule_hist[99*TS_SZ], TS_SZ);
- hexdump(h->ule_hist, TS_SZ);
+ if (ule_where == ule_hist) {
+ hexdump(&ule_hist[98*TS_SZ], TS_SZ);
+ hexdump(&ule_hist[99*TS_SZ], TS_SZ);
+ } else if (ule_where == &ule_hist[TS_SZ]) {
+ hexdump(&ule_hist[99*TS_SZ], TS_SZ);
+ hexdump(ule_hist, TS_SZ);
} else {
- hexdump(h->ule_where - TS_SZ - TS_SZ, TS_SZ);
- hexdump(h->ule_where - TS_SZ, TS_SZ);
+ hexdump(ule_where - TS_SZ - TS_SZ, TS_SZ);
+ hexdump(ule_where - TS_SZ, TS_SZ);
}
- h->ule_dump = 1;
+ ule_dump = 1;
#endif
h->dev->stats.rx_errors++;
@@ -705,11 +699,9 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
if (!h->priv->ule_dbit) {
if (dvb_net_ule_should_drop(h)) {
-#ifdef ULE_DEBUG
netdev_dbg(h->dev,
"Dropping SNDU: MAC destination address does not match: dest addr: %pM, h->dev addr: %pM\n",
h->priv->ule_skb->data, h->dev->dev_addr);
-#endif
dev_kfree_skb(h->priv->ule_skb);
return;
}
@@ -779,6 +771,8 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
int ret;
struct dvb_net_ule_handle h = {
.dev = dev,
+ .priv = netdev_priv(dev),
+ .ethh = NULL,
.buf = buf,
.buf_len = buf_len,
.skipped = 0L,
@@ -788,11 +782,7 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
.ts_remain = 0,
.how_much = 0,
.new_ts = 1,
- .ethh = NULL,
.error = false,
-#ifdef ULE_DEBUG
- .ule_where = ule_hist,
-#endif
};
/*
@@ -860,7 +850,7 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len)
*(tail - 2) << 8 |
*(tail - 1);
- dvb_net_ule_check_crc(&h, ule_crc, expected_crc);
+ dvb_net_ule_check_crc(&h, iov, ule_crc, expected_crc);
/* Prepare for next SNDU. */
reset_ule(h.priv);
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb-core/dvb_ringbuffer.c
index 53011629c9ad..4330b6fa4af2 100644
--- a/drivers/media/dvb-core/dvb_ringbuffer.c
+++ b/drivers/media/dvb-core/dvb_ringbuffer.c
@@ -29,7 +29,7 @@
#include <linux/string.h>
#include <linux/uaccess.h>
-#include "dvb_ringbuffer.h"
+#include <media/dvb_ringbuffer.h>
#define PKT_READY 0
#define PKT_DISPOSED 1
diff --git a/drivers/media/dvb-core/dvb_vb2.c b/drivers/media/dvb-core/dvb_vb2.c
new file mode 100644
index 000000000000..763145d74e83
--- /dev/null
+++ b/drivers/media/dvb-core/dvb_vb2.c
@@ -0,0 +1,430 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dvb-vb2.c - dvb-vb2
+ *
+ * Copyright (C) 2015 Samsung Electronics
+ *
+ * Author: jh1009.sung@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.
+ */
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+
+#include <media/dvbdev.h>
+#include <media/dvb_vb2.h>
+
+#define DVB_V2_MAX_SIZE (4096 * 188)
+
+static int vb2_debug;
+module_param(vb2_debug, int, 0644);
+
+#define dprintk(level, fmt, arg...) \
+ do { \
+ if (vb2_debug >= level) \
+ pr_info("vb2: %s: " fmt, __func__, ## arg); \
+ } while (0)
+
+static int _queue_setup(struct vb2_queue *vq,
+ unsigned int *nbuffers, unsigned int *nplanes,
+ unsigned int sizes[], struct device *alloc_devs[])
+{
+ struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
+
+ ctx->buf_cnt = *nbuffers;
+ *nplanes = 1;
+ sizes[0] = ctx->buf_siz;
+
+ /*
+ * videobuf2-vmalloc allocator is context-less so no need to set
+ * alloc_ctxs array.
+ */
+
+ dprintk(3, "[%s] count=%d, size=%d\n", ctx->name,
+ *nbuffers, sizes[0]);
+
+ return 0;
+}
+
+static int _buffer_prepare(struct vb2_buffer *vb)
+{
+ struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ unsigned long size = ctx->buf_siz;
+
+ if (vb2_plane_size(vb, 0) < size) {
+ dprintk(1, "[%s] data will not fit into plane (%lu < %lu)\n",
+ ctx->name, vb2_plane_size(vb, 0), size);
+ return -EINVAL;
+ }
+
+ vb2_set_plane_payload(vb, 0, size);
+ dprintk(3, "[%s]\n", ctx->name);
+
+ return 0;
+}
+
+static void _buffer_queue(struct vb2_buffer *vb)
+{
+ struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct dvb_buffer *buf = container_of(vb, struct dvb_buffer, vb);
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&ctx->slock, flags);
+ list_add_tail(&buf->list, &ctx->dvb_q);
+ spin_unlock_irqrestore(&ctx->slock, flags);
+
+ dprintk(3, "[%s]\n", ctx->name);
+}
+
+static int _start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+ struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
+
+ dprintk(3, "[%s] count=%d\n", ctx->name, count);
+ return 0;
+}
+
+static void _stop_streaming(struct vb2_queue *vq)
+{
+ struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
+ struct dvb_buffer *buf;
+ unsigned long flags = 0;
+
+ dprintk(3, "[%s]\n", ctx->name);
+
+ spin_lock_irqsave(&ctx->slock, flags);
+ while (!list_empty(&ctx->dvb_q)) {
+ buf = list_entry(ctx->dvb_q.next,
+ struct dvb_buffer, list);
+ vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+ list_del(&buf->list);
+ }
+ spin_unlock_irqrestore(&ctx->slock, flags);
+}
+
+static void _dmxdev_lock(struct vb2_queue *vq)
+{
+ struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
+
+ mutex_lock(&ctx->mutex);
+ dprintk(3, "[%s]\n", ctx->name);
+}
+
+static void _dmxdev_unlock(struct vb2_queue *vq)
+{
+ struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
+
+ if (mutex_is_locked(&ctx->mutex))
+ mutex_unlock(&ctx->mutex);
+ dprintk(3, "[%s]\n", ctx->name);
+}
+
+static const struct vb2_ops dvb_vb2_qops = {
+ .queue_setup = _queue_setup,
+ .buf_prepare = _buffer_prepare,
+ .buf_queue = _buffer_queue,
+ .start_streaming = _start_streaming,
+ .stop_streaming = _stop_streaming,
+ .wait_prepare = _dmxdev_unlock,
+ .wait_finish = _dmxdev_lock,
+};
+
+static void _fill_dmx_buffer(struct vb2_buffer *vb, void *pb)
+{
+ struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct dmx_buffer *b = pb;
+
+ b->index = vb->index;
+ b->length = vb->planes[0].length;
+ b->bytesused = vb->planes[0].bytesused;
+ b->offset = vb->planes[0].m.offset;
+ dprintk(3, "[%s]\n", ctx->name);
+}
+
+static int _fill_vb2_buffer(struct vb2_buffer *vb,
+ const void *pb, struct vb2_plane *planes)
+{
+ struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+
+ planes[0].bytesused = 0;
+ dprintk(3, "[%s]\n", ctx->name);
+
+ return 0;
+}
+
+static const struct vb2_buf_ops dvb_vb2_buf_ops = {
+ .fill_user_buffer = _fill_dmx_buffer,
+ .fill_vb2_buffer = _fill_vb2_buffer,
+};
+
+/*
+ * Videobuf operations
+ */
+int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking)
+{
+ struct vb2_queue *q = &ctx->vb_q;
+ int ret;
+
+ memset(ctx, 0, sizeof(struct dvb_vb2_ctx));
+ q->type = DVB_BUF_TYPE_CAPTURE;
+ /**capture type*/
+ q->is_output = 0;
+ /**only mmap is supported currently*/
+ q->io_modes = VB2_MMAP;
+ q->drv_priv = ctx;
+ q->buf_struct_size = sizeof(struct dvb_buffer);
+ q->min_buffers_needed = 1;
+ q->ops = &dvb_vb2_qops;
+ q->mem_ops = &vb2_vmalloc_memops;
+ q->buf_ops = &dvb_vb2_buf_ops;
+ q->num_buffers = 0;
+ ret = vb2_core_queue_init(q);
+ if (ret) {
+ ctx->state = DVB_VB2_STATE_NONE;
+ dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+ return ret;
+ }
+
+ mutex_init(&ctx->mutex);
+ spin_lock_init(&ctx->slock);
+ INIT_LIST_HEAD(&ctx->dvb_q);
+
+ strlcpy(ctx->name, name, DVB_VB2_NAME_MAX);
+ ctx->nonblocking = nonblocking;
+ ctx->state = DVB_VB2_STATE_INIT;
+
+ dprintk(3, "[%s]\n", ctx->name);
+
+ return 0;
+}
+
+int dvb_vb2_release(struct dvb_vb2_ctx *ctx)
+{
+ struct vb2_queue *q = (struct vb2_queue *)&ctx->vb_q;
+
+ if (ctx->state & DVB_VB2_STATE_INIT)
+ vb2_core_queue_release(q);
+
+ ctx->state = DVB_VB2_STATE_NONE;
+ dprintk(3, "[%s]\n", ctx->name);
+
+ return 0;
+}
+
+int dvb_vb2_stream_on(struct dvb_vb2_ctx *ctx)
+{
+ struct vb2_queue *q = &ctx->vb_q;
+ int ret;
+
+ ret = vb2_core_streamon(q, q->type);
+ if (ret) {
+ ctx->state = DVB_VB2_STATE_NONE;
+ dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+ return ret;
+ }
+ ctx->state |= DVB_VB2_STATE_STREAMON;
+ dprintk(3, "[%s]\n", ctx->name);
+
+ return 0;
+}
+
+int dvb_vb2_stream_off(struct dvb_vb2_ctx *ctx)
+{
+ struct vb2_queue *q = (struct vb2_queue *)&ctx->vb_q;
+ int ret;
+
+ ctx->state &= ~DVB_VB2_STATE_STREAMON;
+ ret = vb2_core_streamoff(q, q->type);
+ if (ret) {
+ ctx->state = DVB_VB2_STATE_NONE;
+ dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+ return ret;
+ }
+ dprintk(3, "[%s]\n", ctx->name);
+
+ return 0;
+}
+
+int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx)
+{
+ return (ctx->state & DVB_VB2_STATE_STREAMON);
+}
+
+int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
+ const unsigned char *src, int len)
+{
+ unsigned long flags = 0;
+ void *vbuf = NULL;
+ int todo = len;
+ unsigned char *psrc = (unsigned char *)src;
+ int ll = 0;
+
+ dprintk(3, "[%s] %d bytes are rcvd\n", ctx->name, len);
+ if (!src) {
+ dprintk(3, "[%s]:NULL pointer src\n", ctx->name);
+ /**normal case: This func is called twice from demux driver
+ * once with valid src pointer, second time with NULL pointer
+ */
+ return 0;
+ }
+ spin_lock_irqsave(&ctx->slock, flags);
+ while (todo) {
+ if (!ctx->buf) {
+ if (list_empty(&ctx->dvb_q)) {
+ dprintk(3, "[%s] Buffer overflow!!!\n",
+ ctx->name);
+ break;
+ }
+
+ ctx->buf = list_entry(ctx->dvb_q.next,
+ struct dvb_buffer, list);
+ ctx->remain = vb2_plane_size(&ctx->buf->vb, 0);
+ ctx->offset = 0;
+ }
+
+ if (!dvb_vb2_is_streaming(ctx)) {
+ vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_ERROR);
+ list_del(&ctx->buf->list);
+ ctx->buf = NULL;
+ break;
+ }
+
+ /* Fill buffer */
+ ll = min(todo, ctx->remain);
+ vbuf = vb2_plane_vaddr(&ctx->buf->vb, 0);
+ memcpy(vbuf + ctx->offset, psrc, ll);
+ todo -= ll;
+ psrc += ll;
+
+ ctx->remain -= ll;
+ ctx->offset += ll;
+
+ if (ctx->remain == 0) {
+ vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_DONE);
+ list_del(&ctx->buf->list);
+ ctx->buf = NULL;
+ }
+ }
+
+ if (ctx->nonblocking && ctx->buf) {
+ vb2_set_plane_payload(&ctx->buf->vb, 0, ll);
+ vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_DONE);
+ list_del(&ctx->buf->list);
+ ctx->buf = NULL;
+ }
+ spin_unlock_irqrestore(&ctx->slock, flags);
+
+ if (todo)
+ dprintk(1, "[%s] %d bytes are dropped.\n", ctx->name, todo);
+ else
+ dprintk(3, "[%s]\n", ctx->name);
+
+ dprintk(3, "[%s] %d bytes are copied\n", ctx->name, len - todo);
+ return (len - todo);
+}
+
+int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req)
+{
+ int ret;
+
+ /* Adjust size to a sane value */
+ if (req->size > DVB_V2_MAX_SIZE)
+ req->size = DVB_V2_MAX_SIZE;
+
+ /* FIXME: round req->size to a 188 or 204 multiple */
+
+ ctx->buf_siz = req->size;
+ ctx->buf_cnt = req->count;
+ ret = vb2_core_reqbufs(&ctx->vb_q, VB2_MEMORY_MMAP, &req->count);
+ if (ret) {
+ ctx->state = DVB_VB2_STATE_NONE;
+ dprintk(1, "[%s] count=%d size=%d errno=%d\n", ctx->name,
+ ctx->buf_cnt, ctx->buf_siz, ret);
+ return ret;
+ }
+ ctx->state |= DVB_VB2_STATE_REQBUFS;
+ dprintk(3, "[%s] count=%d size=%d\n", ctx->name,
+ ctx->buf_cnt, ctx->buf_siz);
+
+ return 0;
+}
+
+int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
+{
+ vb2_core_querybuf(&ctx->vb_q, b->index, b);
+ dprintk(3, "[%s] index=%d\n", ctx->name, b->index);
+ return 0;
+}
+
+int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp)
+{
+ struct vb2_queue *q = &ctx->vb_q;
+ int ret;
+
+ ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, exp->index,
+ 0, exp->flags);
+ if (ret) {
+ dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
+ exp->index, ret);
+ return ret;
+ }
+ dprintk(3, "[%s] index=%d fd=%d\n", ctx->name, exp->index, exp->fd);
+
+ return 0;
+}
+
+int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
+{
+ int ret;
+
+ ret = vb2_core_qbuf(&ctx->vb_q, b->index, b);
+ if (ret) {
+ dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
+ b->index, ret);
+ return ret;
+ }
+ dprintk(5, "[%s] index=%d\n", ctx->name, b->index);
+
+ return 0;
+}
+
+int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
+{
+ int ret;
+
+ ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking);
+ if (ret) {
+ dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+ return ret;
+ }
+ dprintk(5, "[%s] index=%d\n", ctx->name, b->index);
+
+ return 0;
+}
+
+int dvb_vb2_mmap(struct dvb_vb2_ctx *ctx, struct vm_area_struct *vma)
+{
+ int ret;
+
+ ret = vb2_mmap(&ctx->vb_q, vma);
+ if (ret) {
+ dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
+ return ret;
+ }
+ dprintk(3, "[%s] ret=%d\n", ctx->name, ret);
+
+ return 0;
+}
+
+__poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file,
+ poll_table *wait)
+{
+ dprintk(3, "[%s]\n", ctx->name);
+ return vb2_core_poll(&ctx->vb_q, file, wait);
+}
+
diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 060c60ddfcc3..60e9c2ba26be 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -30,7 +30,7 @@
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/mutex.h>
-#include "dvbdev.h"
+#include <media/dvbdev.h>
/* Due to enum tuner_pad_index */
#include <media/tuner.h>
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index d025eb373842..4be59fed4536 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -3,7 +3,6 @@
# Makefile for the kernel DVB frontend device drivers.
#
-ccflags-y += -I$(srctree)/drivers/media/dvb-core/
ccflags-y += -I$(srctree)/drivers/media/tuners/
# FIXME: RTL2832 SDR driver uses power management directly from USB IF driver
diff --git a/drivers/media/dvb-frontends/a8293.h b/drivers/media/dvb-frontends/a8293.h
index 7b90a03fcd0a..bc6f74f10f32 100644
--- a/drivers/media/dvb-frontends/a8293.h
+++ b/drivers/media/dvb-frontends/a8293.h
@@ -17,7 +17,7 @@
#ifndef A8293_H
#define A8293_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/*
* I2C address
diff --git a/drivers/media/dvb-frontends/af9013_priv.h b/drivers/media/dvb-frontends/af9013_priv.h
index 35ca5c9bcacd..688fc3472cf6 100644
--- a/drivers/media/dvb-frontends/af9013_priv.h
+++ b/drivers/media/dvb-frontends/af9013_priv.h
@@ -21,7 +21,7 @@
#ifndef AF9013_PRIV_H
#define AF9013_PRIV_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "af9013.h"
#include <linux/firmware.h>
#include <linux/math64.h>
diff --git a/drivers/media/dvb-frontends/af9033_priv.h b/drivers/media/dvb-frontends/af9033_priv.h
index 8799cda1ae14..f269abf609f0 100644
--- a/drivers/media/dvb-frontends/af9033_priv.h
+++ b/drivers/media/dvb-frontends/af9033_priv.h
@@ -18,12 +18,12 @@
#ifndef AF9033_PRIV_H
#define AF9033_PRIV_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "af9033.h"
#include <linux/math64.h>
#include <linux/regmap.h>
#include <linux/kernel.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
struct reg_val {
u32 reg;
diff --git a/drivers/media/dvb-frontends/as102_fe.c b/drivers/media/dvb-frontends/as102_fe.c
index b1c84ee914f0..9b2f2da1d989 100644
--- a/drivers/media/dvb-frontends/as102_fe.c
+++ b/drivers/media/dvb-frontends/as102_fe.c
@@ -14,7 +14,7 @@
* GNU General Public License for more details.
*/
-#include <dvb_frontend.h>
+#include <media/dvb_frontend.h>
#include "as102_fe.h"
diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c
index 0ee0df53b91b..9746c6dd7fb8 100644
--- a/drivers/media/dvb-frontends/ascot2e.c
+++ b/drivers/media/dvb-frontends/ascot2e.c
@@ -24,7 +24,7 @@
#include <linux/dvb/frontend.h>
#include <linux/types.h>
#include "ascot2e.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#define MAX_WRITE_REGSIZE 10
@@ -155,7 +155,9 @@ static int ascot2e_write_regs(struct ascot2e_priv *priv,
static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val)
{
- return ascot2e_write_regs(priv, reg, &val, 1);
+ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+ return ascot2e_write_regs(priv, reg, &tmp, 1);
}
static int ascot2e_read_regs(struct ascot2e_priv *priv,
diff --git a/drivers/media/dvb-frontends/atbm8830.c b/drivers/media/dvb-frontends/atbm8830.c
index 05850b32d6c6..7b0f3239dbba 100644
--- a/drivers/media/dvb-frontends/atbm8830.c
+++ b/drivers/media/dvb-frontends/atbm8830.c
@@ -16,7 +16,7 @@
*/
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "atbm8830.h"
#include "atbm8830_priv.h"
diff --git a/drivers/media/dvb-frontends/au8522_common.c b/drivers/media/dvb-frontends/au8522_common.c
index 6722838c3707..56605de9923b 100644
--- a/drivers/media/dvb-frontends/au8522_common.c
+++ b/drivers/media/dvb-frontends/au8522_common.c
@@ -23,7 +23,7 @@
*/
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "au8522_priv.h"
static int debug;
diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c
index 3f3635f5a06a..8f659bd1c79e 100644
--- a/drivers/media/dvb-frontends/au8522_dig.c
+++ b/drivers/media/dvb-frontends/au8522_dig.c
@@ -24,7 +24,7 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "au8522.h"
#include "au8522_priv.h"
diff --git a/drivers/media/dvb-frontends/au8522_priv.h b/drivers/media/dvb-frontends/au8522_priv.h
index f5a9438f6ce5..2043c1744753 100644
--- a/drivers/media/dvb-frontends/au8522_priv.h
+++ b/drivers/media/dvb-frontends/au8522_priv.h
@@ -32,7 +32,7 @@
#include <media/v4l2-ctrls.h>
#include <media/v4l2-mc.h>
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "au8522.h"
#include "tuner-i2c.h"
@@ -99,7 +99,7 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H 0x0A5
#define AU8522_AGC_CONTROL_RANGE_REG0A6H 0x0A6
#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H 0x0A7
-#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8
+#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8
#define AU8522_TUNER_AGC_RF_START_REG0A9H 0x0A9
#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH 0x0AA
#define AU8522_TUNER_AGC_IF_STOP_REG0ABH 0x0AB
@@ -110,18 +110,18 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
/* Receiver registers */
#define AU8522_FRMREGTHRD1_REG0B0H 0x0B0
-#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1
-#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2
-#define AU8522_TOREGAGC1_REG0B3H 0x0B3
-#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4
+#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1
+#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2
+#define AU8522_TOREGAGC1_REG0B3H 0x0B3
+#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4
#define AU8522_FRMREGBBH_REG0B5H 0x0B5
-#define AU8522_FRMREGBBM_REG0B6H 0x0B6
-#define AU8522_FRMREGBBL_REG0B7H 0x0B7
+#define AU8522_FRMREGBBM_REG0B6H 0x0B6
+#define AU8522_FRMREGBBL_REG0B7H 0x0B7
/* 0xB8 TO 0xD7 are the filter coefficients */
-#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8
-#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9
-#define AU8522_TOREGAGC2_REG0DAH 0x0DA
-#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB
+#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8
+#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9
+#define AU8522_TOREGAGC2_REG0DAH 0x0DA
+#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB
#define AU8522_FRMREGPILOTH_REG0DCH 0x0DC
#define AU8522_FRMREGPILOTM_REG0DDH 0x0DD
#define AU8522_FRMREGPILOTL_REG0DEH 0x0DE
@@ -134,9 +134,9 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
#define AU8522_CHIP_MODE_REG0FEH 0x0FE
/* I2C bus control registers */
-#define AU8522_I2C_CONTROL_REG0_REG090H 0x090
-#define AU8522_I2C_CONTROL_REG1_REG091H 0x091
-#define AU8522_I2C_STATUS_REG092H 0x092
+#define AU8522_I2C_CONTROL_REG0_REG090H 0x090
+#define AU8522_I2C_CONTROL_REG1_REG091H 0x091
+#define AU8522_I2C_STATUS_REG092H 0x092
#define AU8522_I2C_WR_DATA0_REG093H 0x093
#define AU8522_I2C_WR_DATA1_REG094H 0x094
#define AU8522_I2C_WR_DATA2_REG095H 0x095
@@ -156,48 +156,48 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
#define AU8522_ENA_USB_REG101H 0x101
-#define AU8522_I2S_CTRL_0_REG110H 0x110
-#define AU8522_I2S_CTRL_1_REG111H 0x111
-#define AU8522_I2S_CTRL_2_REG112H 0x112
+#define AU8522_I2S_CTRL_0_REG110H 0x110
+#define AU8522_I2S_CTRL_1_REG111H 0x111
+#define AU8522_I2S_CTRL_2_REG112H 0x112
-#define AU8522_FRMREGFFECONTROL_REG121H 0x121
-#define AU8522_FRMREGDFECONTROL_REG122H 0x122
+#define AU8522_FRMREGFFECONTROL_REG121H 0x121
+#define AU8522_FRMREGDFECONTROL_REG122H 0x122
-#define AU8522_CARRFREQOFFSET0_REG201H 0x201
+#define AU8522_CARRFREQOFFSET0_REG201H 0x201
#define AU8522_CARRFREQOFFSET1_REG202H 0x202
#define AU8522_DECIMATION_GAIN_REG21AH 0x21A
-#define AU8522_FRMREGIFSLP_REG21BH 0x21B
-#define AU8522_FRMREGTHRDL2_REG21CH 0x21C
-#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D
+#define AU8522_FRMREGIFSLP_REG21BH 0x21B
+#define AU8522_FRMREGTHRDL2_REG21CH 0x21C
+#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D
#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH 0x21E
-#define AU8522_FRMREGPLLMODE_REG21FH 0x21F
-#define AU8522_FRMREGCSTHRD_REG220H 0x220
-#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221
-#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222
-#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223
-#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224
-#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225
-#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226
+#define AU8522_FRMREGPLLMODE_REG21FH 0x21F
+#define AU8522_FRMREGCSTHRD_REG220H 0x220
+#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221
+#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222
+#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223
+#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224
+#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225
+#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226
#define AU_FRMREGPLLACQPHASESCL_REG227H 0x227
-#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228
+#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228
/* Analog TV Decoder */
#define AU8522_TVDEC_STATUS_REG000H 0x000
#define AU8522_TVDEC_INT_STATUS_REG001H 0x001
-#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002
+#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002
#define AU8522_TVDEC_SHARPNESSREG009H 0x009
#define AU8522_TVDEC_BRIGHTNESS_REG00AH 0x00A
#define AU8522_TVDEC_CONTRAST_REG00BH 0x00B
#define AU8522_TVDEC_SATURATION_CB_REG00CH 0x00C
#define AU8522_TVDEC_SATURATION_CR_REG00DH 0x00D
#define AU8522_TVDEC_HUE_H_REG00EH 0x00E
-#define AU8522_TVDEC_HUE_L_REG00FH 0x00F
+#define AU8522_TVDEC_HUE_L_REG00FH 0x00F
#define AU8522_TVDEC_INT_MASK_REG010H 0x010
#define AU8522_VIDEO_MODE_REG011H 0x011
#define AU8522_TVDEC_PGA_REG012H 0x012
#define AU8522_TVDEC_COMB_MODE_REG015H 0x015
-#define AU8522_REG016H 0x016
+#define AU8522_REG016H 0x016
#define AU8522_TVDED_DBG_MODE_REG060H 0x060
#define AU8522_TVDEC_FORMAT_CTRL1_REG061H 0x061
#define AU8522_TVDEC_FORMAT_CTRL2_REG062H 0x062
@@ -207,13 +207,13 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H 0x066
#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H 0x067
#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H 0x068
-#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069
#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH 0x06A
-#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B
-#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C
-#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D
-#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E
-#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F
#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H 0x070
#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H 0x073
#define AU8522_TVDEC_DCAGC_CTRL_REG077H 0x077
@@ -229,42 +229,42 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
#define AU8522_TVDEC_CHROMA_AGC_REG401H 0x401
#define AU8522_TVDEC_CHROMA_SFT_REG402H 0x402
-#define AU8522_FILTER_COEF_R410 0x410
-#define AU8522_FILTER_COEF_R411 0x411
-#define AU8522_FILTER_COEF_R412 0x412
-#define AU8522_FILTER_COEF_R413 0x413
-#define AU8522_FILTER_COEF_R414 0x414
-#define AU8522_FILTER_COEF_R415 0x415
-#define AU8522_FILTER_COEF_R416 0x416
-#define AU8522_FILTER_COEF_R417 0x417
-#define AU8522_FILTER_COEF_R418 0x418
-#define AU8522_FILTER_COEF_R419 0x419
-#define AU8522_FILTER_COEF_R41A 0x41A
-#define AU8522_FILTER_COEF_R41B 0x41B
-#define AU8522_FILTER_COEF_R41C 0x41C
-#define AU8522_FILTER_COEF_R41D 0x41D
-#define AU8522_FILTER_COEF_R41E 0x41E
-#define AU8522_FILTER_COEF_R41F 0x41F
-#define AU8522_FILTER_COEF_R420 0x420
-#define AU8522_FILTER_COEF_R421 0x421
-#define AU8522_FILTER_COEF_R422 0x422
-#define AU8522_FILTER_COEF_R423 0x423
-#define AU8522_FILTER_COEF_R424 0x424
-#define AU8522_FILTER_COEF_R425 0x425
-#define AU8522_FILTER_COEF_R426 0x426
-#define AU8522_FILTER_COEF_R427 0x427
-#define AU8522_FILTER_COEF_R428 0x428
-#define AU8522_FILTER_COEF_R429 0x429
-#define AU8522_FILTER_COEF_R42A 0x42A
-#define AU8522_FILTER_COEF_R42B 0x42B
-#define AU8522_FILTER_COEF_R42C 0x42C
-#define AU8522_FILTER_COEF_R42D 0x42D
+#define AU8522_FILTER_COEF_R410 0x410
+#define AU8522_FILTER_COEF_R411 0x411
+#define AU8522_FILTER_COEF_R412 0x412
+#define AU8522_FILTER_COEF_R413 0x413
+#define AU8522_FILTER_COEF_R414 0x414
+#define AU8522_FILTER_COEF_R415 0x415
+#define AU8522_FILTER_COEF_R416 0x416
+#define AU8522_FILTER_COEF_R417 0x417
+#define AU8522_FILTER_COEF_R418 0x418
+#define AU8522_FILTER_COEF_R419 0x419
+#define AU8522_FILTER_COEF_R41A 0x41A
+#define AU8522_FILTER_COEF_R41B 0x41B
+#define AU8522_FILTER_COEF_R41C 0x41C
+#define AU8522_FILTER_COEF_R41D 0x41D
+#define AU8522_FILTER_COEF_R41E 0x41E
+#define AU8522_FILTER_COEF_R41F 0x41F
+#define AU8522_FILTER_COEF_R420 0x420
+#define AU8522_FILTER_COEF_R421 0x421
+#define AU8522_FILTER_COEF_R422 0x422
+#define AU8522_FILTER_COEF_R423 0x423
+#define AU8522_FILTER_COEF_R424 0x424
+#define AU8522_FILTER_COEF_R425 0x425
+#define AU8522_FILTER_COEF_R426 0x426
+#define AU8522_FILTER_COEF_R427 0x427
+#define AU8522_FILTER_COEF_R428 0x428
+#define AU8522_FILTER_COEF_R429 0x429
+#define AU8522_FILTER_COEF_R42A 0x42A
+#define AU8522_FILTER_COEF_R42B 0x42B
+#define AU8522_FILTER_COEF_R42C 0x42C
+#define AU8522_FILTER_COEF_R42D 0x42D
/* VBI Control Registers */
-#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004
-#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005
-#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006
-#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007
+#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004
+#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005
+#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006
+#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007
#define AU8522_TVDEC_VBI_CTRL_H_REG017H 0x017
#define AU8522_TVDEC_VBI_CTRL_L_REG018H 0x018
#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H 0x019
@@ -272,10 +272,10 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH 0x01B
#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH 0x01C
#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH 0x01E
-#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F
-#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020
-#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021
-#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022
#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H 0x023
#define AU8522_REG071H 0x071
@@ -315,17 +315,17 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
#define AU8522_GPIO_DATA_REG0E2H 0x0E2
/* Audio Control Registers */
-#define AU8522_AUDIOAGC_REG0EEH 0x0EE
-#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0
-#define AU8522_AUDIO_MODE_REG0F1H 0x0F1
-#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2
-#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3
-#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4
-#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7
+#define AU8522_AUDIOAGC_REG0EEH 0x0EE
+#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0
+#define AU8522_AUDIO_MODE_REG0F1H 0x0F1
+#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2
+#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3
+#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4
+#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7
#define AU8522_REG0F9H 0x0F9
-#define AU8522_AUDIOAGC2_REG605H 0x605
-#define AU8522_AUDIOFREQ_REG606H 0x606
+#define AU8522_AUDIOAGC2_REG605H 0x605
+#define AU8522_AUDIOFREQ_REG606H 0x606
/**************************************************************/
@@ -356,53 +356,53 @@ int au8522_led_ctrl(struct au8522_state *state, int led);
#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_STD_PAL_M 0x02
-#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4
#define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4
#define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4
-#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4
-#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4
-#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20
+#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20
#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1 0xA2
#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2 0xA0
#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3 0x69
#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4 0x68
-#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28
/* CH1 AS Y,CH3 AS C */
-#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23
/* CH2 AS Y,CH4 AS C */
-#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12
-#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A
#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13 0x1A
#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO 0x02
#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR 0x00
#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO 0x9C
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D
#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC 0xE8
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA
-#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD
#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13 0xDD
#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL 0xDD
#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM 0xDD
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC 0x80
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC 0x40
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256 0x40
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64 0x40
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR 0x00
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF 0x01
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13 0x01
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS 0x01
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03
-#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL 0x01
#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM 0x01
diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c
index ba63ad170d3c..05df133dc5be 100644
--- a/drivers/media/dvb-frontends/bcm3510.c
+++ b/drivers/media/dvb-frontends/bcm3510.c
@@ -40,7 +40,7 @@
#include <linux/slab.h>
#include <linux/mutex.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "bcm3510.h"
#include "bcm3510_priv.h"
diff --git a/drivers/media/dvb-frontends/cx22700.c b/drivers/media/dvb-frontends/cx22700.c
index 2b629e23ceeb..9ffd2c7ac74a 100644
--- a/drivers/media/dvb-frontends/cx22700.c
+++ b/drivers/media/dvb-frontends/cx22700.c
@@ -25,7 +25,7 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "cx22700.h"
diff --git a/drivers/media/dvb-frontends/cx22702.c b/drivers/media/dvb-frontends/cx22702.c
index c0e54c59cccf..e8b1e6b7e7e5 100644
--- a/drivers/media/dvb-frontends/cx22702.c
+++ b/drivers/media/dvb-frontends/cx22702.c
@@ -31,7 +31,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "cx22702.h"
struct cx22702_state {
diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c
index cf1bc99d1f32..2f3a1c237489 100644
--- a/drivers/media/dvb-frontends/cx24110.c
+++ b/drivers/media/dvb-frontends/cx24110.c
@@ -27,7 +27,7 @@
#include <linux/module.h>
#include <linux/init.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "cx24110.h"
diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c
index ee1f704f81f2..037db3e9d2dd 100644
--- a/drivers/media/dvb-frontends/cx24113.c
+++ b/drivers/media/dvb-frontends/cx24113.c
@@ -22,7 +22,7 @@
#include <linux/module.h>
#include <linux/init.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "cx24113.h"
static int debug;
diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c
index 8fb3f095e21c..786c56a4ef76 100644
--- a/drivers/media/dvb-frontends/cx24116.c
+++ b/drivers/media/dvb-frontends/cx24116.c
@@ -41,7 +41,7 @@
#include <linux/init.h>
#include <linux/firmware.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "cx24116.h"
static int debug;
@@ -963,7 +963,7 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
/* Validate length */
if (d->msg_len > sizeof(d->msg))
- return -EINVAL;
+ return -EINVAL;
/* Dump DiSEqC message */
if (debug) {
diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c
index d37cb7762bd6..8935114b75f3 100644
--- a/drivers/media/dvb-frontends/cx24117.c
+++ b/drivers/media/dvb-frontends/cx24117.c
@@ -32,7 +32,7 @@
#include <linux/firmware.h>
#include "tuner-i2c.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "cx24117.h"
diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c
index 7f11dcc94d85..810f68acd69b 100644
--- a/drivers/media/dvb-frontends/cx24120.c
+++ b/drivers/media/dvb-frontends/cx24120.c
@@ -29,7 +29,7 @@
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/firmware.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "cx24120.h"
#define CX24120_SEARCH_RANGE_KHZ 5000
diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c
index 1d59d1d3bd82..228ba1f4bf63 100644
--- a/drivers/media/dvb-frontends/cx24123.c
+++ b/drivers/media/dvb-frontends/cx24123.c
@@ -24,7 +24,7 @@
#include <linux/init.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "cx24123.h"
#define XTAL 10111000
diff --git a/drivers/media/dvb-frontends/cxd2820r_priv.h b/drivers/media/dvb-frontends/cxd2820r_priv.h
index 0d096206ac66..61adde4b4b2f 100644
--- a/drivers/media/dvb-frontends/cxd2820r_priv.h
+++ b/drivers/media/dvb-frontends/cxd2820r_priv.h
@@ -23,8 +23,8 @@
#define CXD2820R_PRIV_H
#include <linux/dvb/version.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
#include "cxd2820r.h"
#include <linux/gpio.h>
#include <linux/math64.h>
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
index 48ee9bc00c06..85905d3503ff 100644
--- a/drivers/media/dvb-frontends/cxd2841er.c
+++ b/drivers/media/dvb-frontends/cxd2841er.c
@@ -29,9 +29,10 @@
#include <linux/math64.h>
#include <linux/log2.h>
#include <linux/dynamic_debug.h>
+#include <linux/kernel.h>
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_math.h>
+#include <media/dvb_frontend.h>
#include "cxd2841er.h"
#include "cxd2841er_priv.h"
@@ -257,7 +258,9 @@ static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
static int cxd2841er_write_reg(struct cxd2841er_priv *priv,
u8 addr, u8 reg, u8 val)
{
- return cxd2841er_write_regs(priv, addr, reg, &val, 1);
+ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+ return cxd2841er_write_regs(priv, addr, reg, &tmp, 1);
}
static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
@@ -1696,12 +1699,10 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
min_index = 0;
if (delsys == SYS_DVBS) {
cn_data = s_cn_data;
- max_index = sizeof(s_cn_data) /
- sizeof(s_cn_data[0]) - 1;
+ max_index = ARRAY_SIZE(s_cn_data) - 1;
} else {
cn_data = s2_cn_data;
- max_index = sizeof(s2_cn_data) /
- sizeof(s2_cn_data[0]) - 1;
+ max_index = ARRAY_SIZE(s2_cn_data) - 1;
}
if (value >= cn_data[min_index].value) {
res = cn_data[min_index].cnr_x1000;
@@ -3340,13 +3341,17 @@ static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
cxd2841er_tune_done(priv);
timeout = ((3000000 + (symbol_rate - 1)) / symbol_rate) + 150;
- for (i = 0; i < timeout / CXD2841ER_DVBS_POLLING_INVL; i++) {
+
+ i = 0;
+ do {
usleep_range(CXD2841ER_DVBS_POLLING_INVL*1000,
(CXD2841ER_DVBS_POLLING_INVL + 2) * 1000);
cxd2841er_read_status_s(fe, &status);
if (status & FE_HAS_LOCK)
break;
- }
+ i++;
+ } while (i < timeout / CXD2841ER_DVBS_POLLING_INVL);
+
if (status & FE_HAS_LOCK) {
if (cxd2841er_get_carrier_offset_s_s2(
priv, &carr_offset)) {
diff --git a/drivers/media/dvb-frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c
index d7614b8b8782..932d235118e2 100644
--- a/drivers/media/dvb-frontends/dib0070.c
+++ b/drivers/media/dvb-frontends/dib0070.c
@@ -27,7 +27,7 @@
#include <linux/i2c.h>
#include <linux/mutex.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "dib0070.h"
#include "dibx000_common.h"
diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c
index d9d730dfe0b1..64f49c8eb1fb 100644
--- a/drivers/media/dvb-frontends/dib0090.c
+++ b/drivers/media/dvb-frontends/dib0090.c
@@ -27,7 +27,7 @@
#include <linux/i2c.h>
#include <linux/mutex.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "dib0090.h"
#include "dibx000_common.h"
diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c
index 068bec104e29..de3ce2786c72 100644
--- a/drivers/media/dvb-frontends/dib3000mb.c
+++ b/drivers/media/dvb-frontends/dib3000mb.c
@@ -30,7 +30,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "dib3000.h"
#include "dib3000mb_priv.h"
diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c
index 4d086a7248e9..7e5d474806a5 100644
--- a/drivers/media/dvb-frontends/dib3000mc.c
+++ b/drivers/media/dvb-frontends/dib3000mc.c
@@ -17,7 +17,7 @@
#include <linux/slab.h>
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "dib3000mc.h"
diff --git a/drivers/media/dvb-frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c
index 5ce9f93a65c3..6a1d357d0c7c 100644
--- a/drivers/media/dvb-frontends/dib7000m.c
+++ b/drivers/media/dvb-frontends/dib7000m.c
@@ -16,7 +16,7 @@
#include <linux/i2c.h>
#include <linux/mutex.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "dib7000m.h"
diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c
index 0fbaabe43682..90ace707a80d 100644
--- a/drivers/media/dvb-frontends/dib7000p.c
+++ b/drivers/media/dvb-frontends/dib7000p.c
@@ -16,8 +16,8 @@
#include <linux/mutex.h>
#include <asm/div64.h>
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_math.h>
+#include <media/dvb_frontend.h>
#include "dib7000p.h"
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c
index 5d9381509b07..e64014f338fb 100644
--- a/drivers/media/dvb-frontends/dib8000.c
+++ b/drivers/media/dvb-frontends/dib8000.c
@@ -16,9 +16,9 @@
#include <linux/mutex.h>
#include <asm/div64.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "dib8000.h"
diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c
index 1b7a4331af05..f9289f488de7 100644
--- a/drivers/media/dvb-frontends/dib9000.c
+++ b/drivers/media/dvb-frontends/dib9000.c
@@ -14,8 +14,8 @@
#include <linux/i2c.h>
#include <linux/mutex.h>
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_math.h>
+#include <media/dvb_frontend.h>
#include "dib9000.h"
#include "dibx000_common.h"
diff --git a/drivers/media/dvb-frontends/dibx000_common.c b/drivers/media/dvb-frontends/dibx000_common.c
index bc28184c7fb0..d981233e458f 100644
--- a/drivers/media/dvb-frontends/dibx000_common.c
+++ b/drivers/media/dvb-frontends/dibx000_common.c
@@ -288,8 +288,8 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
int ret;
if (num > 32) {
- dprintk("%s: too much I2C message to be transmitted (%i).\
- Maximum is 32", __func__, num);
+ dprintk("%s: too much I2C message to be transmitted (%i). Maximum is 32",
+ __func__, num);
return -ENOMEM;
}
@@ -335,8 +335,8 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
int ret;
if (num > 32) {
- dprintk("%s: too much I2C message to be transmitted (%i).\
- Maximum is 32", __func__, num);
+ dprintk("%s: too much I2C message to be transmitted (%i). Maximum is 32",
+ __func__, num);
return -ENOMEM;
}
diff --git a/drivers/media/dvb-frontends/drx39xyj/Makefile b/drivers/media/dvb-frontends/drx39xyj/Makefile
index 672e07774955..87f6eddcf657 100644
--- a/drivers/media/dvb-frontends/drx39xyj/Makefile
+++ b/drivers/media/dvb-frontends/drx39xyj/Makefile
@@ -2,5 +2,4 @@ drx39xyj-objs := drxj.o
obj-$(CONFIG_DVB_DRX39XYJ) += drx39xyj.o
-ccflags-y += -I$(srctree)/drivers/media/dvb-core/
ccflags-y += -I$(srctree)/drivers/media/tuners/
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h b/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
index 11e1ddeeef0a..c0c66ed65b6e 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
+++ b/drivers/media/dvb-frontends/drx39xyj/drx39xxj.h
@@ -19,7 +19,7 @@
#define DRX39XXJ_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "drx_driver.h"
struct drx39xxj_state {
diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
index 855685b6b386..1ec20eecc433 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
+++ b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h
@@ -932,7 +932,7 @@ STRUCTS
* Used by DRX_CTRL_LOAD_UCODE and DRX_CTRL_VERIFY_UCODE
*/
struct drxu_code_info {
- char *mc_file;
+ char *mc_file;
};
/*
diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c
index 8cbd8cc21059..5706898e84cc 100644
--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c
+++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c
@@ -61,7 +61,7 @@ INCLUDE FILES
#include <linux/slab.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "drx39xxj.h"
#include "drxj.h"
@@ -2151,9 +2151,13 @@ int drxj_dap_atomic_read_write_block(struct i2c_device_addr *dev_addr,
if (read_flag) {
/* read data from buffer */
for (i = 0; i < (datasize / 2); i++) {
- drxj_dap_read_reg16(dev_addr,
- (DRXJ_HI_ATOMIC_BUF_START + i),
- &word, 0);
+ rc = drxj_dap_read_reg16(dev_addr,
+ (DRXJ_HI_ATOMIC_BUF_START + i),
+ &word, 0);
+ if (rc) {
+ pr_err("error %d\n", rc);
+ goto rw_error;
+ }
data[2 * i] = (u8) (word & 0xFF);
data[(2 * i) + 1] = (u8) (word >> 8);
}
@@ -11074,7 +11078,7 @@ ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode)
}
}
- if ((*mode == DRX_POWER_UP)) {
+ if (*mode == DRX_POWER_UP) {
/* Restore analog & pin configuration */
/* Initialize default AFE configuration for VSB */
@@ -11723,7 +11727,7 @@ eof:
* - In case of UCODE_UPLOAD: I2C error.
* - In case of UCODE_VERIFY: I2C error or image on device
* is not equal to image provided to this control function.
- * -EINVAL:
+ * -EINVAL:
* - Invalid arguments.
* - Provided image is corrupt
*/
diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c
index 0696bc62dcc9..3b7d31a22d82 100644
--- a/drivers/media/dvb-frontends/drxd_hard.c
+++ b/drivers/media/dvb-frontends/drxd_hard.c
@@ -26,7 +26,7 @@
#include <linux/i2c.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "drxd.h"
#include "drxd_firm.h"
@@ -972,7 +972,6 @@ static int DownloadMicrocode(struct drxd_state *state,
static int HI_Command(struct drxd_state *state, u16 cmd, u16 * pResult)
{
u32 nrRetries = 0;
- u16 waitCmd;
int status;
status = Write16(state, HI_RA_RAM_SRV_CMD__A, cmd, 0);
@@ -985,8 +984,8 @@ static int HI_Command(struct drxd_state *state, u16 cmd, u16 * pResult)
status = -1;
break;
}
- status = Read16(state, HI_RA_RAM_SRV_CMD__A, &waitCmd, 0);
- } while (waitCmd != 0);
+ status = Read16(state, HI_RA_RAM_SRV_CMD__A, NULL, 0);
+ } while (status != 0);
if (status >= 0)
status = Read16(state, HI_RA_RAM_SRV_RES__A, pResult, 0);
@@ -1298,12 +1297,11 @@ static int InitFT(struct drxd_state *state)
static int SC_WaitForReady(struct drxd_state *state)
{
- u16 curCmd;
int i;
for (i = 0; i < DRXD_MAX_RETRIES; i += 1) {
- int status = Read16(state, SC_RA_RAM_CMD__A, &curCmd, 0);
- if (status == 0 || curCmd == 0)
+ int status = Read16(state, SC_RA_RAM_CMD__A, NULL, 0);
+ if (status == 0)
return status;
}
return -1;
@@ -1311,15 +1309,15 @@ static int SC_WaitForReady(struct drxd_state *state)
static int SC_SendCommand(struct drxd_state *state, u16 cmd)
{
- int status = 0;
+ int status = 0, ret;
u16 errCode;
Write16(state, SC_RA_RAM_CMD__A, cmd, 0);
SC_WaitForReady(state);
- Read16(state, SC_RA_RAM_CMD_ADDR__A, &errCode, 0);
+ ret = Read16(state, SC_RA_RAM_CMD_ADDR__A, &errCode, 0);
- if (errCode == 0xFFFF) {
+ if (ret < 0 || errCode == 0xFFFF) {
printk(KERN_ERR "Command Error\n");
status = -1;
}
@@ -1330,13 +1328,13 @@ static int SC_SendCommand(struct drxd_state *state, u16 cmd)
static int SC_ProcStartCommand(struct drxd_state *state,
u16 subCmd, u16 param0, u16 param1)
{
- int status = 0;
+ int ret, status = 0;
u16 scExec;
mutex_lock(&state->mutex);
do {
- Read16(state, SC_COMM_EXEC__A, &scExec, 0);
- if (scExec != 1) {
+ ret = Read16(state, SC_COMM_EXEC__A, &scExec, 0);
+ if (ret < 0 || scExec != 1) {
status = -1;
break;
}
@@ -2140,7 +2138,6 @@ static int DRX_Start(struct drxd_state *state, s32 off)
}
break;
}
- status = status;
if (status < 0)
break;
@@ -2251,7 +2248,6 @@ static int DRX_Start(struct drxd_state *state, s32 off)
break;
}
- status = status;
if (status < 0)
break;
@@ -2318,7 +2314,6 @@ static int DRX_Start(struct drxd_state *state, s32 off)
}
break;
}
- status = status;
if (status < 0)
break;
diff --git a/drivers/media/dvb-frontends/drxk.h b/drivers/media/dvb-frontends/drxk.h
index b16fedbb53a3..76466f7ec3a0 100644
--- a/drivers/media/dvb-frontends/drxk.h
+++ b/drivers/media/dvb-frontends/drxk.h
@@ -10,7 +10,7 @@
*
* @adr: I2C address of the DRX-K
* @parallel_ts: True means that the device uses parallel TS,
- * Serial otherwise.
+ * Serial otherwise.
* @dynamic_clk: True means that the clock will be dynamically
* adjusted. Static clock otherwise.
* @enable_merr_cfg: Enable SIO_PDR_PERR_CFG/SIO_PDR_MVAL_CFG.
@@ -67,8 +67,8 @@ extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
static inline struct dvb_frontend *drxk_attach(const struct drxk_config *config,
struct i2c_adapter *i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
}
#endif
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c
index f59ac2e91c59..5a26ad93be10 100644
--- a/drivers/media/dvb-frontends/drxk_hard.c
+++ b/drivers/media/dvb-frontends/drxk_hard.c
@@ -29,10 +29,10 @@
#include <linux/hardirq.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "drxk.h"
#include "drxk_hard.h"
-#include "dvb_math.h"
+#include <media/dvb_math.h>
static int power_down_dvbt(struct drxk_state *state, bool set_power_mode);
static int power_down_qam(struct drxk_state *state);
@@ -6062,7 +6062,7 @@ static int init_drxk(struct drxk_state *state)
u16 driver_version;
dprintk(1, "\n");
- if ((state->m_drxk_state == DRXK_UNINITIALIZED)) {
+ if (state->m_drxk_state == DRXK_UNINITIALIZED) {
drxk_i2c_lock(state);
status = power_up_device(state);
if (status < 0)
diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c
index bd4f8278c906..2ff90e5eabce 100644
--- a/drivers/media/dvb-frontends/ds3000.c
+++ b/drivers/media/dvb-frontends/ds3000.c
@@ -26,7 +26,7 @@
#include <linux/init.h>
#include <linux/firmware.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "ts2020.h"
#include "ds3000.h"
diff --git a/drivers/media/dvb-frontends/dvb-pll.h b/drivers/media/dvb-frontends/dvb-pll.h
index 212e0730f154..ca885e71d2f0 100644
--- a/drivers/media/dvb-frontends/dvb-pll.h
+++ b/drivers/media/dvb-frontends/dvb-pll.h
@@ -7,7 +7,7 @@
#define __DVB_PLL_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#define DVB_PLL_UNDEFINED 0
#define DVB_PLL_THOMSON_DTT7579 1
diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.c b/drivers/media/dvb-frontends/dvb_dummy_fe.c
index 50b2b666ef6c..6650d4f61ef2 100644
--- a/drivers/media/dvb-frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb-frontends/dvb_dummy_fe.c
@@ -20,7 +20,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "dvb_dummy_fe.h"
diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.h b/drivers/media/dvb-frontends/dvb_dummy_fe.h
index 86dd7b9d1e57..7aacef4b7c80 100644
--- a/drivers/media/dvb-frontends/dvb_dummy_fe.h
+++ b/drivers/media/dvb-frontends/dvb_dummy_fe.h
@@ -19,7 +19,7 @@
#define DVB_DUMMY_FE_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#if IS_REACHABLE(CONFIG_DVB_DUMMY_FE)
extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
diff --git a/drivers/media/dvb-frontends/ec100.c b/drivers/media/dvb-frontends/ec100.c
index fa2a96d5f94e..c2575fdcc811 100644
--- a/drivers/media/dvb-frontends/ec100.c
+++ b/drivers/media/dvb-frontends/ec100.c
@@ -15,7 +15,7 @@
*
*/
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "ec100.h"
struct ec100_state {
diff --git a/drivers/media/dvb-frontends/gp8psk-fe.c b/drivers/media/dvb-frontends/gp8psk-fe.c
index efe015df7f1d..a772ef8bfe1c 100644
--- a/drivers/media/dvb-frontends/gp8psk-fe.c
+++ b/drivers/media/dvb-frontends/gp8psk-fe.c
@@ -16,7 +16,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include "gp8psk-fe.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
static int debug;
module_param(debug, int, 0644);
diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c
index 4bf5a551ba40..a0d0b53c91d7 100644
--- a/drivers/media/dvb-frontends/helene.c
+++ b/drivers/media/dvb-frontends/helene.c
@@ -23,7 +23,7 @@
#include <linux/dvb/frontend.h>
#include <linux/types.h>
#include "helene.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#define MAX_WRITE_REGSIZE 20
@@ -331,7 +331,9 @@ static int helene_write_regs(struct helene_priv *priv,
static int helene_write_reg(struct helene_priv *priv, u8 reg, u8 val)
{
- return helene_write_regs(priv, reg, &val, 1);
+ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+ return helene_write_regs(priv, reg, &tmp, 1);
}
static int helene_read_regs(struct helene_priv *priv,
diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c
index 68d759c4c52e..5e7e265a52e6 100644
--- a/drivers/media/dvb-frontends/horus3a.c
+++ b/drivers/media/dvb-frontends/horus3a.c
@@ -24,7 +24,7 @@
#include <linux/dvb/frontend.h>
#include <linux/types.h>
#include "horus3a.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#define MAX_WRITE_REGSIZE 5
@@ -89,7 +89,9 @@ static int horus3a_write_regs(struct horus3a_priv *priv,
static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val)
{
- return horus3a_write_regs(priv, reg, &val, 1);
+ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+ return horus3a_write_regs(priv, reg, &tmp, 1);
}
static int horus3a_enter_power_save(struct horus3a_priv *priv)
diff --git a/drivers/media/dvb-frontends/isl6405.c b/drivers/media/dvb-frontends/isl6405.c
index 2fc8d3c72c11..3bc78f8ffc00 100644
--- a/drivers/media/dvb-frontends/isl6405.c
+++ b/drivers/media/dvb-frontends/isl6405.c
@@ -29,7 +29,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "isl6405.h"
struct isl6405 {
diff --git a/drivers/media/dvb-frontends/isl6421.c b/drivers/media/dvb-frontends/isl6421.c
index 3f3487887672..ae8ec59b665c 100644
--- a/drivers/media/dvb-frontends/isl6421.c
+++ b/drivers/media/dvb-frontends/isl6421.c
@@ -29,7 +29,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "isl6421.h"
struct isl6421 {
diff --git a/drivers/media/dvb-frontends/isl6423.c b/drivers/media/dvb-frontends/isl6423.c
index dca5bebfeeb5..3dd2465d17cf 100644
--- a/drivers/media/dvb-frontends/isl6423.c
+++ b/drivers/media/dvb-frontends/isl6423.c
@@ -26,7 +26,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "isl6423.h"
static unsigned int verbose;
diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c
index 5bb1e73a10b4..04f7f6854f73 100644
--- a/drivers/media/dvb-frontends/itd1000.c
+++ b/drivers/media/dvb-frontends/itd1000.c
@@ -22,7 +22,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "itd1000.h"
#include "itd1000_priv.h"
@@ -95,8 +95,9 @@ static int itd1000_read_reg(struct itd1000_state *state, u8 reg)
static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
{
- int ret = itd1000_write_regs(state, r, &v, 1);
- state->shadow[r] = v;
+ u8 tmp = v; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+ int ret = itd1000_write_regs(state, r, &tmp, 1);
+ state->shadow[r] = tmp;
return ret;
}
diff --git a/drivers/media/dvb-frontends/ix2505v.h b/drivers/media/dvb-frontends/ix2505v.h
index 49ed93e754ed..20b1eb3dda1a 100644
--- a/drivers/media/dvb-frontends/ix2505v.h
+++ b/drivers/media/dvb-frontends/ix2505v.h
@@ -17,7 +17,7 @@
#define DVB_IX2505V_H
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/**
* struct ix2505v_config - ix2505 attachment configuration
diff --git a/drivers/media/dvb-frontends/l64781.c b/drivers/media/dvb-frontends/l64781.c
index e5a6c1766664..e056f36e6f0c 100644
--- a/drivers/media/dvb-frontends/l64781.c
+++ b/drivers/media/dvb-frontends/l64781.c
@@ -25,7 +25,7 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "l64781.h"
diff --git a/drivers/media/dvb-frontends/lg2160.h b/drivers/media/dvb-frontends/lg2160.h
index ba99125deac0..df817aec29e2 100644
--- a/drivers/media/dvb-frontends/lg2160.h
+++ b/drivers/media/dvb-frontends/lg2160.h
@@ -19,7 +19,7 @@
#define _LG2160_H_
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
enum lg_chip_type {
LG2160 = 0,
diff --git a/drivers/media/dvb-frontends/lgdt3305.c b/drivers/media/dvb-frontends/lgdt3305.c
index 0af4d9104761..735d73060265 100644
--- a/drivers/media/dvb-frontends/lgdt3305.c
+++ b/drivers/media/dvb-frontends/lgdt3305.c
@@ -20,7 +20,7 @@
#include <asm/div64.h>
#include <linux/dvb/frontend.h>
#include <linux/slab.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
#include "lgdt3305.h"
static int debug;
diff --git a/drivers/media/dvb-frontends/lgdt3305.h b/drivers/media/dvb-frontends/lgdt3305.h
index 2fb60d91f7b4..a54daaee823a 100644
--- a/drivers/media/dvb-frontends/lgdt3305.h
+++ b/drivers/media/dvb-frontends/lgdt3305.h
@@ -19,7 +19,7 @@
#define _LGDT3305_H_
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
enum lgdt3305_mpeg_mode {
diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c
index 724e9aac0f11..6356815cf3e1 100644
--- a/drivers/media/dvb-frontends/lgdt3306a.c
+++ b/drivers/media/dvb-frontends/lgdt3306a.c
@@ -21,7 +21,7 @@
#include <asm/div64.h>
#include <linux/kernel.h>
#include <linux/dvb/frontend.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
#include "lgdt3306a.h"
#include <linux/i2c-mux.h>
diff --git a/drivers/media/dvb-frontends/lgdt3306a.h b/drivers/media/dvb-frontends/lgdt3306a.h
index 6ce337ec5272..8b53044f5bdb 100644
--- a/drivers/media/dvb-frontends/lgdt3306a.h
+++ b/drivers/media/dvb-frontends/lgdt3306a.h
@@ -19,7 +19,7 @@
#define _LGDT3306A_H_
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
enum lgdt3306a_mpeg_mode {
diff --git a/drivers/media/dvb-frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c
index 06f47dc8cd3d..8ad03bd81af5 100644
--- a/drivers/media/dvb-frontends/lgdt330x.c
+++ b/drivers/media/dvb-frontends/lgdt330x.c
@@ -37,8 +37,8 @@
#include <linux/slab.h>
#include <asm/byteorder.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
#include "lgdt330x_priv.h"
#include "lgdt330x.h"
diff --git a/drivers/media/dvb-frontends/lgs8gl5.c b/drivers/media/dvb-frontends/lgs8gl5.c
index 970e42fdbc1b..f47e5a1af16d 100644
--- a/drivers/media/dvb-frontends/lgs8gl5.c
+++ b/drivers/media/dvb-frontends/lgs8gl5.c
@@ -25,7 +25,7 @@
#include <linux/module.h>
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "lgs8gl5.h"
diff --git a/drivers/media/dvb-frontends/lgs8gxx.c b/drivers/media/dvb-frontends/lgs8gxx.c
index e6bf60e1138c..84af8a12f26a 100644
--- a/drivers/media/dvb-frontends/lgs8gxx.c
+++ b/drivers/media/dvb-frontends/lgs8gxx.c
@@ -22,7 +22,7 @@
#include <asm/div64.h>
#include <linux/firmware.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "lgs8gxx.h"
#include "lgs8gxx_priv.h"
diff --git a/drivers/media/dvb-frontends/lnbh25.c b/drivers/media/dvb-frontends/lnbh25.c
index cb486e879fdd..0b388502c298 100644
--- a/drivers/media/dvb-frontends/lnbh25.c
+++ b/drivers/media/dvb-frontends/lnbh25.c
@@ -23,7 +23,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "lnbh25.h"
/**
diff --git a/drivers/media/dvb-frontends/lnbp21.c b/drivers/media/dvb-frontends/lnbp21.c
index 392d7be93774..d9966a338a72 100644
--- a/drivers/media/dvb-frontends/lnbp21.c
+++ b/drivers/media/dvb-frontends/lnbp21.c
@@ -29,7 +29,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "lnbp21.h"
#include "lnbh24.h"
diff --git a/drivers/media/dvb-frontends/lnbp22.c b/drivers/media/dvb-frontends/lnbp22.c
index 39326a2ebab2..a62e82bf46f5 100644
--- a/drivers/media/dvb-frontends/lnbp22.c
+++ b/drivers/media/dvb-frontends/lnbp22.c
@@ -30,7 +30,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "lnbp22.h"
static int debug;
diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h b/drivers/media/dvb-frontends/m88ds3103_priv.h
index 07f20c269c67..1ba0b79df311 100644
--- a/drivers/media/dvb-frontends/m88ds3103_priv.h
+++ b/drivers/media/dvb-frontends/m88ds3103_priv.h
@@ -17,9 +17,9 @@
#ifndef M88DS3103_PRIV_H
#define M88DS3103_PRIV_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "m88ds3103.h"
-#include "dvb_math.h"
+#include <media/dvb_math.h>
#include <linux/firmware.h>
#include <linux/i2c-mux.h>
#include <linux/regmap.h>
diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c
index ce6c21d405ee..496ce27fa63a 100644
--- a/drivers/media/dvb-frontends/m88rs2000.c
+++ b/drivers/media/dvb-frontends/m88rs2000.c
@@ -31,7 +31,7 @@
#include <linux/types.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "m88rs2000.h"
struct m88rs2000_state {
@@ -630,13 +630,16 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
if (ret < 0)
return -ENODEV;
- if (fe->ops.tuner_ops.get_frequency)
+ if (fe->ops.tuner_ops.get_frequency) {
ret = fe->ops.tuner_ops.get_frequency(fe, &tuner_freq);
- if (ret < 0)
- return -ENODEV;
+ if (ret < 0)
+ return -ENODEV;
- offset = (s16)((s32)tuner_freq - c->frequency);
+ offset = (s16)((s32)tuner_freq - c->frequency);
+ } else {
+ offset = 0;
+ }
/* default mclk value 96.4285 * 2 * 1000 = 192857 */
if (((c->frequency % 192857) >= (192857 - 3000)) ||
diff --git a/drivers/media/dvb-frontends/m88rs2000.h b/drivers/media/dvb-frontends/m88rs2000.h
index 1a313b0f5875..b015872c4ff4 100644
--- a/drivers/media/dvb-frontends/m88rs2000.h
+++ b/drivers/media/dvb-frontends/m88rs2000.h
@@ -21,7 +21,7 @@
#define M88RS2000_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct m88rs2000_config {
/* Demodulator i2c address */
diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c
index dfe322eccaa1..2969ba6ed9e1 100644
--- a/drivers/media/dvb-frontends/mb86a16.c
+++ b/drivers/media/dvb-frontends/mb86a16.c
@@ -24,7 +24,7 @@
#include <linux/moduleparam.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mb86a16.h"
#include "mb86a16_priv.h"
@@ -635,6 +635,7 @@ static int sync_chk(struct mb86a16_state *state,
return sync;
err:
dprintk(verbose, MB86A16_ERROR, 1, "I2C transfer error");
+ *VIRM = 0;
return -EREMOTEIO;
}
@@ -1676,15 +1677,15 @@ static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
* the deinterleaver output.
* monitored BER is expressed as a 20 bit output in total
*/
- ber_rst = ber_mon >> 3;
+ ber_rst = (ber_mon >> 3) & 0x03;
*ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
if (ber_rst == 0)
timer = 12500000;
- if (ber_rst == 1)
+ else if (ber_rst == 1)
timer = 25000000;
- if (ber_rst == 2)
+ else if (ber_rst == 2)
timer = 50000000;
- if (ber_rst == 3)
+ else /* ber_rst == 3 */
timer = 100000000;
*ber /= timer;
@@ -1696,11 +1697,11 @@ static int mb86a16_read_ber(struct dvb_frontend *fe, u32 *ber)
* QPSK demodulator output.
* monitored BER is expressed as a 24 bit output in total
*/
- ber_tim = ber_mon >> 1;
+ ber_tim = (ber_mon >> 1) & 0x01;
*ber = (((ber_msb << 8) | ber_mid) << 8) | ber_lsb;
if (ber_tim == 0)
timer = 16;
- if (ber_tim == 1)
+ else /* ber_tim == 1 */
timer = 24;
*ber /= 2 ^ timer;
diff --git a/drivers/media/dvb-frontends/mb86a16.h b/drivers/media/dvb-frontends/mb86a16.h
index dbd5f43fa128..f13820bc7a21 100644
--- a/drivers/media/dvb-frontends/mb86a16.h
+++ b/drivers/media/dvb-frontends/mb86a16.h
@@ -22,7 +22,7 @@
#define __MB86A16_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct mb86a16_config {
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
index bdaf9d235fed..36e95196dff4 100644
--- a/drivers/media/dvb-frontends/mb86a20s.c
+++ b/drivers/media/dvb-frontends/mb86a20s.c
@@ -17,7 +17,7 @@
#include <linux/kernel.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mb86a20s.h"
#define NUM_LAYERS 3
@@ -2057,7 +2057,7 @@ static void mb86a20s_release(struct dvb_frontend *fe)
static int mb86a20s_get_frontend_algo(struct dvb_frontend *fe)
{
- return DVBFE_ALGO_HW;
+ return DVBFE_ALGO_HW;
}
static const struct dvb_frontend_ops mb86a20s_ops;
diff --git a/drivers/media/dvb-frontends/mn88472_priv.h b/drivers/media/dvb-frontends/mn88472_priv.h
index fb50f56ba30b..2ec126a42527 100644
--- a/drivers/media/dvb-frontends/mn88472_priv.h
+++ b/drivers/media/dvb-frontends/mn88472_priv.h
@@ -17,8 +17,8 @@
#ifndef MN88472_PRIV_H
#define MN88472_PRIV_H
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
#include "mn88472.h"
#include <linux/firmware.h>
#include <linux/regmap.h>
diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c
index 58247432a628..ca722084e534 100644
--- a/drivers/media/dvb-frontends/mn88473.c
+++ b/drivers/media/dvb-frontends/mn88473.c
@@ -764,7 +764,7 @@ MODULE_DEVICE_TABLE(i2c, mn88473_id_table);
static struct i2c_driver mn88473_driver = {
.driver = {
- .name = "mn88473",
+ .name = "mn88473",
.suppress_bind_attrs = true,
},
.probe = mn88473_probe,
diff --git a/drivers/media/dvb-frontends/mn88473_priv.h b/drivers/media/dvb-frontends/mn88473_priv.h
index 5fc463d147c8..d89a86320263 100644
--- a/drivers/media/dvb-frontends/mn88473_priv.h
+++ b/drivers/media/dvb-frontends/mn88473_priv.h
@@ -17,8 +17,8 @@
#ifndef MN88473_PRIV_H
#define MN88473_PRIV_H
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
#include "mn88473.h"
#include <linux/math64.h>
#include <linux/firmware.h>
diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c
index 961b9a2508e0..e2a3fc521620 100644
--- a/drivers/media/dvb-frontends/mt312.c
+++ b/drivers/media/dvb-frontends/mt312.c
@@ -32,7 +32,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mt312_priv.h"
#include "mt312.h"
@@ -142,7 +142,10 @@ static inline int mt312_readreg(struct mt312_state *state,
static inline int mt312_writereg(struct mt312_state *state,
const enum mt312_reg_addr reg, const u8 val)
{
- return mt312_write(state, reg, &val, 1);
+ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+
+ return mt312_write(state, reg, &tmp, 1);
}
static inline u32 mt312_div(u32 a, u32 b)
diff --git a/drivers/media/dvb-frontends/mt352.c b/drivers/media/dvb-frontends/mt352.c
index d5fa96f0a6cd..a440b76444d3 100644
--- a/drivers/media/dvb-frontends/mt352.c
+++ b/drivers/media/dvb-frontends/mt352.c
@@ -33,7 +33,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mt352_priv.h"
#include "mt352.h"
diff --git a/drivers/media/dvb-frontends/mxl5xx.c b/drivers/media/dvb-frontends/mxl5xx.c
index 53064e11f5f1..e899821018a0 100644
--- a/drivers/media/dvb-frontends/mxl5xx.c
+++ b/drivers/media/dvb-frontends/mxl5xx.c
@@ -33,7 +33,7 @@
#include <asm/div64.h>
#include <asm/unaligned.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mxl5xx.h"
#include "mxl5xx_regs.h"
#include "mxl5xx_defs.h"
@@ -636,16 +636,9 @@ static int tune(struct dvb_frontend *fe, bool re_tune,
if (r)
return r;
state->tune_time = jiffies;
- return 0;
}
- if (*status & FE_HAS_LOCK)
- return 0;
- r = read_status(fe, status);
- if (r)
- return r;
-
- return 0;
+ return read_status(fe, status);
}
static enum fe_code_rate conv_fec(enum MXL_HYDRA_FEC_E fec)
diff --git a/drivers/media/dvb-frontends/mxl5xx.h b/drivers/media/dvb-frontends/mxl5xx.h
index 532e08111537..ad4c21846800 100644
--- a/drivers/media/dvb-frontends/mxl5xx.h
+++ b/drivers/media/dvb-frontends/mxl5xx.h
@@ -4,7 +4,7 @@
#include <linux/types.h>
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct mxl5xx_cfg {
u8 adr;
diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c
index bf6e5cd572c5..7aa74403648e 100644
--- a/drivers/media/dvb-frontends/nxt200x.c
+++ b/drivers/media/dvb-frontends/nxt200x.c
@@ -48,7 +48,7 @@
#include <linux/slab.h>
#include <linux/string.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "nxt200x.h"
struct nxt200x_state {
diff --git a/drivers/media/dvb-frontends/nxt6000.c b/drivers/media/dvb-frontends/nxt6000.c
index 1ce5ea28489b..109a635d166a 100644
--- a/drivers/media/dvb-frontends/nxt6000.c
+++ b/drivers/media/dvb-frontends/nxt6000.c
@@ -27,7 +27,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "nxt6000_priv.h"
#include "nxt6000.h"
diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c
index 5f2549c48eb0..b4c9aadcb552 100644
--- a/drivers/media/dvb-frontends/or51132.c
+++ b/drivers/media/dvb-frontends/or51132.c
@@ -38,8 +38,8 @@
#include <linux/slab.h>
#include <asm/byteorder.h>
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_math.h>
+#include <media/dvb_frontend.h>
#include "or51132.h"
static int debug;
diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c
index d14fa9736ae5..a1b7c301828f 100644
--- a/drivers/media/dvb-frontends/or51211.c
+++ b/drivers/media/dvb-frontends/or51211.c
@@ -36,8 +36,8 @@
#include <linux/slab.h>
#include <asm/byteorder.h>
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_math.h>
+#include <media/dvb_frontend.h>
#include "or51211.h"
static int debug;
diff --git a/drivers/media/dvb-frontends/rtl2830_priv.h b/drivers/media/dvb-frontends/rtl2830_priv.h
index 8ec4721d79ac..72d3f3546ff2 100644
--- a/drivers/media/dvb-frontends/rtl2830_priv.h
+++ b/drivers/media/dvb-frontends/rtl2830_priv.h
@@ -18,8 +18,8 @@
#ifndef RTL2830_PRIV_H
#define RTL2830_PRIV_H
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
#include "rtl2830.h"
#include <linux/i2c-mux.h>
#include <linux/math64.h>
diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h b/drivers/media/dvb-frontends/rtl2832_priv.h
index 9a6d01a9c690..bd13d9ad9ab7 100644
--- a/drivers/media/dvb-frontends/rtl2832_priv.h
+++ b/drivers/media/dvb-frontends/rtl2832_priv.h
@@ -26,8 +26,8 @@
#include <linux/math64.h>
#include <linux/bitops.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
#include "rtl2832.h"
struct rtl2832_dev {
diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.h b/drivers/media/dvb-frontends/rtl2832_sdr.h
index 8f88c2fb8627..d28735c1cb0c 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.h
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.h
@@ -27,7 +27,7 @@
#include <linux/i2c.h>
#include <media/v4l2-subdev.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/**
* struct rtl2832_sdr_platform_data - Platform data for the rtl2832_sdr driver
diff --git a/drivers/media/dvb-frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c
index f370c6df0a8b..aced6a956ec5 100644
--- a/drivers/media/dvb-frontends/s5h1409.c
+++ b/drivers/media/dvb-frontends/s5h1409.c
@@ -25,7 +25,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "s5h1409.h"
struct s5h1409_state {
diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c
index dd09336a135b..c4b1e9725f3e 100644
--- a/drivers/media/dvb-frontends/s5h1411.c
+++ b/drivers/media/dvb-frontends/s5h1411.c
@@ -25,7 +25,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "s5h1411.h"
struct s5h1411_state {
diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c
index fd427a29c001..8b2222530227 100644
--- a/drivers/media/dvb-frontends/s5h1420.c
+++ b/drivers/media/dvb-frontends/s5h1420.c
@@ -30,7 +30,7 @@
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "s5h1420.h"
#include "s5h1420_priv.h"
diff --git a/drivers/media/dvb-frontends/s5h1432.c b/drivers/media/dvb-frontends/s5h1432.c
index 4de50fe0c638..740a60df0455 100644
--- a/drivers/media/dvb-frontends/s5h1432.c
+++ b/drivers/media/dvb-frontends/s5h1432.c
@@ -20,7 +20,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "s5h1432.h"
struct s5h1432_state {
diff --git a/drivers/media/dvb-frontends/s921.c b/drivers/media/dvb-frontends/s921.c
index 274544a3ae0e..2d75ede77aca 100644
--- a/drivers/media/dvb-frontends/s921.c
+++ b/drivers/media/dvb-frontends/s921.c
@@ -25,7 +25,7 @@
#include <linux/kernel.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "s921.h"
static int debug = 1;
diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c
index 528b82a5dd46..2dd336f95cbf 100644
--- a/drivers/media/dvb-frontends/si2165.c
+++ b/drivers/media/dvb-frontends/si2165.c
@@ -1,7 +1,7 @@
/*
* Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator
*
- * Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.org>
+ * Copyright (C) 2013-2017 Matthias Schwarzott <zzam@gentoo.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
@@ -27,8 +27,8 @@
#include <linux/firmware.h>
#include <linux/regmap.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
#include "si2165_priv.h"
#include "si2165.h"
@@ -57,63 +57,21 @@ struct si2165_state {
u32 sys_clk;
u32 adc_clk;
+ /* DVBv3 stats */
+ u64 ber_prev;
+
bool has_dvbc;
bool has_dvbt;
bool firmware_loaded;
};
-#define DEBUG_OTHER 0x01
-#define DEBUG_I2C_WRITE 0x02
-#define DEBUG_I2C_READ 0x04
-#define DEBUG_REG_READ 0x08
-#define DEBUG_REG_WRITE 0x10
-#define DEBUG_FW_LOAD 0x20
-
-static int debug = 0x00;
-
-#define dprintk(args...) \
- do { \
- if (debug & DEBUG_OTHER) \
- printk(KERN_DEBUG "si2165: " args); \
- } while (0)
-
-#define deb_i2c_write(args...) \
- do { \
- if (debug & DEBUG_I2C_WRITE) \
- printk(KERN_DEBUG "si2165: i2c write: " args); \
- } while (0)
-
-#define deb_i2c_read(args...) \
- do { \
- if (debug & DEBUG_I2C_READ) \
- printk(KERN_DEBUG "si2165: i2c read: " args); \
- } while (0)
-
-#define deb_readreg(args...) \
- do { \
- if (debug & DEBUG_REG_READ) \
- printk(KERN_DEBUG "si2165: reg read: " args); \
- } while (0)
-
-#define deb_writereg(args...) \
- do { \
- if (debug & DEBUG_REG_WRITE) \
- printk(KERN_DEBUG "si2165: reg write: " args); \
- } while (0)
-
-#define deb_fw_load(args...) \
- do { \
- if (debug & DEBUG_FW_LOAD) \
- printk(KERN_DEBUG "si2165: fw load: " args); \
- } while (0)
-
static int si2165_write(struct si2165_state *state, const u16 reg,
- const u8 *src, const int count)
+ const u8 *src, const int count)
{
int ret;
- if (debug & DEBUG_I2C_WRITE)
- deb_i2c_write("reg: 0x%04x, data: %*ph\n", reg, count, src);
+ dev_dbg(&state->client->dev, "i2c write: reg: 0x%04x, data: %*ph\n",
+ reg, count, src);
ret = regmap_bulk_write(state->regmap, reg, src, count);
@@ -134,30 +92,41 @@ static int si2165_read(struct si2165_state *state,
return ret;
}
- if (debug & DEBUG_I2C_READ)
- deb_i2c_read("reg: 0x%04x, data: %*ph\n", reg, count, val);
+ dev_dbg(&state->client->dev, "i2c read: reg: 0x%04x, data: %*ph\n",
+ reg, count, val);
return 0;
}
static int si2165_readreg8(struct si2165_state *state,
- const u16 reg, u8 *val)
+ const u16 reg, u8 *val)
{
unsigned int val_tmp;
int ret = regmap_read(state->regmap, reg, &val_tmp);
*val = (u8)val_tmp;
- deb_readreg("R(0x%04x)=0x%02x\n", reg, *val);
+ dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%02x\n", reg, *val);
return ret;
}
static int si2165_readreg16(struct si2165_state *state,
- const u16 reg, u16 *val)
+ const u16 reg, u16 *val)
{
u8 buf[2];
int ret = si2165_read(state, reg, buf, 2);
*val = buf[0] | buf[1] << 8;
- deb_readreg("R(0x%04x)=0x%04x\n", reg, *val);
+ dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%04x\n", reg, *val);
+ return ret;
+}
+
+static int si2165_readreg24(struct si2165_state *state,
+ const u16 reg, u32 *val)
+{
+ u8 buf[3];
+
+ int ret = si2165_read(state, reg, buf, 3);
+ *val = buf[0] | buf[1] << 8 | buf[2] << 16;
+ dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%06x\n", reg, *val);
return ret;
}
@@ -208,7 +177,9 @@ static int si2165_writereg_mask8(struct si2165_state *state, const u16 reg,
return si2165_writereg8(state, reg, val);
}
-#define REG16(reg, val) { (reg), (val) & 0xff }, { (reg)+1, (val)>>8 & 0xff }
+#define REG16(reg, val) \
+ { (reg), (val) & 0xff }, \
+ { (reg) + 1, (val) >> 8 & 0xff }
struct si2165_reg_value_pair {
u16 reg;
u8 val;
@@ -238,7 +209,7 @@ static int si2165_get_tune_settings(struct dvb_frontend *fe,
static int si2165_init_pll(struct si2165_state *state)
{
- u32 ref_freq_Hz = state->config.ref_freq_Hz;
+ u32 ref_freq_hz = state->config.ref_freq_hz;
u8 divr = 1; /* 1..7 */
u8 divp = 1; /* only 1 or 4 */
u8 divn = 56; /* 1..63 */
@@ -250,7 +221,7 @@ static int si2165_init_pll(struct si2165_state *state)
* hardcoded values can be deleted if calculation is verified
* or it yields the same values as the windows driver
*/
- switch (ref_freq_Hz) {
+ switch (ref_freq_hz) {
case 16000000u:
divn = 56;
break;
@@ -261,39 +232,39 @@ static int si2165_init_pll(struct si2165_state *state)
break;
default:
/* ref_freq / divr must be between 4 and 16 MHz */
- if (ref_freq_Hz > 16000000u)
+ if (ref_freq_hz > 16000000u)
divr = 2;
/*
* now select divn and divp such that
* fvco is in 1624..1824 MHz
*/
- if (1624000000u * divr > ref_freq_Hz * 2u * 63u)
+ if (1624000000u * divr > ref_freq_hz * 2u * 63u)
divp = 4;
/* is this already correct regarding rounding? */
- divn = 1624000000u * divr / (ref_freq_Hz * 2u * divp);
+ divn = 1624000000u * divr / (ref_freq_hz * 2u * divp);
break;
}
/* adc_clk and sys_clk depend on xtal and pll settings */
- state->fvco_hz = ref_freq_Hz / divr
+ state->fvco_hz = ref_freq_hz / divr
* 2u * divn * divp;
state->adc_clk = state->fvco_hz / (divm * 4u);
state->sys_clk = state->fvco_hz / (divl * 2u);
- /* write pll registers 0x00a0..0x00a3 at once */
+ /* write all 4 pll registers 0x00a0..0x00a3 at once */
buf[0] = divl;
buf[1] = divm;
buf[2] = (divn & 0x3f) | ((divp == 1) ? 0x40 : 0x00) | 0x80;
buf[3] = divr;
- return si2165_write(state, 0x00a0, buf, 4);
+ return si2165_write(state, REG_PLL_DIVL, buf, 4);
}
static int si2165_adjust_pll_divl(struct si2165_state *state, u8 divl)
{
state->sys_clk = state->fvco_hz / (divl * 2u);
- return si2165_writereg8(state, 0x00a0, divl); /* pll_divl */
+ return si2165_writereg8(state, REG_PLL_DIVL, divl);
}
static u32 si2165_get_fe_clk(struct si2165_state *state)
@@ -309,18 +280,18 @@ static int si2165_wait_init_done(struct si2165_state *state)
int i;
for (i = 0; i < 3; ++i) {
- si2165_readreg8(state, 0x0054, &val);
+ si2165_readreg8(state, REG_INIT_DONE, &val);
if (val == 0x01)
return 0;
usleep_range(1000, 50000);
}
- dev_err(&state->client->dev, "%s: init_done was not set\n",
- KBUILD_MODNAME);
+ dev_err(&state->client->dev, "init_done was not set\n");
return ret;
}
static int si2165_upload_firmware_block(struct si2165_state *state,
- const u8 *data, u32 len, u32 *poffset, u32 block_count)
+ const u8 *data, u32 len, u32 *poffset,
+ u32 block_count)
{
int ret;
u8 buf_ctrl[4] = { 0x00, 0x00, 0x00, 0xc0 };
@@ -333,42 +304,43 @@ static int si2165_upload_firmware_block(struct si2165_state *state,
if (len % 4 != 0)
return -EINVAL;
- deb_fw_load(
- "si2165_upload_firmware_block called with len=0x%x offset=0x%x blockcount=0x%x\n",
- len, offset, block_count);
- while (offset+12 <= len && cur_block < block_count) {
- deb_fw_load(
- "si2165_upload_firmware_block in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
- len, offset, cur_block, block_count);
+ dev_dbg(&state->client->dev,
+ "fw load: %s: called with len=0x%x offset=0x%x blockcount=0x%x\n",
+ __func__, len, offset, block_count);
+ while (offset + 12 <= len && cur_block < block_count) {
+ dev_dbg(&state->client->dev,
+ "fw load: %s: in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
+ __func__, len, offset, cur_block, block_count);
wordcount = data[offset];
- if (wordcount < 1 || data[offset+1] ||
- data[offset+2] || data[offset+3]) {
+ if (wordcount < 1 || data[offset + 1] ||
+ data[offset + 2] || data[offset + 3]) {
dev_warn(&state->client->dev,
- "%s: bad fw data[0..3] = %*ph\n",
- KBUILD_MODNAME, 4, data);
+ "bad fw data[0..3] = %*ph\n",
+ 4, data);
return -EINVAL;
}
if (offset + 8 + wordcount * 4 > len) {
dev_warn(&state->client->dev,
- "%s: len is too small for block len=%d, wordcount=%d\n",
- KBUILD_MODNAME, len, wordcount);
+ "len is too small for block len=%d, wordcount=%d\n",
+ len, wordcount);
return -EINVAL;
}
buf_ctrl[0] = wordcount - 1;
- ret = si2165_write(state, 0x0364, buf_ctrl, 4);
+ ret = si2165_write(state, REG_DCOM_CONTROL_BYTE, buf_ctrl, 4);
if (ret < 0)
goto error;
- ret = si2165_write(state, 0x0368, data+offset+4, 4);
+ ret = si2165_write(state, REG_DCOM_ADDR, data + offset + 4, 4);
if (ret < 0)
goto error;
offset += 8;
while (wordcount > 0) {
- ret = si2165_write(state, 0x36c, data+offset, 4);
+ ret = si2165_write(state, REG_DCOM_DATA,
+ data + offset, 4);
if (ret < 0)
goto error;
wordcount--;
@@ -377,15 +349,16 @@ static int si2165_upload_firmware_block(struct si2165_state *state,
cur_block++;
}
- deb_fw_load(
- "si2165_upload_firmware_block after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
- len, offset, cur_block, block_count);
+ dev_dbg(&state->client->dev,
+ "fw load: %s: after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
+ __func__, len, offset, cur_block, block_count);
if (poffset)
*poffset = offset;
- deb_fw_load("si2165_upload_firmware_block returned offset=0x%x\n",
- offset);
+ dev_dbg(&state->client->dev,
+ "fw load: %s: returned offset=0x%x\n",
+ __func__, offset);
return 0;
error:
@@ -413,43 +386,40 @@ static int si2165_upload_firmware(struct si2165_state *state)
fw_file = SI2165_FIRMWARE_REV_D;
break;
default:
- dev_info(&state->client->dev, "%s: no firmware file for revision=%d\n",
- KBUILD_MODNAME, state->chip_revcode);
+ dev_info(&state->client->dev, "no firmware file for revision=%d\n",
+ state->chip_revcode);
return 0;
}
/* request the firmware, this will block and timeout */
ret = request_firmware(&fw, fw_file, &state->client->dev);
if (ret) {
- dev_warn(&state->client->dev, "%s: firmware file '%s' not found\n",
- KBUILD_MODNAME, fw_file);
+ dev_warn(&state->client->dev, "firmware file '%s' not found\n",
+ fw_file);
goto error;
}
data = fw->data;
len = fw->size;
- dev_info(&state->client->dev, "%s: downloading firmware from file '%s' size=%d\n",
- KBUILD_MODNAME, fw_file, len);
+ dev_info(&state->client->dev, "downloading firmware from file '%s' size=%d\n",
+ fw_file, len);
if (len % 4 != 0) {
- dev_warn(&state->client->dev, "%s: firmware size is not multiple of 4\n",
- KBUILD_MODNAME);
+ dev_warn(&state->client->dev, "firmware size is not multiple of 4\n");
ret = -EINVAL;
goto error;
}
/* check header (8 bytes) */
if (len < 8) {
- dev_warn(&state->client->dev, "%s: firmware header is missing\n",
- KBUILD_MODNAME);
+ dev_warn(&state->client->dev, "firmware header is missing\n");
ret = -EINVAL;
goto error;
}
if (data[0] != 1 || data[1] != 0) {
- dev_warn(&state->client->dev, "%s: firmware file version is wrong\n",
- KBUILD_MODNAME);
+ dev_warn(&state->client->dev, "firmware file version is wrong\n");
ret = -EINVAL;
goto error;
}
@@ -460,45 +430,45 @@ static int si2165_upload_firmware(struct si2165_state *state)
/* start uploading fw */
/* boot/wdog status */
- ret = si2165_writereg8(state, 0x0341, 0x00);
+ ret = si2165_writereg8(state, REG_WDOG_AND_BOOT, 0x00);
if (ret < 0)
goto error;
/* reset */
- ret = si2165_writereg8(state, 0x00c0, 0x00);
+ ret = si2165_writereg8(state, REG_RST_ALL, 0x00);
if (ret < 0)
goto error;
/* boot/wdog status */
- ret = si2165_readreg8(state, 0x0341, val);
+ ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, val);
if (ret < 0)
goto error;
/* enable reset on error */
- ret = si2165_readreg8(state, 0x035c, val);
+ ret = si2165_readreg8(state, REG_EN_RST_ERROR, val);
if (ret < 0)
goto error;
- ret = si2165_readreg8(state, 0x035c, val);
+ ret = si2165_readreg8(state, REG_EN_RST_ERROR, val);
if (ret < 0)
goto error;
- ret = si2165_writereg8(state, 0x035c, 0x02);
+ ret = si2165_writereg8(state, REG_EN_RST_ERROR, 0x02);
if (ret < 0)
goto error;
/* start right after the header */
offset = 8;
- dev_info(&state->client->dev, "%s: si2165_upload_firmware extracted patch_version=0x%02x, block_count=0x%02x, crc_expected=0x%04x\n",
- KBUILD_MODNAME, patch_version, block_count, crc_expected);
+ dev_info(&state->client->dev, "%s: extracted patch_version=0x%02x, block_count=0x%02x, crc_expected=0x%04x\n",
+ __func__, patch_version, block_count, crc_expected);
ret = si2165_upload_firmware_block(state, data, len, &offset, 1);
if (ret < 0)
goto error;
- ret = si2165_writereg8(state, 0x0344, patch_version);
+ ret = si2165_writereg8(state, REG_PATCH_VERSION, patch_version);
if (ret < 0)
goto error;
/* reset crc */
- ret = si2165_writereg8(state, 0x0379, 0x01);
+ ret = si2165_writereg8(state, REG_RST_CRC, 0x01);
if (ret)
goto error;
@@ -506,20 +476,19 @@ static int si2165_upload_firmware(struct si2165_state *state)
&offset, block_count);
if (ret < 0) {
dev_err(&state->client->dev,
- "%s: firmware could not be uploaded\n",
- KBUILD_MODNAME);
+ "firmware could not be uploaded\n");
goto error;
}
/* read crc */
- ret = si2165_readreg16(state, 0x037a, &val16);
+ ret = si2165_readreg16(state, REG_CRC, &val16);
if (ret)
goto error;
if (val16 != crc_expected) {
dev_err(&state->client->dev,
- "%s: firmware crc mismatch %04x != %04x\n",
- KBUILD_MODNAME, val16, crc_expected);
+ "firmware crc mismatch %04x != %04x\n",
+ val16, crc_expected);
ret = -EINVAL;
goto error;
}
@@ -530,23 +499,23 @@ static int si2165_upload_firmware(struct si2165_state *state)
if (len != offset) {
dev_err(&state->client->dev,
- "%s: firmware len mismatch %04x != %04x\n",
- KBUILD_MODNAME, len, offset);
+ "firmware len mismatch %04x != %04x\n",
+ len, offset);
ret = -EINVAL;
goto error;
}
/* reset watchdog error register */
- ret = si2165_writereg_mask8(state, 0x0341, 0x02, 0x02);
+ ret = si2165_writereg_mask8(state, REG_WDOG_AND_BOOT, 0x02, 0x02);
if (ret < 0)
goto error;
/* enable reset on error */
- ret = si2165_writereg_mask8(state, 0x035c, 0x01, 0x01);
+ ret = si2165_writereg_mask8(state, REG_EN_RST_ERROR, 0x01, 0x01);
if (ret < 0)
goto error;
- dev_info(&state->client->dev, "%s: fw load finished\n", KBUILD_MODNAME);
+ dev_info(&state->client->dev, "fw load finished\n");
ret = 0;
state->firmware_loaded = true;
@@ -563,46 +532,47 @@ static int si2165_init(struct dvb_frontend *fe)
{
int ret = 0;
struct si2165_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
u8 val;
u8 patch_version = 0x00;
- dprintk("%s: called\n", __func__);
+ dev_dbg(&state->client->dev, "%s: called\n", __func__);
/* powerup */
- ret = si2165_writereg8(state, 0x0000, state->config.chip_mode);
+ ret = si2165_writereg8(state, REG_CHIP_MODE, state->config.chip_mode);
if (ret < 0)
goto error;
/* dsp_clock_enable */
- ret = si2165_writereg8(state, 0x0104, 0x01);
+ ret = si2165_writereg8(state, REG_DSP_CLOCK, 0x01);
if (ret < 0)
goto error;
- ret = si2165_readreg8(state, 0x0000, &val); /* verify chip_mode */
+ /* verify chip_mode */
+ ret = si2165_readreg8(state, REG_CHIP_MODE, &val);
if (ret < 0)
goto error;
if (val != state->config.chip_mode) {
- dev_err(&state->client->dev, "%s: could not set chip_mode\n",
- KBUILD_MODNAME);
+ dev_err(&state->client->dev, "could not set chip_mode\n");
return -EINVAL;
}
/* agc */
- ret = si2165_writereg8(state, 0x018b, 0x00);
+ ret = si2165_writereg8(state, REG_AGC_IF_TRI, 0x00);
if (ret < 0)
goto error;
- ret = si2165_writereg8(state, 0x0190, 0x01);
+ ret = si2165_writereg8(state, REG_AGC_IF_SLR, 0x01);
if (ret < 0)
goto error;
- ret = si2165_writereg8(state, 0x0170, 0x00);
+ ret = si2165_writereg8(state, REG_AGC2_OUTPUT, 0x00);
if (ret < 0)
goto error;
- ret = si2165_writereg8(state, 0x0171, 0x07);
+ ret = si2165_writereg8(state, REG_AGC2_CLKDIV, 0x07);
if (ret < 0)
goto error;
/* rssi pad */
- ret = si2165_writereg8(state, 0x0646, 0x00);
+ ret = si2165_writereg8(state, REG_RSSI_PAD_CTRL, 0x00);
if (ret < 0)
goto error;
- ret = si2165_writereg8(state, 0x0641, 0x00);
+ ret = si2165_writereg8(state, REG_RSSI_ENABLE, 0x00);
if (ret < 0)
goto error;
@@ -611,11 +581,11 @@ static int si2165_init(struct dvb_frontend *fe)
goto error;
/* enable chip_init */
- ret = si2165_writereg8(state, 0x0050, 0x01);
+ ret = si2165_writereg8(state, REG_CHIP_INIT, 0x01);
if (ret < 0)
goto error;
/* set start_init */
- ret = si2165_writereg8(state, 0x0096, 0x01);
+ ret = si2165_writereg8(state, REG_START_INIT, 0x01);
if (ret < 0)
goto error;
ret = si2165_wait_init_done(state);
@@ -623,29 +593,30 @@ static int si2165_init(struct dvb_frontend *fe)
goto error;
/* disable chip_init */
- ret = si2165_writereg8(state, 0x0050, 0x00);
+ ret = si2165_writereg8(state, REG_CHIP_INIT, 0x00);
if (ret < 0)
goto error;
- /* ber_pkt */
- ret = si2165_writereg16(state, 0x0470, 0x7530);
+ /* ber_pkt - default 65535 */
+ ret = si2165_writereg16(state, REG_BER_PKT,
+ STATISTICS_PERIOD_PKT_COUNT);
if (ret < 0)
goto error;
- ret = si2165_readreg8(state, 0x0344, &patch_version);
+ ret = si2165_readreg8(state, REG_PATCH_VERSION, &patch_version);
if (ret < 0)
goto error;
- ret = si2165_writereg8(state, 0x00cb, 0x00);
+ ret = si2165_writereg8(state, REG_AUTO_RESET, 0x00);
if (ret < 0)
goto error;
/* dsp_addr_jump */
- ret = si2165_writereg32(state, 0x0348, 0xf4000000);
+ ret = si2165_writereg32(state, REG_ADDR_JUMP, 0xf4000000);
if (ret < 0)
goto error;
/* boot/wdog status */
- ret = si2165_readreg8(state, 0x0341, &val);
+ ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, &val);
if (ret < 0)
goto error;
@@ -656,19 +627,30 @@ static int si2165_init(struct dvb_frontend *fe)
}
/* ts output config */
- ret = si2165_writereg8(state, 0x04e4, 0x20);
+ ret = si2165_writereg8(state, REG_TS_DATA_MODE, 0x20);
+ if (ret < 0)
+ return ret;
+ ret = si2165_writereg16(state, REG_TS_TRI, 0x00fe);
if (ret < 0)
return ret;
- ret = si2165_writereg16(state, 0x04ef, 0x00fe);
+ ret = si2165_writereg24(state, REG_TS_SLR, 0x555555);
if (ret < 0)
return ret;
- ret = si2165_writereg24(state, 0x04f4, 0x555555);
+ ret = si2165_writereg8(state, REG_TS_CLK_MODE, 0x01);
if (ret < 0)
return ret;
- ret = si2165_writereg8(state, 0x04e5, 0x01);
+ ret = si2165_writereg8(state, REG_TS_PARALLEL_MODE, 0x00);
if (ret < 0)
return ret;
+ c = &state->fe.dtv_property_cache;
+ c->cnr.len = 1;
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_error.len = 1;
+ c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.len = 1;
+ c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
return 0;
error:
return ret;
@@ -680,11 +662,11 @@ static int si2165_sleep(struct dvb_frontend *fe)
struct si2165_state *state = fe->demodulator_priv;
/* dsp clock disable */
- ret = si2165_writereg8(state, 0x0104, 0x00);
+ ret = si2165_writereg8(state, REG_DSP_CLOCK, 0x00);
if (ret < 0)
return ret;
/* chip mode */
- ret = si2165_writereg8(state, 0x0000, SI2165_MODE_OFF);
+ ret = si2165_writereg8(state, REG_CHIP_MODE, SI2165_MODE_OFF);
if (ret < 0)
return ret;
return 0;
@@ -693,18 +675,48 @@ static int si2165_sleep(struct dvb_frontend *fe)
static int si2165_read_status(struct dvb_frontend *fe, enum fe_status *status)
{
int ret;
- u8 fec_lock = 0;
+ u8 u8tmp;
+ u32 u32tmp;
struct si2165_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u32 delsys = c->delivery_system;
- if (!state->has_dvbt)
- return -EINVAL;
+ *status = 0;
+
+ switch (delsys) {
+ case SYS_DVBT:
+ /* check fast signal type */
+ ret = si2165_readreg8(state, REG_CHECK_SIGNAL, &u8tmp);
+ if (ret < 0)
+ return ret;
+ switch (u8tmp & 0x3) {
+ case 0: /* searching */
+ case 1: /* nothing */
+ break;
+ case 2: /* digital signal */
+ *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+ break;
+ }
+ break;
+ case SYS_DVBC_ANNEX_A:
+ /* check packet sync lock */
+ ret = si2165_readreg8(state, REG_PS_LOCK, &u8tmp);
+ if (ret < 0)
+ return ret;
+ if (u8tmp & 0x01) {
+ *status |= FE_HAS_SIGNAL;
+ *status |= FE_HAS_CARRIER;
+ *status |= FE_HAS_VITERBI;
+ *status |= FE_HAS_SYNC;
+ }
+ break;
+ }
/* check fec_lock */
- ret = si2165_readreg8(state, 0x4e0, &fec_lock);
+ ret = si2165_readreg8(state, REG_FEC_LOCK, &u8tmp);
if (ret < 0)
return ret;
- *status = 0;
- if (fec_lock & 0x01) {
+ if (u8tmp & 0x01) {
*status |= FE_HAS_SIGNAL;
*status |= FE_HAS_CARRIER;
*status |= FE_HAS_VITERBI;
@@ -712,6 +724,109 @@ static int si2165_read_status(struct dvb_frontend *fe, enum fe_status *status)
*status |= FE_HAS_LOCK;
}
+ /* CNR */
+ if (delsys == SYS_DVBC_ANNEX_A && *status & FE_HAS_VITERBI) {
+ ret = si2165_readreg24(state, REG_C_N, &u32tmp);
+ if (ret < 0)
+ return ret;
+ /*
+ * svalue =
+ * 1000 * c_n/dB =
+ * 1000 * 10 * log10(2^24 / regval) =
+ * 1000 * 10 * (log10(2^24) - log10(regval)) =
+ * 1000 * 10 * (intlog10(2^24) - intlog10(regval)) / 2^24
+ *
+ * intlog10(x) = log10(x) * 2^24
+ * intlog10(2^24) = log10(2^24) * 2^24 = 121210686
+ */
+ u32tmp = (1000 * 10 * (121210686 - (u64)intlog10(u32tmp)))
+ >> 24;
+ c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+ c->cnr.stat[0].svalue = u32tmp;
+ } else
+ c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+ /* BER */
+ if (*status & FE_HAS_VITERBI) {
+ if (c->post_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
+ /* start new sampling period to get rid of old data*/
+ ret = si2165_writereg8(state, REG_BER_RST, 0x01);
+ if (ret < 0)
+ return ret;
+
+ /* set scale to enter read code on next call */
+ c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+ c->post_bit_error.stat[0].uvalue = 0;
+ c->post_bit_count.stat[0].uvalue = 0;
+
+ /*
+ * reset DVBv3 value to deliver a good result
+ * for the first call
+ */
+ state->ber_prev = 0;
+
+ } else {
+ ret = si2165_readreg8(state, REG_BER_AVAIL, &u8tmp);
+ if (ret < 0)
+ return ret;
+
+ if (u8tmp & 1) {
+ u32 biterrcnt;
+
+ ret = si2165_readreg24(state, REG_BER_BIT,
+ &biterrcnt);
+ if (ret < 0)
+ return ret;
+
+ c->post_bit_error.stat[0].uvalue +=
+ biterrcnt;
+ c->post_bit_count.stat[0].uvalue +=
+ STATISTICS_PERIOD_BIT_COUNT;
+
+ /* start new sampling period */
+ ret = si2165_writereg8(state,
+ REG_BER_RST, 0x01);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(&state->client->dev,
+ "post_bit_error=%u post_bit_count=%u\n",
+ biterrcnt, STATISTICS_PERIOD_BIT_COUNT);
+ }
+ }
+ } else {
+ c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+ }
+
+ return 0;
+}
+
+static int si2165_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
+ *snr = div_s64(c->cnr.stat[0].svalue, 100);
+ else
+ *snr = 0;
+ return 0;
+}
+
+static int si2165_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct si2165_state *state = fe->demodulator_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ if (c->post_bit_error.stat[0].scale != FE_SCALE_COUNTER) {
+ *ber = 0;
+ return 0;
+ }
+
+ *ber = c->post_bit_error.stat[0].uvalue - state->ber_prev;
+ state->ber_prev = c->post_bit_error.stat[0].uvalue;
+
return 0;
}
@@ -728,8 +843,8 @@ static int si2165_set_oversamp(struct si2165_state *state, u32 dvb_rate)
do_div(oversamp, dvb_rate);
reg_value = oversamp & 0x3fffffff;
- dprintk("%s: Write oversamp=%#x\n", __func__, reg_value);
- return si2165_writereg32(state, 0x00e4, reg_value);
+ dev_dbg(&state->client->dev, "Write oversamp=%#x\n", reg_value);
+ return si2165_writereg32(state, REG_OVERSAMP, reg_value);
}
static int si2165_set_if_freq_shift(struct si2165_state *state)
@@ -742,8 +857,7 @@ static int si2165_set_if_freq_shift(struct si2165_state *state)
if (!fe->ops.tuner_ops.get_if_frequency) {
dev_err(&state->client->dev,
- "%s: Error: get_if_frequency() not defined at tuner. Can't work without it!\n",
- KBUILD_MODNAME);
+ "Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
return -EINVAL;
}
@@ -763,30 +877,29 @@ static int si2165_set_if_freq_shift(struct si2165_state *state)
reg_value = reg_value & 0x1fffffff;
/* if_freq_shift, usbdump contained 0x023ee08f; */
- return si2165_writereg32(state, 0x00e8, reg_value);
+ return si2165_writereg32(state, REG_IF_FREQ_SHIFT, reg_value);
}
static const struct si2165_reg_value_pair dvbt_regs[] = {
/* standard = DVB-T */
- { 0x00ec, 0x01 },
- { 0x08f8, 0x00 },
+ { REG_DVB_STANDARD, 0x01 },
/* impulsive_noise_remover */
- { 0x031c, 0x01 },
- { 0x00cb, 0x00 },
+ { REG_IMPULSIVE_NOISE_REM, 0x01 },
+ { REG_AUTO_RESET, 0x00 },
/* agc2 */
- { 0x016e, 0x41 },
- { 0x016c, 0x0e },
- { 0x016d, 0x10 },
+ { REG_AGC2_MIN, 0x41 },
+ { REG_AGC2_KACQ, 0x0e },
+ { REG_AGC2_KLOC, 0x10 },
/* agc */
- { 0x015b, 0x03 },
- { 0x0150, 0x78 },
+ { REG_AGC_UNFREEZE_THR, 0x03 },
+ { REG_AGC_CRESTF_DBX8, 0x78 },
/* agc */
- { 0x01a0, 0x78 },
- { 0x01c8, 0x68 },
+ { REG_AAF_CRESTF_DBX8, 0x78 },
+ { REG_ACI_CRESTF_DBX8, 0x68 },
/* freq_sync_range */
- REG16(0x030c, 0x0064),
+ REG16(REG_FREQ_SYNC_RANGE, 0x0064),
/* gp_reg0 */
- { 0x0387, 0x00 }
+ { REG_GP_REG0_MSB, 0x00 }
};
static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
@@ -798,7 +911,7 @@ static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
u16 bw10k;
u32 bw_hz = p->bandwidth_hz;
- dprintk("%s: called\n", __func__);
+ dev_dbg(&state->client->dev, "%s: called\n", __func__);
if (!state->has_dvbt)
return -EINVAL;
@@ -815,7 +928,7 @@ static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
return ret;
/* bandwidth in 10KHz steps */
- ret = si2165_writereg16(state, 0x0308, bw10k);
+ ret = si2165_writereg16(state, REG_T_BANDWIDTH, bw10k);
if (ret < 0)
return ret;
ret = si2165_set_oversamp(state, dvb_rate);
@@ -831,33 +944,30 @@ static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
static const struct si2165_reg_value_pair dvbc_regs[] = {
/* standard = DVB-C */
- { 0x00ec, 0x05 },
- { 0x08f8, 0x00 },
+ { REG_DVB_STANDARD, 0x05 },
/* agc2 */
- { 0x016e, 0x50 },
- { 0x016c, 0x0e },
- { 0x016d, 0x10 },
+ { REG_AGC2_MIN, 0x50 },
+ { REG_AGC2_KACQ, 0x0e },
+ { REG_AGC2_KLOC, 0x10 },
/* agc */
- { 0x015b, 0x03 },
- { 0x0150, 0x68 },
+ { REG_AGC_UNFREEZE_THR, 0x03 },
+ { REG_AGC_CRESTF_DBX8, 0x68 },
/* agc */
- { 0x01a0, 0x68 },
- { 0x01c8, 0x50 },
-
- { 0x0278, 0x0d },
-
- { 0x023a, 0x05 },
- { 0x0261, 0x09 },
- REG16(0x0350, 0x3e80),
- { 0x02f4, 0x00 },
-
- { 0x00cb, 0x01 },
- REG16(0x024c, 0x0000),
- REG16(0x027c, 0x0000),
- { 0x0232, 0x03 },
- { 0x02f4, 0x0b },
- { 0x018b, 0x00 },
+ { REG_AAF_CRESTF_DBX8, 0x68 },
+ { REG_ACI_CRESTF_DBX8, 0x50 },
+
+ { REG_EQ_AUTO_CONTROL, 0x0d },
+
+ { REG_KP_LOCK, 0x05 },
+ { REG_CENTRAL_TAP, 0x09 },
+ REG16(REG_UNKNOWN_350, 0x3e80),
+
+ { REG_AUTO_RESET, 0x01 },
+ REG16(REG_UNKNOWN_24C, 0x0000),
+ REG16(REG_UNKNOWN_27C, 0x0000),
+ { REG_SWEEP_STEP, 0x03 },
+ { REG_AGC_IF_TRI, 0x00 },
};
static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
@@ -866,7 +976,7 @@ static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
int ret;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
const u32 dvb_rate = p->symbol_rate;
- const u32 bw_hz = p->bandwidth_hz;
+ u8 u8tmp;
if (!state->has_dvbc)
return -EINVAL;
@@ -883,7 +993,32 @@ static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
if (ret < 0)
return ret;
- ret = si2165_writereg32(state, 0x00c4, bw_hz);
+ switch (p->modulation) {
+ case QPSK:
+ u8tmp = 0x3;
+ break;
+ case QAM_16:
+ u8tmp = 0x7;
+ break;
+ case QAM_32:
+ u8tmp = 0x8;
+ break;
+ case QAM_64:
+ u8tmp = 0x9;
+ break;
+ case QAM_128:
+ u8tmp = 0xa;
+ break;
+ case QAM_256:
+ default:
+ u8tmp = 0xb;
+ break;
+ }
+ ret = si2165_writereg8(state, REG_REQ_CONSTELLATION, u8tmp);
+ if (ret < 0)
+ return ret;
+
+ ret = si2165_writereg32(state, REG_LOCK_TIMEOUT, 0x007a1200);
if (ret < 0)
return ret;
@@ -894,12 +1029,12 @@ static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
return 0;
}
-static const struct si2165_reg_value_pair agc_rewrite[] = {
- { 0x012a, 0x46 },
- { 0x012c, 0x00 },
- { 0x012e, 0x0a },
- { 0x012f, 0xff },
- { 0x0123, 0x70 }
+static const struct si2165_reg_value_pair adc_rewrite[] = {
+ { REG_ADC_RI1, 0x46 },
+ { REG_ADC_RI3, 0x00 },
+ { REG_ADC_RI5, 0x0a },
+ { REG_ADC_RI6, 0xff },
+ { REG_ADC_RI8, 0x70 }
};
static int si2165_set_frontend(struct dvb_frontend *fe)
@@ -931,7 +1066,7 @@ static int si2165_set_frontend(struct dvb_frontend *fe)
}
/* dsp_addr_jump */
- ret = si2165_writereg32(state, 0x0348, 0xf4000000);
+ ret = si2165_writereg32(state, REG_ADDR_JUMP, 0xf4000000);
if (ret < 0)
return ret;
@@ -944,34 +1079,34 @@ static int si2165_set_frontend(struct dvb_frontend *fe)
return ret;
/* boot/wdog status */
- ret = si2165_readreg8(state, 0x0341, val);
+ ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, val);
if (ret < 0)
return ret;
- ret = si2165_writereg8(state, 0x0341, 0x00);
+ ret = si2165_writereg8(state, REG_WDOG_AND_BOOT, 0x00);
if (ret < 0)
return ret;
/* reset all */
- ret = si2165_writereg8(state, 0x00c0, 0x00);
+ ret = si2165_writereg8(state, REG_RST_ALL, 0x00);
if (ret < 0)
return ret;
/* gp_reg0 */
- ret = si2165_writereg32(state, 0x0384, 0x00000000);
+ ret = si2165_writereg32(state, REG_GP_REG0_LSB, 0x00000000);
if (ret < 0)
return ret;
/* write adc values after each reset*/
- ret = si2165_write_reg_list(state, agc_rewrite,
- ARRAY_SIZE(agc_rewrite));
+ ret = si2165_write_reg_list(state, adc_rewrite,
+ ARRAY_SIZE(adc_rewrite));
if (ret < 0)
return ret;
/* start_synchro */
- ret = si2165_writereg8(state, 0x02e0, 0x01);
+ ret = si2165_writereg8(state, REG_START_SYNCHRO, 0x01);
if (ret < 0)
return ret;
/* boot/wdog status */
- ret = si2165_readreg8(state, 0x0341, val);
+ ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, val);
if (ret < 0)
return ret;
@@ -998,7 +1133,6 @@ static const struct dvb_frontend_ops si2165_ops = {
FE_CAN_QAM_64 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
- FE_CAN_QAM_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO |
FE_CAN_MUTE_TS |
@@ -1013,10 +1147,12 @@ static const struct dvb_frontend_ops si2165_ops = {
.set_frontend = si2165_set_frontend,
.read_status = si2165_read_status,
+ .read_snr = si2165_read_snr,
+ .read_ber = si2165_read_ber,
};
static int si2165_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct si2165_state *state = NULL;
struct si2165_platform_data *pdata = client->dev.platform_data;
@@ -1032,8 +1168,8 @@ static int si2165_probe(struct i2c_client *client,
};
/* allocate memory for the internal state */
- state = kzalloc(sizeof(struct si2165_state), GFP_KERNEL);
- if (state == NULL) {
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (!state) {
ret = -ENOMEM;
goto error;
}
@@ -1049,45 +1185,45 @@ static int si2165_probe(struct i2c_client *client,
state->client = client;
state->config.i2c_addr = client->addr;
state->config.chip_mode = pdata->chip_mode;
- state->config.ref_freq_Hz = pdata->ref_freq_Hz;
+ state->config.ref_freq_hz = pdata->ref_freq_hz;
state->config.inversion = pdata->inversion;
- if (state->config.ref_freq_Hz < 4000000
- || state->config.ref_freq_Hz > 27000000) {
- dev_err(&state->client->dev, "%s: ref_freq of %d Hz not supported by this driver\n",
- KBUILD_MODNAME, state->config.ref_freq_Hz);
+ if (state->config.ref_freq_hz < 4000000 ||
+ state->config.ref_freq_hz > 27000000) {
+ dev_err(&state->client->dev, "ref_freq of %d Hz not supported by this driver\n",
+ state->config.ref_freq_hz);
ret = -EINVAL;
goto error;
}
/* create dvb_frontend */
memcpy(&state->fe.ops, &si2165_ops,
- sizeof(struct dvb_frontend_ops));
+ sizeof(struct dvb_frontend_ops));
state->fe.ops.release = NULL;
state->fe.demodulator_priv = state;
i2c_set_clientdata(client, state);
/* powerup */
- ret = si2165_writereg8(state, 0x0000, state->config.chip_mode);
+ ret = si2165_writereg8(state, REG_CHIP_MODE, state->config.chip_mode);
if (ret < 0)
goto nodev_error;
- ret = si2165_readreg8(state, 0x0000, &val);
+ ret = si2165_readreg8(state, REG_CHIP_MODE, &val);
if (ret < 0)
goto nodev_error;
if (val != state->config.chip_mode)
goto nodev_error;
- ret = si2165_readreg8(state, 0x0023, &state->chip_revcode);
+ ret = si2165_readreg8(state, REG_CHIP_REVCODE, &state->chip_revcode);
if (ret < 0)
goto nodev_error;
- ret = si2165_readreg8(state, 0x0118, &state->chip_type);
+ ret = si2165_readreg8(state, REV_CHIP_TYPE, &state->chip_type);
if (ret < 0)
goto nodev_error;
/* powerdown */
- ret = si2165_writereg8(state, 0x0000, SI2165_MODE_OFF);
+ ret = si2165_writereg8(state, REG_CHIP_MODE, SI2165_MODE_OFF);
if (ret < 0)
goto nodev_error;
@@ -1107,18 +1243,18 @@ static int si2165_probe(struct i2c_client *client,
state->has_dvbc = true;
break;
default:
- dev_err(&state->client->dev, "%s: Unsupported Silicon Labs chip (type %d, rev %d)\n",
- KBUILD_MODNAME, state->chip_type, state->chip_revcode);
+ dev_err(&state->client->dev, "Unsupported Silicon Labs chip (type %d, rev %d)\n",
+ state->chip_type, state->chip_revcode);
goto nodev_error;
}
dev_info(&state->client->dev,
- "%s: Detected Silicon Labs %s-%c (type %d, rev %d)\n",
- KBUILD_MODNAME, chip_name, rev_char, state->chip_type,
+ "Detected Silicon Labs %s-%c (type %d, rev %d)\n",
+ chip_name, rev_char, state->chip_type,
state->chip_revcode);
strlcat(state->fe.ops.info.name, chip_name,
- sizeof(state->fe.ops.info.name));
+ sizeof(state->fe.ops.info.name));
n = 0;
if (state->has_dvbt) {
@@ -1173,9 +1309,6 @@ static struct i2c_driver si2165_driver = {
module_i2c_driver(si2165_driver);
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
MODULE_DESCRIPTION("Silicon Labs Si2165 DVB-C/-T Demodulator driver");
MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb-frontends/si2165.h b/drivers/media/dvb-frontends/si2165.h
index 76c2ca7d7edb..74a57b7ecd26 100644
--- a/drivers/media/dvb-frontends/si2165.h
+++ b/drivers/media/dvb-frontends/si2165.h
@@ -1,21 +1,22 @@
/*
- Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
-
- Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.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.
-
- References:
- http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
-*/
+ * Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
+ *
+ * Copyright (C) 2013-2017 Matthias Schwarzott <zzam@gentoo.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.
+ *
+ * References:
+ * http://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
+ *
+ */
#ifndef _DVB_SI2165_H
#define _DVB_SI2165_H
@@ -44,7 +45,7 @@ struct si2165_platform_data {
/* frequency of external clock or xtal in Hz
* possible values: 4000000, 16000000, 20000000, 240000000, 27000000
*/
- u32 ref_freq_Hz;
+ u32 ref_freq_hz;
/* invert the spectrum */
bool inversion;
diff --git a/drivers/media/dvb-frontends/si2165_priv.h b/drivers/media/dvb-frontends/si2165_priv.h
index e5932118834b..8c6fbfe441ff 100644
--- a/drivers/media/dvb-frontends/si2165_priv.h
+++ b/drivers/media/dvb-frontends/si2165_priv.h
@@ -1,19 +1,19 @@
/*
- Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
-
- Copyright (C) 2013-2014 Matthias Schwarzott <zzam@gentoo.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.
-
-*/
+ * Driver for Silicon Labs SI2165 DVB-C/-T Demodulator
+ *
+ * Copyright (C) 2013-2017 Matthias Schwarzott <zzam@gentoo.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.
+ *
+ */
#ifndef _DVB_SI2165_PRIV
#define _DVB_SI2165_PRIV
@@ -22,7 +22,8 @@
struct si2165_config {
/* i2c addr
- * possible values: 0x64,0x65,0x66,0x67 */
+ * possible values: 0x64,0x65,0x66,0x67
+ */
u8 i2c_addr;
/* external clock or XTAL */
@@ -31,10 +32,89 @@ struct si2165_config {
/* frequency of external clock or xtal in Hz
* possible values: 4000000, 16000000, 20000000, 240000000, 27000000
*/
- u32 ref_freq_Hz;
+ u32 ref_freq_hz;
/* invert the spectrum */
bool inversion;
};
+#define STATISTICS_PERIOD_PKT_COUNT 30000u
+#define STATISTICS_PERIOD_BIT_COUNT (STATISTICS_PERIOD_PKT_COUNT * 204 * 8)
+
+#define REG_CHIP_MODE 0x0000
+#define REG_CHIP_REVCODE 0x0023
+#define REV_CHIP_TYPE 0x0118
+#define REG_CHIP_INIT 0x0050
+#define REG_INIT_DONE 0x0054
+#define REG_START_INIT 0x0096
+#define REG_PLL_DIVL 0x00a0
+#define REG_RST_ALL 0x00c0
+#define REG_LOCK_TIMEOUT 0x00c4
+#define REG_AUTO_RESET 0x00cb
+#define REG_OVERSAMP 0x00e4
+#define REG_IF_FREQ_SHIFT 0x00e8
+#define REG_DVB_STANDARD 0x00ec
+#define REG_DSP_CLOCK 0x0104
+#define REG_ADC_RI8 0x0123
+#define REG_ADC_RI1 0x012a
+#define REG_ADC_RI2 0x012b
+#define REG_ADC_RI3 0x012c
+#define REG_ADC_RI4 0x012d
+#define REG_ADC_RI5 0x012e
+#define REG_ADC_RI6 0x012f
+#define REG_AGC_CRESTF_DBX8 0x0150
+#define REG_AGC_UNFREEZE_THR 0x015b
+#define REG_AGC2_MIN 0x016e
+#define REG_AGC2_KACQ 0x016c
+#define REG_AGC2_KLOC 0x016d
+#define REG_AGC2_OUTPUT 0x0170
+#define REG_AGC2_CLKDIV 0x0171
+#define REG_AGC_IF_TRI 0x018b
+#define REG_AGC_IF_SLR 0x0190
+#define REG_AAF_CRESTF_DBX8 0x01a0
+#define REG_ACI_CRESTF_DBX8 0x01c8
+#define REG_SWEEP_STEP 0x0232
+#define REG_KP_LOCK 0x023a
+#define REG_UNKNOWN_24C 0x024c
+#define REG_CENTRAL_TAP 0x0261
+#define REG_C_N 0x026c
+#define REG_EQ_AUTO_CONTROL 0x0278
+#define REG_UNKNOWN_27C 0x027c
+#define REG_START_SYNCHRO 0x02e0
+#define REG_REQ_CONSTELLATION 0x02f4
+#define REG_T_BANDWIDTH 0x0308
+#define REG_FREQ_SYNC_RANGE 0x030c
+#define REG_IMPULSIVE_NOISE_REM 0x031c
+#define REG_WDOG_AND_BOOT 0x0341
+#define REG_PATCH_VERSION 0x0344
+#define REG_ADDR_JUMP 0x0348
+#define REG_UNKNOWN_350 0x0350
+#define REG_EN_RST_ERROR 0x035c
+#define REG_DCOM_CONTROL_BYTE 0x0364
+#define REG_DCOM_ADDR 0x0368
+#define REG_DCOM_DATA 0x036c
+#define REG_RST_CRC 0x0379
+#define REG_GP_REG0_LSB 0x0384
+#define REG_GP_REG0_MSB 0x0387
+#define REG_CRC 0x037a
+#define REG_CHECK_SIGNAL 0x03a8
+#define REG_CBER_RST 0x0424
+#define REG_CBER_BIT 0x0428
+#define REG_CBER_ERR 0x0430
+#define REG_CBER_AVAIL 0x0434
+#define REG_PS_LOCK 0x0440
+#define REG_UNCOR_CNT 0x0468
+#define REG_BER_RST 0x046c
+#define REG_BER_PKT 0x0470
+#define REG_BER_BIT 0x0478
+#define REG_BER_AVAIL 0x047c
+#define REG_FEC_LOCK 0x04e0
+#define REG_TS_DATA_MODE 0x04e4
+#define REG_TS_CLK_MODE 0x04e5
+#define REG_TS_TRI 0x04ef
+#define REG_TS_SLR 0x04f4
+#define REG_RSSI_ENABLE 0x0641
+#define REG_RSSI_PAD_CTRL 0x0646
+#define REG_TS_PARALLEL_MODE 0x08f8
+
#endif /* _DVB_SI2165_PRIV */
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 41d9c513b7e8..539399dac551 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -14,6 +14,8 @@
* GNU General Public License for more details.
*/
+#include <linux/delay.h>
+
#include "si2168_priv.h"
static const struct dvb_frontend_ops si2168_ops;
@@ -435,6 +437,7 @@ static int si2168_init(struct dvb_frontend *fe)
if (ret)
goto err;
+ udelay(100);
memcpy(cmd.args, "\x85", 1);
cmd.wlen = 1;
cmd.rlen = 1;
diff --git a/drivers/media/dvb-frontends/si2168_priv.h b/drivers/media/dvb-frontends/si2168_priv.h
index 737cf416fbb2..3c8746a20038 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -18,7 +18,7 @@
#define SI2168_PRIV_H
#include "si2168.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include <linux/firmware.h>
#include <linux/i2c-mux.h>
#include <linux/kernel.h>
diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c
index 4e8c3ac4303f..9b32a1b3205e 100644
--- a/drivers/media/dvb-frontends/si21xx.c
+++ b/drivers/media/dvb-frontends/si21xx.c
@@ -16,7 +16,7 @@
#include <linux/jiffies.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "si21xx.h"
#define REVISION_REG 0x00
diff --git a/drivers/media/dvb-frontends/si21xx.h b/drivers/media/dvb-frontends/si21xx.h
index 43d480bb6ea2..12fa1d579820 100644
--- a/drivers/media/dvb-frontends/si21xx.h
+++ b/drivers/media/dvb-frontends/si21xx.h
@@ -3,7 +3,7 @@
#define SI21XX_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct si21xx_config {
/* the demodulator's i2c address */
diff --git a/drivers/media/dvb-frontends/sp2.h b/drivers/media/dvb-frontends/sp2.h
index 3901cd74b3f7..1bf60b80566f 100644
--- a/drivers/media/dvb-frontends/sp2.h
+++ b/drivers/media/dvb-frontends/sp2.h
@@ -17,7 +17,7 @@
#ifndef SP2_H
#define SP2_H
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
/*
* I2C address
diff --git a/drivers/media/dvb-frontends/sp2_priv.h b/drivers/media/dvb-frontends/sp2_priv.h
index 37fef7bcd63f..c9ee53073ec0 100644
--- a/drivers/media/dvb-frontends/sp2_priv.h
+++ b/drivers/media/dvb-frontends/sp2_priv.h
@@ -18,7 +18,7 @@
#define SP2_PRIV_H
#include "sp2.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/* state struct */
struct sp2 {
diff --git a/drivers/media/dvb-frontends/sp8870.c b/drivers/media/dvb-frontends/sp8870.c
index 04454cb78467..9a726f3a4896 100644
--- a/drivers/media/dvb-frontends/sp8870.c
+++ b/drivers/media/dvb-frontends/sp8870.c
@@ -35,7 +35,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "sp8870.h"
diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c
index d2c402b52c6e..572a297811fe 100644
--- a/drivers/media/dvb-frontends/sp887x.c
+++ b/drivers/media/dvb-frontends/sp887x.c
@@ -17,7 +17,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "sp887x.h"
diff --git a/drivers/media/dvb-frontends/stb0899_algo.c b/drivers/media/dvb-frontends/stb0899_algo.c
index 3012f196e9bd..bd2defde7a77 100644
--- a/drivers/media/dvb-frontends/stb0899_algo.c
+++ b/drivers/media/dvb-frontends/stb0899_algo.c
@@ -925,8 +925,7 @@ static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state)
wn = (4 * zeta * zeta) + 1000000;
wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn; /*wn =wn 10^-8*/
- k_indirect = (wn * wn) / K;
- k_indirect = k_indirect; /*kindirect = kindirect 10^-6*/
+ k_indirect = (wn * wn) / K; /*kindirect = kindirect 10^-6*/
k_direct = (2 * wn * zeta) / K; /*kDirect = kDirect 10^-2*/
k_direct *= 100;
diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
index 02347598277a..3c654ae16e78 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.c
+++ b/drivers/media/dvb-frontends/stb0899_drv.c
@@ -27,7 +27,7 @@
#include <linux/string.h>
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "stb0899_drv.h"
#include "stb0899_priv.h"
@@ -539,7 +539,8 @@ int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data,
int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
{
- return stb0899_write_regs(state, reg, &data, 1);
+ u8 tmp = data;
+ return stb0899_write_regs(state, reg, &tmp, 1);
}
/*
@@ -1582,15 +1583,15 @@ static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe)
static const struct dvb_frontend_ops stb0899_ops = {
.delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
.info = {
- .name = "STB0899 Multistandard",
+ .name = "STB0899 Multistandard",
.frequency_min = 950000,
- .frequency_max = 2150000,
+ .frequency_max = 2150000,
.frequency_stepsize = 0,
.frequency_tolerance = 0,
- .symbol_rate_min = 5000000,
- .symbol_rate_max = 45000000,
+ .symbol_rate_min = 5000000,
+ .symbol_rate_max = 45000000,
- .caps = FE_CAN_INVERSION_AUTO |
+ .caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_AUTO |
FE_CAN_2G_MODULATION |
FE_CAN_QPSK
diff --git a/drivers/media/dvb-frontends/stb0899_drv.h b/drivers/media/dvb-frontends/stb0899_drv.h
index 0a72131a57db..f65f9a8266f8 100644
--- a/drivers/media/dvb-frontends/stb0899_drv.h
+++ b/drivers/media/dvb-frontends/stb0899_drv.h
@@ -25,7 +25,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#define STB0899_TSMODE_SERIAL 1
#define STB0899_CLKPOL_FALLING 2
@@ -82,7 +82,7 @@ enum stb0899_inversion {
* 1. POWER ON/OFF (index 0)
* 2. FE_HAS_LOCK/LOCK_LOSS (index 1)
*
- * @gpio = one of the above listed GPIO's
+ * @gpio = one of the above listed GPIO's
* @level = output state: pulled up or low
*/
struct stb0899_postproc {
diff --git a/drivers/media/dvb-frontends/stb0899_priv.h b/drivers/media/dvb-frontends/stb0899_priv.h
index 82395b912815..3285cd1ba60a 100644
--- a/drivers/media/dvb-frontends/stb0899_priv.h
+++ b/drivers/media/dvb-frontends/stb0899_priv.h
@@ -22,7 +22,7 @@
#ifndef __STB0899_PRIV_H
#define __STB0899_PRIV_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "stb0899_drv.h"
#define FE_ERROR 0
@@ -252,7 +252,7 @@ extern int stb0899_write_s2reg(struct stb0899_state *state,
extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable);
-#define STB0899_READ_S2REG(DEVICE, REG) (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
+#define STB0899_READ_S2REG(DEVICE, REG) (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG))
//#define STB0899_WRITE_S2REG(DEVICE, REG, DATA) (_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA))
/* stb0899_algo.c */
diff --git a/drivers/media/dvb-frontends/stb6000.h b/drivers/media/dvb-frontends/stb6000.h
index e94a3d5facf6..1adda72379ff 100644
--- a/drivers/media/dvb-frontends/stb6000.h
+++ b/drivers/media/dvb-frontends/stb6000.h
@@ -24,7 +24,7 @@
#define __DVB_STB6000_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#if IS_REACHABLE(CONFIG_DVB_STB6000)
/**
diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c
index 17a955d0031b..3a851f524b16 100644
--- a/drivers/media/dvb-frontends/stb6100.c
+++ b/drivers/media/dvb-frontends/stb6100.c
@@ -25,7 +25,7 @@
#include <linux/slab.h>
#include <linux/string.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "stb6100.h"
static unsigned int verbose;
@@ -226,12 +226,14 @@ static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int st
static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
{
+ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
if (unlikely(reg >= STB6100_NUMREGS)) {
dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
return -EREMOTEIO;
}
- data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set;
- return stb6100_write_reg_range(state, &data, reg, 1);
+ tmp = (tmp & stb6100_template[reg].mask) | stb6100_template[reg].set;
+ return stb6100_write_reg_range(state, &tmp, reg, 1);
}
diff --git a/drivers/media/dvb-frontends/stb6100.h b/drivers/media/dvb-frontends/stb6100.h
index f7b468b6dc26..6cdae688a23e 100644
--- a/drivers/media/dvb-frontends/stb6100.h
+++ b/drivers/media/dvb-frontends/stb6100.h
@@ -23,7 +23,7 @@
#define __STB_6100_REG_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#define STB6100_LD 0x00
#define STB6100_LD_LOCK (1 << 0)
diff --git a/drivers/media/dvb-frontends/stb6100_cfg.h b/drivers/media/dvb-frontends/stb6100_cfg.h
index 2ef67aa768b9..203f9b36c0eb 100644
--- a/drivers/media/dvb-frontends/stb6100_cfg.h
+++ b/drivers/media/dvb-frontends/stb6100_cfg.h
@@ -20,7 +20,7 @@
*/
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
{
diff --git a/drivers/media/dvb-frontends/stb6100_proc.h b/drivers/media/dvb-frontends/stb6100_proc.h
index 50ffa21e3871..fad877b2fc7d 100644
--- a/drivers/media/dvb-frontends/stb6100_proc.h
+++ b/drivers/media/dvb-frontends/stb6100_proc.h
@@ -18,7 +18,7 @@
*/
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
static int stb6100_get_freq(struct dvb_frontend *fe, u32 *frequency)
{
diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c
index 67f91814b9f7..f947ed947aae 100644
--- a/drivers/media/dvb-frontends/stv0288.c
+++ b/drivers/media/dvb-frontends/stv0288.c
@@ -33,7 +33,7 @@
#include <linux/jiffies.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "stv0288.h"
struct stv0288_state {
diff --git a/drivers/media/dvb-frontends/stv0288.h b/drivers/media/dvb-frontends/stv0288.h
index 803acb917282..c10227aaa62c 100644
--- a/drivers/media/dvb-frontends/stv0288.h
+++ b/drivers/media/dvb-frontends/stv0288.h
@@ -28,7 +28,7 @@
#define STV0288_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct stv0288_config {
/* the demodulator's i2c address */
diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c
index db94d4d109f9..b823c04e24d3 100644
--- a/drivers/media/dvb-frontends/stv0297.c
+++ b/drivers/media/dvb-frontends/stv0297.c
@@ -27,7 +27,7 @@
#include <linux/jiffies.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "stv0297.h"
struct stv0297_state {
diff --git a/drivers/media/dvb-frontends/stv0297.h b/drivers/media/dvb-frontends/stv0297.h
index b30632a67333..8fa5ac700fc3 100644
--- a/drivers/media/dvb-frontends/stv0297.h
+++ b/drivers/media/dvb-frontends/stv0297.h
@@ -22,7 +22,7 @@
#define STV0297_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct stv0297_config
{
diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c
index b1f3d675d316..633b90e6fe86 100644
--- a/drivers/media/dvb-frontends/stv0299.c
+++ b/drivers/media/dvb-frontends/stv0299.c
@@ -51,7 +51,7 @@
#include <linux/jiffies.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "stv0299.h"
struct stv0299_state {
diff --git a/drivers/media/dvb-frontends/stv0299.h b/drivers/media/dvb-frontends/stv0299.h
index 0aca30a8ec25..700c124a1699 100644
--- a/drivers/media/dvb-frontends/stv0299.h
+++ b/drivers/media/dvb-frontends/stv0299.h
@@ -46,7 +46,7 @@
#define STV0299_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#define STV0299_LOCKOUTPUT_0 0
#define STV0299_LOCKOUTPUT_1 1
diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
index f3529df8211d..5435c908e298 100644
--- a/drivers/media/dvb-frontends/stv0367.c
+++ b/drivers/media/dvb-frontends/stv0367.c
@@ -25,7 +25,7 @@
#include <linux/slab.h>
#include <linux/i2c.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
#include "stv0367.h"
#include "stv0367_defs.h"
@@ -166,7 +166,9 @@ int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
{
- return stv0367_writeregs(state, reg, &data, 1);
+ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+ return stv0367_writeregs(state, reg, &tmp, 1);
}
static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
@@ -1547,7 +1549,6 @@ static int stv0367ter_read_ber(struct dvb_frontend *fe, u32 *ber)
} else if (abc == 0x7) {
if (Errors <= 4) {
temporary = (Errors * 1000000000) / (8 * (1 << 14));
- temporary = temporary;
} else if (Errors <= 42) {
temporary = (Errors * 100000000) / (8 * (1 << 14));
temporary = temporary * 10;
@@ -1625,7 +1626,6 @@ static u32 stv0367ter_get_per(struct stv0367_state *state)
else if (abc == 0x9) {
if (Errors <= 4) {
temporary = (Errors * 1000000000) / (8 * (1 << 8));
- temporary = temporary;
} else if (Errors <= 42) {
temporary = (Errors * 100000000) / (8 * (1 << 8));
temporary = temporary * 10;
diff --git a/drivers/media/dvb-frontends/stv0367.h b/drivers/media/dvb-frontends/stv0367.h
index 8f7a31481744..14a50ecef6dd 100644
--- a/drivers/media/dvb-frontends/stv0367.h
+++ b/drivers/media/dvb-frontends/stv0367.h
@@ -23,7 +23,7 @@
#define STV0367_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#define STV0367_ICSPEED_53125 53125000
#define STV0367_ICSPEED_58000 58000000
diff --git a/drivers/media/dvb-frontends/stv0900.h b/drivers/media/dvb-frontends/stv0900.h
index 1571a465e05c..5dbe1e550fe5 100644
--- a/drivers/media/dvb-frontends/stv0900.h
+++ b/drivers/media/dvb-frontends/stv0900.h
@@ -23,7 +23,7 @@
#define STV0900_H
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct stv0900_reg {
u16 addr;
diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c
index 0b739725e3c0..72f17b97ca04 100644
--- a/drivers/media/dvb-frontends/stv0900_core.c
+++ b/drivers/media/dvb-frontends/stv0900_core.c
@@ -1929,7 +1929,7 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
switch (demod) {
case 0:
case 1:
- init_params.dmd_ref_clk = config->xtal;
+ init_params.dmd_ref_clk = config->xtal;
init_params.demod_mode = config->demod_mode;
init_params.rolloff = STV0900_35;
init_params.path1_ts_clock = config->path1_mode;
diff --git a/drivers/media/dvb-frontends/stv0900_init.h b/drivers/media/dvb-frontends/stv0900_init.h
index 411941442086..550ef4a0f654 100644
--- a/drivers/media/dvb-frontends/stv0900_init.h
+++ b/drivers/media/dvb-frontends/stv0900_init.h
@@ -148,8 +148,8 @@ struct stv0900_short_frames_car_loop_optim_vs_mod {
/* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
- /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
- 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
+ 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
{ STV0900_QPSK_12, 0x1C, 0x0D, 0x1B, 0x2C, 0x3A,
0x1C, 0x2A, 0x3B, 0x2A, 0x1B },
{ STV0900_QPSK_35, 0x2C, 0x0D, 0x2B, 0x2C, 0x3A,
@@ -176,15 +176,15 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
0x0B, 0x39, 0x1A, 0x19, 0x0A },
{ STV0900_8PSK_89, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A,
0x0B, 0x39, 0x1A, 0x29, 0x39 },
- { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A,
+ { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A,
0x0B, 0x39, 0x1A, 0x29, 0x39 }
};
/* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
- /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
- 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
+ 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
{ STV0900_QPSK_12, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D,
0x1F, 0x3D, 0x3E, 0x3D, 0x1E },
{ STV0900_QPSK_35, 0x2F, 0x3F, 0x2E, 0x2F, 0x3D,
@@ -211,7 +211,7 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
{ STV0900_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d,
0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
- { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d,
+ { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d,
0x1e, 0x1d, 0x2d, 0x0d, 0x1d },
};
@@ -219,8 +219,8 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
/* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
- /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
- 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
+ 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
{ STV0900_16APSK_23, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D,
0x0C, 0x3C, 0x0C, 0x2C, 0x0C },
{ STV0900_16APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E,
@@ -248,8 +248,8 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
/* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
- /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
- 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
+ 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
{ STV0900_QPSK_14, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D,
0x2F, 0x2D, 0x1F, 0x3D, 0x3E },
{ STV0900_QPSK_13, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D,
@@ -275,10 +275,10 @@ struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
};
static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = {
- /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
- 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
+ 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
{ STV0900_QPSK_12, 0x3C, 0x2C, 0x0C, 0x2C, 0x1B,
- 0x2C, 0x1B, 0x1C, 0x0B, 0x3B },
+ 0x2C, 0x1B, 0x1C, 0x0B, 0x3B },
{ STV0900_QPSK_35, 0x0D, 0x0D, 0x0C, 0x0D, 0x1B,
0x3C, 0x1B, 0x1C, 0x0B, 0x3B },
{ STV0900_QPSK_23, 0x1D, 0x0D, 0x0C, 0x1D, 0x2B,
@@ -309,8 +309,8 @@ static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut30[14] = {
static const
struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = {
- /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
- 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
+ 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
{ STV0900_16APSK_23, 0x0A, 0x0A, 0x0A, 0x0A, 0x1A,
0x0A, 0x3A, 0x0A, 0x2A, 0x0A },
{ STV0900_16APSK_34, 0x0A, 0x0A, 0x0A, 0x0A, 0x0B,
@@ -337,8 +337,8 @@ struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut30[11] = {
static const
struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut30[3] = {
- /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
- 10MPoff 20MPon 20MPoff 30MPon 30MPoff*/
+ /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon
+ 10MPoff 20MPon 20MPoff 30MPon 30MPoff*/
{ STV0900_QPSK_14, 0x0C, 0x3C, 0x0B, 0x3C, 0x2A,
0x2C, 0x2A, 0x1C, 0x3A, 0x3B },
{ STV0900_QPSK_13, 0x0C, 0x3C, 0x0B, 0x3C, 0x2A,
diff --git a/drivers/media/dvb-frontends/stv0900_priv.h b/drivers/media/dvb-frontends/stv0900_priv.h
index 7a95f955627b..d1fc06ff27d3 100644
--- a/drivers/media/dvb-frontends/stv0900_priv.h
+++ b/drivers/media/dvb-frontends/stv0900_priv.h
@@ -243,7 +243,7 @@ struct stv0900_init_params{
u8 tun1_maddress;
int tuner1_adc;
- int tuner1_type;
+ int tuner1_type;
/* IQ from the tuner1 to the demod */
enum stv0900_iq_inversion tun1_iq_inv;
diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
index 7ef469c0c866..9133f65d4623 100644
--- a/drivers/media/dvb-frontends/stv090x.c
+++ b/drivers/media/dvb-frontends/stv090x.c
@@ -27,7 +27,7 @@
#include <linux/mutex.h>
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "stv6110x.h" /* for demodulator internal modes */
@@ -677,7 +677,7 @@ static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut20[] = {
/* Cut 3.0 Short Frame Tracking CR Loop */
static struct stv090x_short_frame_crloop stv090x_s2_short_crl_cut30[] = {
- /* MODCOD 2M 5M 10M 20M 30M */
+ /* MODCOD 2M 5M 10M 20M 30M */
{ STV090x_QPSK, 0x2C, 0x2B, 0x0B, 0x0B, 0x3A },
{ STV090x_8PSK, 0x3B, 0x0B, 0x2A, 0x0A, 0x39 },
{ STV090x_16APSK, 0x1B, 0x1B, 0x1B, 0x3A, 0x2A },
@@ -701,7 +701,7 @@ static int stv090x_read_reg(struct stv090x_state *state, unsigned int reg)
u8 buf;
struct i2c_msg msg[] = {
- { .addr = config->address, .flags = 0, .buf = b0, .len = 2 },
+ { .addr = config->address, .flags = 0, .buf = b0, .len = 2 },
{ .addr = config->address, .flags = I2C_M_RD, .buf = &buf, .len = 1 }
};
@@ -755,7 +755,9 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8
static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
{
- return stv090x_write_regs(state, reg, &data, 1);
+ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+ return stv090x_write_regs(state, reg, &tmp, 1);
}
static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
@@ -2215,13 +2217,12 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
if (state->config->tuner_get_status) {
if (state->config->tuner_get_status(fe, &reg) < 0)
goto err_gateoff;
+ if (reg)
+ dprintk(FE_DEBUG, 1, "Tuner phase locked");
+ else
+ dprintk(FE_DEBUG, 1, "Tuner unlocked");
}
- if (reg)
- dprintk(FE_DEBUG, 1, "Tuner phase locked");
- else
- dprintk(FE_DEBUG, 1, "Tuner unlocked");
-
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
goto err;
@@ -3429,6 +3430,21 @@ err:
return -1;
}
+static int stv090x_set_pls(struct stv090x_state *state, u32 pls_code)
+{
+ dprintk(FE_DEBUG, 1, "Set Gold PLS code %d", pls_code);
+ if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code & 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, PLROOT1, (pls_code >> 8) & 0xff) < 0)
+ goto err;
+ if (STV090x_WRITE_DEMOD(state, PLROOT2, 0x04 | (pls_code >> 16)) < 0)
+ goto err;
+ return 0;
+err:
+ dprintk(FE_ERROR, 1, "I/O error");
+ return -1;
+}
+
static int stv090x_set_mis(struct stv090x_state *state, int mis)
{
u32 reg;
@@ -3491,6 +3507,7 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)
state->search_range = 5000000;
}
+ stv090x_set_pls(state, props->scrambling_sequence_index);
stv090x_set_mis(state, props->stream_id);
if (stv090x_algo(state) == STV090x_RANGEOK) {
@@ -4889,11 +4906,11 @@ static const struct dvb_frontend_ops stv090x_ops = {
.info = {
.name = "STV090x Multistandard",
.frequency_min = 950000,
- .frequency_max = 2150000,
+ .frequency_max = 2150000,
.frequency_stepsize = 0,
.frequency_tolerance = 0,
- .symbol_rate_min = 1000000,
- .symbol_rate_max = 45000000,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
.caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_AUTO |
FE_CAN_QPSK |
@@ -4936,7 +4953,7 @@ struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
state->frontend.ops = stv090x_ops;
state->frontend.demodulator_priv = state;
state->demod = demod;
- state->demod_mode = config->demod_mode; /* Single or Dual mode */
+ state->demod_mode = config->demod_mode; /* Single or Dual mode */
state->device = config->device;
state->rolloff = STV090x_RO_35; /* default */
diff --git a/drivers/media/dvb-frontends/stv090x_priv.h b/drivers/media/dvb-frontends/stv090x_priv.h
index 5b780c80d496..fdda2185db9d 100644
--- a/drivers/media/dvb-frontends/stv090x_priv.h
+++ b/drivers/media/dvb-frontends/stv090x_priv.h
@@ -22,7 +22,7 @@
#ifndef __STV090x_PRIV_H
#define __STV090x_PRIV_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#define FE_ERROR 0
#define FE_NOTICE 1
@@ -231,7 +231,7 @@ struct stv090x_tab {
};
struct stv090x_internal {
- struct i2c_adapter *i2c_adap;
+ struct i2c_adapter *i2c_adap;
u8 i2c_addr;
struct mutex demod_lock; /* Lock access to shared register */
diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c
index 8bf855c301f5..a2f7c0c1587f 100644
--- a/drivers/media/dvb-frontends/stv0910.c
+++ b/drivers/media/dvb-frontends/stv0910.c
@@ -24,8 +24,7 @@
#include <linux/i2c.h>
#include <asm/div64.h>
-#include "dvb_math.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "stv0910.h"
#include "stv0910_regs.h"
@@ -138,33 +137,21 @@ struct slookup {
u32 reg_value;
};
-static inline int i2c_write(struct i2c_adapter *adap, u8 adr,
- u8 *data, int len)
+static int write_reg(struct stv *state, u16 reg, u8 val)
{
- struct i2c_msg msg = {.addr = adr, .flags = 0,
- .buf = data, .len = len};
+ struct i2c_adapter *adap = state->base->i2c;
+ u8 data[3] = {reg >> 8, reg & 0xff, val};
+ struct i2c_msg msg = {.addr = state->base->adr, .flags = 0,
+ .buf = data, .len = 3};
if (i2c_transfer(adap, &msg, 1) != 1) {
dev_warn(&adap->dev, "i2c write error ([%02x] %04x: %02x)\n",
- adr, (data[0] << 8) | data[1],
- (len > 2 ? data[2] : 0));
- return -EREMOTEIO;
+ state->base->adr, reg, val);
+ return -EIO;
}
return 0;
}
-static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, u16 reg, u8 val)
-{
- u8 msg[3] = {reg >> 8, reg & 0xff, val};
-
- return i2c_write(adap, adr, msg, 3);
-}
-
-static int write_reg(struct stv *state, u16 reg, u8 val)
-{
- return i2c_write_reg16(state->base->i2c, state->base->adr, reg, val);
-}
-
static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr,
u16 reg, u8 *val, int count)
{
@@ -177,7 +164,7 @@ static inline int i2c_read_regs16(struct i2c_adapter *adapter, u8 adr,
if (i2c_transfer(adapter, msgs, 2) != 2) {
dev_warn(&adapter->dev, "i2c read error ([%02x] %04x)\n",
adr, reg);
- return -EREMOTEIO;
+ return -EIO;
}
return 0;
}
@@ -207,6 +194,34 @@ static int write_shared_reg(struct stv *state, u16 reg, u8 mask, u8 val)
return status;
}
+static int write_field(struct stv *state, u32 field, u8 val)
+{
+ int status;
+ u8 shift, mask, old, new;
+
+ status = read_reg(state, field >> 16, &old);
+ if (status)
+ return status;
+ mask = field & 0xff;
+ shift = (field >> 12) & 0xf;
+ new = ((val << shift) & mask) | (old & ~mask);
+ if (new == old)
+ return 0;
+ return write_reg(state, field >> 16, new);
+}
+
+#define SET_FIELD(_reg, _val) \
+ write_field(state, state->nr ? FSTV0910_P2_##_reg : \
+ FSTV0910_P1_##_reg, _val)
+
+#define SET_REG(_reg, _val) \
+ write_reg(state, state->nr ? RSTV0910_P2_##_reg : \
+ RSTV0910_P1_##_reg, _val)
+
+#define GET_REG(_reg, _val) \
+ read_reg(state, state->nr ? RSTV0910_P2_##_reg : \
+ RSTV0910_P1_##_reg, _val)
+
static const struct slookup s1_sn_lookup[] = {
{ 0, 9242 }, /* C/N= 0dB */
{ 5, 9105 }, /* C/N= 0.5dB */
@@ -533,10 +548,8 @@ static int get_signal_parameters(struct stv *state)
static int tracking_optimization(struct stv *state)
{
- u32 symbol_rate = 0;
u8 tmp;
- get_cur_symbol_rate(state, &symbol_rate);
read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, &tmp);
tmp &= ~0xC0;
@@ -867,71 +880,90 @@ static int stop(struct stv *state)
return 0;
}
-static int init_search_param(struct stv *state)
+static void set_pls(struct stv *state, u32 pls_code)
{
- u8 tmp;
-
- read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp);
- tmp |= 0x20; /* Filter_en (no effect if SIS=non-MIS */
- write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp);
-
- read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, &tmp);
- tmp &= ~0x02; /* frame mode = 0 */
- write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, tmp);
-
- write_reg(state, RSTV0910_P2_UPLCCST0 + state->regoff, 0xe0);
- write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0x00);
-
- read_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, &tmp);
- tmp &= ~0x01; /* nosync = 0, in case next signal is standard TS */
- write_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, tmp);
-
- read_reg(state, RSTV0910_P2_TSCFGL + state->regoff, &tmp);
- tmp &= ~0x04; /* embindvb = 0 */
- write_reg(state, RSTV0910_P2_TSCFGL + state->regoff, tmp);
-
- read_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, &tmp);
- tmp &= ~0x80; /* syncbyte = 0 */
- write_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, tmp);
-
- read_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, &tmp);
- tmp &= ~0x08; /* token = 0 */
- write_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, tmp);
+ if (pls_code == state->cur_scrambling_code)
+ return;
+
+ /* PLROOT2 bit 2 = gold code */
+ write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff,
+ pls_code & 0xff);
+ write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff,
+ (pls_code >> 8) & 0xff);
+ write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff,
+ 0x04 | ((pls_code >> 16) & 0x03));
+ state->cur_scrambling_code = pls_code;
+}
- read_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, &tmp);
- tmp &= ~0x30; /* hysteresis threshold = 0 */
- write_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, tmp);
+static void set_isi(struct stv *state, u32 isi)
+{
+ if (isi == NO_STREAM_ID_FILTER)
+ return;
+ if (isi == 0x80000000) {
+ SET_FIELD(FORCE_CONTINUOUS, 1);
+ SET_FIELD(TSOUT_NOSYNC, 1);
+ } else {
+ SET_FIELD(FILTER_EN, 1);
+ write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff,
+ isi & 0xff);
+ write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0xff);
+ }
+ SET_FIELD(ALGOSWRST, 1);
+ SET_FIELD(ALGOSWRST, 0);
+}
- read_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, &tmp);
- tmp = (tmp & ~0x30) | 0x10; /* isi obs mode = 1, observe min ISI */
- write_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, tmp);
+static void set_stream_modes(struct stv *state,
+ struct dtv_frontend_properties *p)
+{
+ set_isi(state, p->stream_id);
+ set_pls(state, p->scrambling_sequence_index);
+}
+static int init_search_param(struct stv *state,
+ struct dtv_frontend_properties *p)
+{
+ SET_FIELD(FORCE_CONTINUOUS, 0);
+ SET_FIELD(FRAME_MODE, 0);
+ SET_FIELD(FILTER_EN, 0);
+ SET_FIELD(TSOUT_NOSYNC, 0);
+ SET_FIELD(TSFIFO_EMBINDVB, 0);
+ SET_FIELD(TSDEL_SYNCBYTE, 0);
+ SET_REG(UPLCCST0, 0xe0);
+ SET_FIELD(TSINS_TOKEN, 0);
+ SET_FIELD(HYSTERESIS_THRESHOLD, 0);
+ SET_FIELD(ISIOBS_MODE, 1);
+
+ set_stream_modes(state, p);
return 0;
}
static int enable_puncture_rate(struct stv *state, enum fe_code_rate rate)
{
+ u8 val;
+
switch (rate) {
case FEC_1_2:
- return write_reg(state,
- RSTV0910_P2_PRVIT + state->regoff, 0x01);
+ val = 0x01;
+ break;
case FEC_2_3:
- return write_reg(state,
- RSTV0910_P2_PRVIT + state->regoff, 0x02);
+ val = 0x02;
+ break;
case FEC_3_4:
- return write_reg(state,
- RSTV0910_P2_PRVIT + state->regoff, 0x04);
+ val = 0x04;
+ break;
case FEC_5_6:
- return write_reg(state,
- RSTV0910_P2_PRVIT + state->regoff, 0x08);
+ val = 0x08;
+ break;
case FEC_7_8:
- return write_reg(state,
- RSTV0910_P2_PRVIT + state->regoff, 0x20);
+ val = 0x20;
+ break;
case FEC_NONE:
default:
- return write_reg(state,
- RSTV0910_P2_PRVIT + state->regoff, 0x2f);
+ val = 0x2f;
+ break;
}
+
+ return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, val);
}
static int set_vth_default(struct stv *state)
@@ -988,7 +1020,6 @@ static int start(struct stv *state, struct dtv_frontend_properties *p)
s32 freq;
u8 reg_dmdcfgmd;
u16 symb;
- u32 scrambling_code = 1;
if (p->symbol_rate < 100000 || p->symbol_rate > 70000000)
return -EINVAL;
@@ -1000,30 +1031,7 @@ static int start(struct stv *state, struct dtv_frontend_properties *p)
if (state->started)
write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5C);
- init_search_param(state);
-
- if (p->stream_id != NO_STREAM_ID_FILTER) {
- /*
- * Backwards compatibility to "crazy" API.
- * PRBS X root cannot be 0, so this should always work.
- */
- if (p->stream_id & 0xffffff00)
- scrambling_code = p->stream_id >> 8;
- write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff,
- p->stream_id & 0xff);
- write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff,
- 0xff);
- }
-
- if (scrambling_code != state->cur_scrambling_code) {
- write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff,
- scrambling_code & 0xff);
- write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff,
- (scrambling_code >> 8) & 0xff);
- write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff,
- (scrambling_code >> 16) & 0x0f);
- state->cur_scrambling_code = scrambling_code;
- }
+ init_search_param(state, p);
if (p->symbol_rate <= 1000000) { /* SR <=1Msps */
state->demod_timeout = 3000;
@@ -1241,7 +1249,8 @@ static int gate_ctrl(struct dvb_frontend *fe, int enable)
if (write_reg(state, state->nr ? RSTV0910_P2_I2CRPT :
RSTV0910_P1_I2CRPT, i2crpt) < 0) {
/* don't hold the I2C bus lock on failure */
- mutex_unlock(&state->base->i2c_lock);
+ if (!WARN_ON(!mutex_is_locked(&state->base->i2c_lock)))
+ mutex_unlock(&state->base->i2c_lock);
dev_err(&state->base->i2c->dev,
"%s() write_reg failure (enable=%d)\n",
__func__, enable);
@@ -1251,7 +1260,8 @@ static int gate_ctrl(struct dvb_frontend *fe, int enable)
state->i2crpt = i2crpt;
if (!enable)
- mutex_unlock(&state->base->i2c_lock);
+ if (!WARN_ON(!mutex_is_locked(&state->base->i2c_lock)))
+ mutex_unlock(&state->base->i2c_lock);
return 0;
}
@@ -1271,14 +1281,11 @@ static int set_parameters(struct dvb_frontend *fe)
{
int stat = 0;
struct stv *state = fe->demodulator_priv;
- u32 iffreq;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
stop(state);
if (fe->ops.tuner_ops.set_params)
fe->ops.tuner_ops.set_params(fe);
- if (fe->ops.tuner_ops.get_if_frequency)
- fe->ops.tuner_ops.get_if_frequency(fe, &iffreq);
state->symbol_rate = p->symbol_rate;
stat = start(state, p);
return stat;
@@ -1498,6 +1505,19 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status)
enable_puncture_rate(state,
state->puncture_rate);
}
+
+ /* Use highest signaled ModCod for quality */
+ if (state->is_vcm) {
+ u8 tmp;
+ enum fe_stv0910_mod_cod mod_cod;
+
+ read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff,
+ &tmp);
+ mod_cod = (enum fe_stv0910_mod_cod)((tmp & 0x7c) >> 2);
+
+ if (mod_cod > state->mod_cod)
+ state->mod_cod = mod_cod;
+ }
}
/* read signal statistics */
@@ -1527,6 +1547,7 @@ static int get_frontend(struct dvb_frontend *fe,
{
struct stv *state = fe->demodulator_priv;
u8 tmp;
+ u32 symbolrate;
if (state->receive_mode == RCVMODE_DVBS2) {
u32 mc;
@@ -1580,6 +1601,10 @@ static int get_frontend(struct dvb_frontend *fe,
p->rolloff = ROLLOFF_35;
}
+ if (state->receive_mode != RCVMODE_NONE) {
+ get_cur_symbol_rate(state, &symbolrate);
+ p->symbol_rate = symbolrate;
+ }
return 0;
}
diff --git a/drivers/media/dvb-frontends/stv0910_regs.h b/drivers/media/dvb-frontends/stv0910_regs.h
index 32ced4eaf296..f0eb915090bd 100644
--- a/drivers/media/dvb-frontends/stv0910_regs.h
+++ b/drivers/media/dvb-frontends/stv0910_regs.h
@@ -7,15 +7,15 @@
* Registers Declaration (Internal ST, All Applications )
* -------------------------
* Each register (RSTV0910__XXXXX) is defined by its address (2 bytes).
- *
- * Each field (FSTV0910__XXXXX)is defined as follow:
- * [register address -- 2bytes][field sign -- 1byte][field mask -- 1byte]
- * ======================================================================
+ * Each field (FSTV0910__XXXXX) is defined as follow:
+ * [register address -- 2bytes][field offset -- 4 bits][unused -- 3 bits]
+ * [field sign -- 1 bit][field mask -- 1byte]
+ * =======================================================================
*/
/* MID */
#define RSTV0910_MID 0xf100
-#define FSTV0910_MCHIP_IDENT 0xf10000f0
+#define FSTV0910_MCHIP_IDENT 0xf10040f0
#define FSTV0910_MRELEASE 0xf100000f
/* DID */
@@ -24,7 +24,7 @@
/* DACR1 */
#define RSTV0910_DACR1 0xf113
-#define FSTV0910_DAC_MODE 0xf11300e0
+#define FSTV0910_DAC_MODE 0xf11350e0
#define FSTV0910_DAC_VALUE1 0xf113000f
/* DACR2 */
@@ -33,283 +33,283 @@
/* PADCFG */
#define RSTV0910_PADCFG 0xf11a
-#define FSTV0910_AGCRF2_OPD 0xf11a0008
-#define FSTV0910_AGCRF2_XOR 0xf11a0004
-#define FSTV0910_AGCRF1_OPD 0xf11a0002
+#define FSTV0910_AGCRF2_OPD 0xf11a3008
+#define FSTV0910_AGCRF2_XOR 0xf11a2004
+#define FSTV0910_AGCRF1_OPD 0xf11a1002
#define FSTV0910_AGCRF1_XOR 0xf11a0001
/* OUTCFG2 */
#define RSTV0910_OUTCFG2 0xf11b
-#define FSTV0910_TS2_ERROR_XOR 0xf11b0080
-#define FSTV0910_TS2_DPN_XOR 0xf11b0040
-#define FSTV0910_TS2_STROUT_XOR 0xf11b0020
-#define FSTV0910_TS2_CLOCKOUT_XOR 0xf11b0010
-#define FSTV0910_TS1_ERROR_XOR 0xf11b0008
-#define FSTV0910_TS1_DPN_XOR 0xf11b0004
-#define FSTV0910_TS1_STROUT_XOR 0xf11b0002
+#define FSTV0910_TS2_ERROR_XOR 0xf11b7080
+#define FSTV0910_TS2_DPN_XOR 0xf11b6040
+#define FSTV0910_TS2_STROUT_XOR 0xf11b5020
+#define FSTV0910_TS2_CLOCKOUT_XOR 0xf11b4010
+#define FSTV0910_TS1_ERROR_XOR 0xf11b3008
+#define FSTV0910_TS1_DPN_XOR 0xf11b2004
+#define FSTV0910_TS1_STROUT_XOR 0xf11b1002
#define FSTV0910_TS1_CLOCKOUT_XOR 0xf11b0001
/* OUTCFG */
#define RSTV0910_OUTCFG 0xf11c
-#define FSTV0910_TS2_OUTSER_HZ 0xf11c0020
-#define FSTV0910_TS1_OUTSER_HZ 0xf11c0010
-#define FSTV0910_TS2_OUTPAR_HZ 0xf11c0008
-#define FSTV0910_TS1_OUTPAR_HZ 0xf11c0004
-#define FSTV0910_TS_SERDATA0 0xf11c0002
+#define FSTV0910_TS2_OUTSER_HZ 0xf11c5020
+#define FSTV0910_TS1_OUTSER_HZ 0xf11c4010
+#define FSTV0910_TS2_OUTPAR_HZ 0xf11c3008
+#define FSTV0910_TS1_OUTPAR_HZ 0xf11c2004
+#define FSTV0910_TS_SERDATA0 0xf11c1002
/* IRQSTATUS3 */
#define RSTV0910_IRQSTATUS3 0xf120
-#define FSTV0910_SPLL_LOCK 0xf1200020
-#define FSTV0910_SSTREAM_LCK_1 0xf1200010
-#define FSTV0910_SSTREAM_LCK_2 0xf1200008
-#define FSTV0910_SDVBS1_PRF_2 0xf1200002
+#define FSTV0910_SPLL_LOCK 0xf1205020
+#define FSTV0910_SSTREAM_LCK_1 0xf1204010
+#define FSTV0910_SSTREAM_LCK_2 0xf1203008
+#define FSTV0910_SDVBS1_PRF_2 0xf1201002
#define FSTV0910_SDVBS1_PRF_1 0xf1200001
/* IRQSTATUS2 */
#define RSTV0910_IRQSTATUS2 0xf121
-#define FSTV0910_SSPY_ENDSIM_1 0xf1210080
-#define FSTV0910_SSPY_ENDSIM_2 0xf1210040
-#define FSTV0910_SPKTDEL_ERROR_2 0xf1210010
-#define FSTV0910_SPKTDEL_LOCKB_2 0xf1210008
-#define FSTV0910_SPKTDEL_LOCK_2 0xf1210004
-#define FSTV0910_SPKTDEL_ERROR_1 0xf1210002
+#define FSTV0910_SSPY_ENDSIM_1 0xf1217080
+#define FSTV0910_SSPY_ENDSIM_2 0xf1216040
+#define FSTV0910_SPKTDEL_ERROR_2 0xf1214010
+#define FSTV0910_SPKTDEL_LOCKB_2 0xf1213008
+#define FSTV0910_SPKTDEL_LOCK_2 0xf1212004
+#define FSTV0910_SPKTDEL_ERROR_1 0xf1211002
#define FSTV0910_SPKTDEL_LOCKB_1 0xf1210001
/* IRQSTATUS1 */
#define RSTV0910_IRQSTATUS1 0xf122
-#define FSTV0910_SPKTDEL_LOCK_1 0xf1220080
-#define FSTV0910_SFEC_LOCKB_2 0xf1220040
-#define FSTV0910_SFEC_LOCK_2 0xf1220020
-#define FSTV0910_SFEC_LOCKB_1 0xf1220010
-#define FSTV0910_SFEC_LOCK_1 0xf1220008
-#define FSTV0910_SDEMOD_LOCKB_2 0xf1220004
-#define FSTV0910_SDEMOD_LOCK_2 0xf1220002
+#define FSTV0910_SPKTDEL_LOCK_1 0xf1227080
+#define FSTV0910_SFEC_LOCKB_2 0xf1226040
+#define FSTV0910_SFEC_LOCK_2 0xf1225020
+#define FSTV0910_SFEC_LOCKB_1 0xf1224010
+#define FSTV0910_SFEC_LOCK_1 0xf1223008
+#define FSTV0910_SDEMOD_LOCKB_2 0xf1222004
+#define FSTV0910_SDEMOD_LOCK_2 0xf1221002
#define FSTV0910_SDEMOD_IRQ_2 0xf1220001
/* IRQSTATUS0 */
#define RSTV0910_IRQSTATUS0 0xf123
-#define FSTV0910_SDEMOD_LOCKB_1 0xf1230080
-#define FSTV0910_SDEMOD_LOCK_1 0xf1230040
-#define FSTV0910_SDEMOD_IRQ_1 0xf1230020
-#define FSTV0910_SBCH_ERRFLAG 0xf1230010
-#define FSTV0910_SDISEQC2_IRQ 0xf1230004
+#define FSTV0910_SDEMOD_LOCKB_1 0xf1237080
+#define FSTV0910_SDEMOD_LOCK_1 0xf1236040
+#define FSTV0910_SDEMOD_IRQ_1 0xf1235020
+#define FSTV0910_SBCH_ERRFLAG 0xf1234010
+#define FSTV0910_SDISEQC2_IRQ 0xf1232004
#define FSTV0910_SDISEQC1_IRQ 0xf1230001
/* IRQMASK3 */
#define RSTV0910_IRQMASK3 0xf124
-#define FSTV0910_MPLL_LOCK 0xf1240020
-#define FSTV0910_MSTREAM_LCK_1 0xf1240010
-#define FSTV0910_MSTREAM_LCK_2 0xf1240008
-#define FSTV0910_MDVBS1_PRF_2 0xf1240002
+#define FSTV0910_MPLL_LOCK 0xf1245020
+#define FSTV0910_MSTREAM_LCK_1 0xf1244010
+#define FSTV0910_MSTREAM_LCK_2 0xf1243008
+#define FSTV0910_MDVBS1_PRF_2 0xf1241002
#define FSTV0910_MDVBS1_PRF_1 0xf1240001
/* IRQMASK2 */
#define RSTV0910_IRQMASK2 0xf125
-#define FSTV0910_MSPY_ENDSIM_1 0xf1250080
-#define FSTV0910_MSPY_ENDSIM_2 0xf1250040
-#define FSTV0910_MPKTDEL_ERROR_2 0xf1250010
-#define FSTV0910_MPKTDEL_LOCKB_2 0xf1250008
-#define FSTV0910_MPKTDEL_LOCK_2 0xf1250004
-#define FSTV0910_MPKTDEL_ERROR_1 0xf1250002
+#define FSTV0910_MSPY_ENDSIM_1 0xf1257080
+#define FSTV0910_MSPY_ENDSIM_2 0xf1256040
+#define FSTV0910_MPKTDEL_ERROR_2 0xf1254010
+#define FSTV0910_MPKTDEL_LOCKB_2 0xf1253008
+#define FSTV0910_MPKTDEL_LOCK_2 0xf1252004
+#define FSTV0910_MPKTDEL_ERROR_1 0xf1251002
#define FSTV0910_MPKTDEL_LOCKB_1 0xf1250001
/* IRQMASK1 */
#define RSTV0910_IRQMASK1 0xf126
-#define FSTV0910_MPKTDEL_LOCK_1 0xf1260080
-#define FSTV0910_MFEC_LOCKB_2 0xf1260040
-#define FSTV0910_MFEC_LOCK_2 0xf1260020
-#define FSTV0910_MFEC_LOCKB_1 0xf1260010
-#define FSTV0910_MFEC_LOCK_1 0xf1260008
-#define FSTV0910_MDEMOD_LOCKB_2 0xf1260004
-#define FSTV0910_MDEMOD_LOCK_2 0xf1260002
+#define FSTV0910_MPKTDEL_LOCK_1 0xf1267080
+#define FSTV0910_MFEC_LOCKB_2 0xf1266040
+#define FSTV0910_MFEC_LOCK_2 0xf1265020
+#define FSTV0910_MFEC_LOCKB_1 0xf1264010
+#define FSTV0910_MFEC_LOCK_1 0xf1263008
+#define FSTV0910_MDEMOD_LOCKB_2 0xf1262004
+#define FSTV0910_MDEMOD_LOCK_2 0xf1261002
#define FSTV0910_MDEMOD_IRQ_2 0xf1260001
/* IRQMASK0 */
#define RSTV0910_IRQMASK0 0xf127
-#define FSTV0910_MDEMOD_LOCKB_1 0xf1270080
-#define FSTV0910_MDEMOD_LOCK_1 0xf1270040
-#define FSTV0910_MDEMOD_IRQ_1 0xf1270020
-#define FSTV0910_MBCH_ERRFLAG 0xf1270010
-#define FSTV0910_MDISEQC2_IRQ 0xf1270004
+#define FSTV0910_MDEMOD_LOCKB_1 0xf1277080
+#define FSTV0910_MDEMOD_LOCK_1 0xf1276040
+#define FSTV0910_MDEMOD_IRQ_1 0xf1275020
+#define FSTV0910_MBCH_ERRFLAG 0xf1274010
+#define FSTV0910_MDISEQC2_IRQ 0xf1272004
#define FSTV0910_MDISEQC1_IRQ 0xf1270001
/* I2CCFG */
#define RSTV0910_I2CCFG 0xf129
-#define FSTV0910_I2C_FASTMODE 0xf1290008
+#define FSTV0910_I2C_FASTMODE 0xf1293008
#define FSTV0910_I2CADDR_INC 0xf1290003
/* P1_I2CRPT */
#define RSTV0910_P1_I2CRPT 0xf12a
-#define FSTV0910_P1_I2CT_ON 0xf12a0080
-#define FSTV0910_P1_ENARPT_LEVEL 0xf12a0070
-#define FSTV0910_P1_SCLT_DELAY 0xf12a0008
-#define FSTV0910_P1_STOP_ENABLE 0xf12a0004
-#define FSTV0910_P1_STOP_SDAT2SDA 0xf12a0002
+#define FSTV0910_P1_I2CT_ON 0xf12a7080
+#define FSTV0910_P1_ENARPT_LEVEL 0xf12a4070
+#define FSTV0910_P1_SCLT_DELAY 0xf12a3008
+#define FSTV0910_P1_STOP_ENABLE 0xf12a2004
+#define FSTV0910_P1_STOP_SDAT2SDA 0xf12a1002
/* P2_I2CRPT */
#define RSTV0910_P2_I2CRPT 0xf12b
-#define FSTV0910_P2_I2CT_ON 0xf12b0080
-#define FSTV0910_P2_ENARPT_LEVEL 0xf12b0070
-#define FSTV0910_P2_SCLT_DELAY 0xf12b0008
-#define FSTV0910_P2_STOP_ENABLE 0xf12b0004
-#define FSTV0910_P2_STOP_SDAT2SDA 0xf12b0002
+#define FSTV0910_P2_I2CT_ON 0xf12b7080
+#define FSTV0910_P2_ENARPT_LEVEL 0xf12b4070
+#define FSTV0910_P2_SCLT_DELAY 0xf12b3008
+#define FSTV0910_P2_STOP_ENABLE 0xf12b2004
+#define FSTV0910_P2_STOP_SDAT2SDA 0xf12b1002
/* GPIO0CFG */
#define RSTV0910_GPIO0CFG 0xf140
-#define FSTV0910_GPIO0_OPD 0xf1400080
-#define FSTV0910_GPIO0_CONFIG 0xf140007e
+#define FSTV0910_GPIO0_OPD 0xf1407080
+#define FSTV0910_GPIO0_CONFIG 0xf140107e
#define FSTV0910_GPIO0_XOR 0xf1400001
/* GPIO1CFG */
#define RSTV0910_GPIO1CFG 0xf141
-#define FSTV0910_GPIO1_OPD 0xf1410080
-#define FSTV0910_GPIO1_CONFIG 0xf141007e
+#define FSTV0910_GPIO1_OPD 0xf1417080
+#define FSTV0910_GPIO1_CONFIG 0xf141107e
#define FSTV0910_GPIO1_XOR 0xf1410001
/* GPIO2CFG */
#define RSTV0910_GPIO2CFG 0xf142
-#define FSTV0910_GPIO2_OPD 0xf1420080
-#define FSTV0910_GPIO2_CONFIG 0xf142007e
+#define FSTV0910_GPIO2_OPD 0xf1427080
+#define FSTV0910_GPIO2_CONFIG 0xf142107e
#define FSTV0910_GPIO2_XOR 0xf1420001
/* GPIO3CFG */
#define RSTV0910_GPIO3CFG 0xf143
-#define FSTV0910_GPIO3_OPD 0xf1430080
-#define FSTV0910_GPIO3_CONFIG 0xf143007e
+#define FSTV0910_GPIO3_OPD 0xf1437080
+#define FSTV0910_GPIO3_CONFIG 0xf143107e
#define FSTV0910_GPIO3_XOR 0xf1430001
/* GPIO4CFG */
#define RSTV0910_GPIO4CFG 0xf144
-#define FSTV0910_GPIO4_OPD 0xf1440080
-#define FSTV0910_GPIO4_CONFIG 0xf144007e
+#define FSTV0910_GPIO4_OPD 0xf1447080
+#define FSTV0910_GPIO4_CONFIG 0xf144107e
#define FSTV0910_GPIO4_XOR 0xf1440001
/* GPIO5CFG */
#define RSTV0910_GPIO5CFG 0xf145
-#define FSTV0910_GPIO5_OPD 0xf1450080
-#define FSTV0910_GPIO5_CONFIG 0xf145007e
+#define FSTV0910_GPIO5_OPD 0xf1457080
+#define FSTV0910_GPIO5_CONFIG 0xf145107e
#define FSTV0910_GPIO5_XOR 0xf1450001
/* GPIO6CFG */
#define RSTV0910_GPIO6CFG 0xf146
-#define FSTV0910_GPIO6_OPD 0xf1460080
-#define FSTV0910_GPIO6_CONFIG 0xf146007e
+#define FSTV0910_GPIO6_OPD 0xf1467080
+#define FSTV0910_GPIO6_CONFIG 0xf146107e
#define FSTV0910_GPIO6_XOR 0xf1460001
/* GPIO7CFG */
#define RSTV0910_GPIO7CFG 0xf147
-#define FSTV0910_GPIO7_OPD 0xf1470080
-#define FSTV0910_GPIO7_CONFIG 0xf147007e
+#define FSTV0910_GPIO7_OPD 0xf1477080
+#define FSTV0910_GPIO7_CONFIG 0xf147107e
#define FSTV0910_GPIO7_XOR 0xf1470001
/* GPIO8CFG */
#define RSTV0910_GPIO8CFG 0xf148
-#define FSTV0910_GPIO8_OPD 0xf1480080
-#define FSTV0910_GPIO8_CONFIG 0xf148007e
+#define FSTV0910_GPIO8_OPD 0xf1487080
+#define FSTV0910_GPIO8_CONFIG 0xf148107e
#define FSTV0910_GPIO8_XOR 0xf1480001
/* GPIO9CFG */
#define RSTV0910_GPIO9CFG 0xf149
-#define FSTV0910_GPIO9_OPD 0xf1490080
-#define FSTV0910_GPIO9_CONFIG 0xf149007e
+#define FSTV0910_GPIO9_OPD 0xf1497080
+#define FSTV0910_GPIO9_CONFIG 0xf149107e
#define FSTV0910_GPIO9_XOR 0xf1490001
/* GPIO10CFG */
#define RSTV0910_GPIO10CFG 0xf14a
-#define FSTV0910_GPIO10_OPD 0xf14a0080
-#define FSTV0910_GPIO10_CONFIG 0xf14a007e
+#define FSTV0910_GPIO10_OPD 0xf14a7080
+#define FSTV0910_GPIO10_CONFIG 0xf14a107e
#define FSTV0910_GPIO10_XOR 0xf14a0001
/* GPIO11CFG */
#define RSTV0910_GPIO11CFG 0xf14b
-#define FSTV0910_GPIO11_OPD 0xf14b0080
-#define FSTV0910_GPIO11_CONFIG 0xf14b007e
+#define FSTV0910_GPIO11_OPD 0xf14b7080
+#define FSTV0910_GPIO11_CONFIG 0xf14b107e
#define FSTV0910_GPIO11_XOR 0xf14b0001
/* GPIO12CFG */
#define RSTV0910_GPIO12CFG 0xf14c
-#define FSTV0910_GPIO12_OPD 0xf14c0080
-#define FSTV0910_GPIO12_CONFIG 0xf14c007e
+#define FSTV0910_GPIO12_OPD 0xf14c7080
+#define FSTV0910_GPIO12_CONFIG 0xf14c107e
#define FSTV0910_GPIO12_XOR 0xf14c0001
/* GPIO13CFG */
#define RSTV0910_GPIO13CFG 0xf14d
-#define FSTV0910_GPIO13_OPD 0xf14d0080
-#define FSTV0910_GPIO13_CONFIG 0xf14d007e
+#define FSTV0910_GPIO13_OPD 0xf14d7080
+#define FSTV0910_GPIO13_CONFIG 0xf14d107e
#define FSTV0910_GPIO13_XOR 0xf14d0001
/* GPIO14CFG */
#define RSTV0910_GPIO14CFG 0xf14e
-#define FSTV0910_GPIO14_OPD 0xf14e0080
-#define FSTV0910_GPIO14_CONFIG 0xf14e007e
+#define FSTV0910_GPIO14_OPD 0xf14e7080
+#define FSTV0910_GPIO14_CONFIG 0xf14e107e
#define FSTV0910_GPIO14_XOR 0xf14e0001
/* GPIO15CFG */
#define RSTV0910_GPIO15CFG 0xf14f
-#define FSTV0910_GPIO15_OPD 0xf14f0080
-#define FSTV0910_GPIO15_CONFIG 0xf14f007e
+#define FSTV0910_GPIO15_OPD 0xf14f7080
+#define FSTV0910_GPIO15_CONFIG 0xf14f107e
#define FSTV0910_GPIO15_XOR 0xf14f0001
/* GPIO16CFG */
#define RSTV0910_GPIO16CFG 0xf150
-#define FSTV0910_GPIO16_OPD 0xf1500080
-#define FSTV0910_GPIO16_CONFIG 0xf150007e
+#define FSTV0910_GPIO16_OPD 0xf1507080
+#define FSTV0910_GPIO16_CONFIG 0xf150107e
#define FSTV0910_GPIO16_XOR 0xf1500001
/* GPIO17CFG */
#define RSTV0910_GPIO17CFG 0xf151
-#define FSTV0910_GPIO17_OPD 0xf1510080
-#define FSTV0910_GPIO17_CONFIG 0xf151007e
+#define FSTV0910_GPIO17_OPD 0xf1517080
+#define FSTV0910_GPIO17_CONFIG 0xf151107e
#define FSTV0910_GPIO17_XOR 0xf1510001
/* GPIO18CFG */
#define RSTV0910_GPIO18CFG 0xf152
-#define FSTV0910_GPIO18_OPD 0xf1520080
-#define FSTV0910_GPIO18_CONFIG 0xf152007e
+#define FSTV0910_GPIO18_OPD 0xf1527080
+#define FSTV0910_GPIO18_CONFIG 0xf152107e
#define FSTV0910_GPIO18_XOR 0xf1520001
/* GPIO19CFG */
#define RSTV0910_GPIO19CFG 0xf153
-#define FSTV0910_GPIO19_OPD 0xf1530080
-#define FSTV0910_GPIO19_CONFIG 0xf153007e
+#define FSTV0910_GPIO19_OPD 0xf1537080
+#define FSTV0910_GPIO19_CONFIG 0xf153107e
#define FSTV0910_GPIO19_XOR 0xf1530001
/* GPIO20CFG */
#define RSTV0910_GPIO20CFG 0xf154
-#define FSTV0910_GPIO20_OPD 0xf1540080
-#define FSTV0910_GPIO20_CONFIG 0xf154007e
+#define FSTV0910_GPIO20_OPD 0xf1547080
+#define FSTV0910_GPIO20_CONFIG 0xf154107e
#define FSTV0910_GPIO20_XOR 0xf1540001
/* GPIO21CFG */
#define RSTV0910_GPIO21CFG 0xf155
-#define FSTV0910_GPIO21_OPD 0xf1550080
-#define FSTV0910_GPIO21_CONFIG 0xf155007e
+#define FSTV0910_GPIO21_OPD 0xf1557080
+#define FSTV0910_GPIO21_CONFIG 0xf155107e
#define FSTV0910_GPIO21_XOR 0xf1550001
/* GPIO22CFG */
#define RSTV0910_GPIO22CFG 0xf156
-#define FSTV0910_GPIO22_OPD 0xf1560080
-#define FSTV0910_GPIO22_CONFIG 0xf156007e
+#define FSTV0910_GPIO22_OPD 0xf1567080
+#define FSTV0910_GPIO22_CONFIG 0xf156107e
#define FSTV0910_GPIO22_XOR 0xf1560001
/* STRSTATUS1 */
#define RSTV0910_STRSTATUS1 0xf16a
-#define FSTV0910_STRSTATUS_SEL2 0xf16a00f0
+#define FSTV0910_STRSTATUS_SEL2 0xf16a40f0
#define FSTV0910_STRSTATUS_SEL1 0xf16a000f
/* STRSTATUS2 */
#define RSTV0910_STRSTATUS2 0xf16b
-#define FSTV0910_STRSTATUS_SEL4 0xf16b00f0
+#define FSTV0910_STRSTATUS_SEL4 0xf16b40f0
#define FSTV0910_STRSTATUS_SEL3 0xf16b000f
/* STRSTATUS3 */
#define RSTV0910_STRSTATUS3 0xf16c
-#define FSTV0910_STRSTATUS_SEL6 0xf16c00f0
+#define FSTV0910_STRSTATUS_SEL6 0xf16c40f0
#define FSTV0910_STRSTATUS_SEL5 0xf16c000f
/* FSKTFC2 */
#define RSTV0910_FSKTFC2 0xf170
-#define FSTV0910_FSKT_KMOD 0xf17000fc
+#define FSTV0910_FSKT_KMOD 0xf17020fc
#define FSTV0910_FSKT_CAR2 0xf1700003
/* FSKTFC1 */
@@ -330,17 +330,17 @@
/* FSKTCTRL */
#define RSTV0910_FSKTCTRL 0xf175
-#define FSTV0910_FSKT_PINSEL 0xf1750080
-#define FSTV0910_FSKT_EN_SGN 0xf1750040
-#define FSTV0910_FSKT_MOD_SGN 0xf1750020
-#define FSTV0910_FSKT_MOD_EN 0xf175001c
+#define FSTV0910_FSKT_PINSEL 0xf1757080
+#define FSTV0910_FSKT_EN_SGN 0xf1756040
+#define FSTV0910_FSKT_MOD_SGN 0xf1755020
+#define FSTV0910_FSKT_MOD_EN 0xf175201c
#define FSTV0910_FSKT_DACMODE 0xf1750003
/* FSKRFC2 */
#define RSTV0910_FSKRFC2 0xf176
-#define FSTV0910_FSKR_DETSGN 0xf1760040
-#define FSTV0910_FSKR_OUTSGN 0xf1760020
-#define FSTV0910_FSKR_KAGC 0xf176001c
+#define FSTV0910_FSKR_DETSGN 0xf1766040
+#define FSTV0910_FSKR_OUTSGN 0xf1765020
+#define FSTV0910_FSKR_KAGC 0xf176201c
#define FSTV0910_FSKR_CAR2 0xf1760003
/* FSKRFC1 */
@@ -353,17 +353,17 @@
/* FSKRK1 */
#define RSTV0910_FSKRK1 0xf179
-#define FSTV0910_FSKR_K1_EXP 0xf17900e0
+#define FSTV0910_FSKR_K1_EXP 0xf17950e0
#define FSTV0910_FSKR_K1_MANT 0xf179001f
/* FSKRK2 */
#define RSTV0910_FSKRK2 0xf17a
-#define FSTV0910_FSKR_K2_EXP 0xf17a00e0
+#define FSTV0910_FSKR_K2_EXP 0xf17a50e0
#define FSTV0910_FSKR_K2_MANT 0xf17a001f
/* FSKRAGCR */
#define RSTV0910_FSKRAGCR 0xf17b
-#define FSTV0910_FSKR_OUTCTL 0xf17b00c0
+#define FSTV0910_FSKR_OUTCTL 0xf17b60c0
#define FSTV0910_FSKR_AGC_REF 0xf17b003f
/* FSKRAGC */
@@ -372,12 +372,12 @@
/* FSKRALPHA */
#define RSTV0910_FSKRALPHA 0xf17d
-#define FSTV0910_FSKR_ALPHA_EXP 0xf17d001c
+#define FSTV0910_FSKR_ALPHA_EXP 0xf17d201c
#define FSTV0910_FSKR_ALPHA_M 0xf17d0003
/* FSKRPLTH1 */
#define RSTV0910_FSKRPLTH1 0xf17e
-#define FSTV0910_FSKR_BETA 0xf17e00f0
+#define FSTV0910_FSKR_BETA 0xf17e40f0
#define FSTV0910_FSKR_PLL_TRESH1 0xf17e000f
/* FSKRPLTH0 */
@@ -386,8 +386,8 @@
/* FSKRDF1 */
#define RSTV0910_FSKRDF1 0xf180
-#define FSTV0910_FSKR_OUT 0xf1800080
-#define FSTV0910_FSKR_STATE 0xf1800060
+#define FSTV0910_FSKR_OUT 0xf1807080
+#define FSTV0910_FSKR_STATE 0xf1805060
#define FSTV0910_FSKR_DELTAF1 0xf180001f
/* FSKRDF0 */
@@ -404,7 +404,7 @@
/* FSKRDET1 */
#define RSTV0910_FSKRDET1 0xf184
-#define FSTV0910_FSKR_DETECT 0xf1840080
+#define FSTV0910_FSKR_DETECT 0xf1847080
#define FSTV0910_FSKR_CARDET_ACCU1 0xf184000f
/* FSKRDET0 */
@@ -413,7 +413,7 @@
/* FSKRDTH1 */
#define RSTV0910_FSKRDTH1 0xf186
-#define FSTV0910_FSKR_CARLOSS_THRESH1 0xf18600f0
+#define FSTV0910_FSKR_CARLOSS_THRESH1 0xf18640f0
#define FSTV0910_FSKR_CARDET_THRESH1 0xf186000f
/* FSKRDTH0 */
@@ -426,7 +426,7 @@
/* NCOARSE */
#define RSTV0910_NCOARSE 0xf1b3
-#define FSTV0910_CP 0xf1b300f8
+#define FSTV0910_CP 0xf1b330f8
#define FSTV0910_IDF 0xf1b30007
/* NCOARSE1 */
@@ -439,14 +439,14 @@
/* SYNTCTRL */
#define RSTV0910_SYNTCTRL 0xf1b6
-#define FSTV0910_STANDBY 0xf1b60080
-#define FSTV0910_BYPASSPLLCORE 0xf1b60040
-#define FSTV0910_STOP_PLL 0xf1b60008
-#define FSTV0910_OSCI_E 0xf1b60002
+#define FSTV0910_STANDBY 0xf1b67080
+#define FSTV0910_BYPASSPLLCORE 0xf1b66040
+#define FSTV0910_STOP_PLL 0xf1b63008
+#define FSTV0910_OSCI_E 0xf1b61002
/* FILTCTRL */
#define RSTV0910_FILTCTRL 0xf1b7
-#define FSTV0910_INV_CLKFSK 0xf1b70002
+#define FSTV0910_INV_CLKFSK 0xf1b71002
#define FSTV0910_BYPASS_APPLI 0xf1b70001
/* PLLSTAT */
@@ -455,48 +455,48 @@
/* STOPCLK1 */
#define RSTV0910_STOPCLK1 0xf1c2
-#define FSTV0910_INV_CLKADCI2 0xf1c20004
+#define FSTV0910_INV_CLKADCI2 0xf1c22004
#define FSTV0910_INV_CLKADCI1 0xf1c20001
/* STOPCLK2 */
#define RSTV0910_STOPCLK2 0xf1c3
-#define FSTV0910_STOP_DVBS2FEC2 0xf1c30020
-#define FSTV0910_STOP_DVBS2FEC 0xf1c30010
-#define FSTV0910_STOP_DVBS1FEC2 0xf1c30008
-#define FSTV0910_STOP_DVBS1FEC 0xf1c30004
-#define FSTV0910_STOP_DEMOD2 0xf1c30002
+#define FSTV0910_STOP_DVBS2FEC2 0xf1c35020
+#define FSTV0910_STOP_DVBS2FEC 0xf1c34010
+#define FSTV0910_STOP_DVBS1FEC2 0xf1c33008
+#define FSTV0910_STOP_DVBS1FEC 0xf1c32004
+#define FSTV0910_STOP_DEMOD2 0xf1c31002
#define FSTV0910_STOP_DEMOD 0xf1c30001
/* PREGCTL */
#define RSTV0910_PREGCTL 0xf1c8
-#define FSTV0910_REG3V3TO2V5_POFF 0xf1c80080
+#define FSTV0910_REG3V3TO2V5_POFF 0xf1c87080
/* TSTTNR0 */
#define RSTV0910_TSTTNR0 0xf1df
-#define FSTV0910_FSK_PON 0xf1df0004
+#define FSTV0910_FSK_PON 0xf1df2004
/* TSTTNR1 */
#define RSTV0910_TSTTNR1 0xf1e0
-#define FSTV0910_ADC1_PON 0xf1e00002
+#define FSTV0910_ADC1_PON 0xf1e01002
/* TSTTNR2 */
#define RSTV0910_TSTTNR2 0xf1e1
-#define FSTV0910_I2C_DISEQC_PON 0xf1e10020
+#define FSTV0910_I2C_DISEQC_PON 0xf1e15020
#define FSTV0910_DISEQC_CLKDIV 0xf1e1000f
/* TSTTNR3 */
#define RSTV0910_TSTTNR3 0xf1e2
-#define FSTV0910_ADC2_PON 0xf1e20002
+#define FSTV0910_ADC2_PON 0xf1e21002
/* P2_IQCONST */
#define RSTV0910_P2_IQCONST 0xf200
-#define FSTV0910_P2_CONSTEL_SELECT 0xf2000060
+#define FSTV0910_P2_CONSTEL_SELECT 0xf2005060
#define FSTV0910_P2_IQSYMB_SEL 0xf200001f
/* P2_NOSCFG */
#define RSTV0910_P2_NOSCFG 0xf201
-#define FSTV0910_P2_DUMMYPL_NOSDATA 0xf2010020
-#define FSTV0910_P2_NOSPLH_BETA 0xf2010018
+#define FSTV0910_P2_DUMMYPL_NOSDATA 0xf2015020
+#define FSTV0910_P2_NOSPLH_BETA 0xf2013018
#define FSTV0910_P2_NOSDATA_BETA 0xf2010007
/* P2_ISYMB */
@@ -509,18 +509,18 @@
/* P2_AGC1CFG */
#define RSTV0910_P2_AGC1CFG 0xf204
-#define FSTV0910_P2_DC_FROZEN 0xf2040080
-#define FSTV0910_P2_DC_CORRECT 0xf2040040
-#define FSTV0910_P2_AMM_FROZEN 0xf2040020
-#define FSTV0910_P2_AMM_CORRECT 0xf2040010
-#define FSTV0910_P2_QUAD_FROZEN 0xf2040008
-#define FSTV0910_P2_QUAD_CORRECT 0xf2040004
+#define FSTV0910_P2_DC_FROZEN 0xf2047080
+#define FSTV0910_P2_DC_CORRECT 0xf2046040
+#define FSTV0910_P2_AMM_FROZEN 0xf2045020
+#define FSTV0910_P2_AMM_CORRECT 0xf2044010
+#define FSTV0910_P2_QUAD_FROZEN 0xf2043008
+#define FSTV0910_P2_QUAD_CORRECT 0xf2042004
/* P2_AGC1CN */
#define RSTV0910_P2_AGC1CN 0xf206
-#define FSTV0910_P2_AGC1_LOCKED 0xf2060080
-#define FSTV0910_P2_AGC1_MINPOWER 0xf2060010
-#define FSTV0910_P2_AGCOUT_FAST 0xf2060008
+#define FSTV0910_P2_AGC1_LOCKED 0xf2067080
+#define FSTV0910_P2_AGC1_MINPOWER 0xf2064010
+#define FSTV0910_P2_AGCOUT_FAST 0xf2063008
#define FSTV0910_P2_AGCIQ_BETA 0xf2060007
/* P2_AGC1REF */
@@ -561,50 +561,50 @@
/* P2_DEMOD */
#define RSTV0910_P2_DEMOD 0xf210
-#define FSTV0910_P2_MANUALS2_ROLLOFF 0xf2100080
-#define FSTV0910_P2_SPECINV_CONTROL 0xf2100030
-#define FSTV0910_P2_MANUALSX_ROLLOFF 0xf2100004
+#define FSTV0910_P2_MANUALS2_ROLLOFF 0xf2107080
+#define FSTV0910_P2_SPECINV_CONTROL 0xf2104030
+#define FSTV0910_P2_MANUALSX_ROLLOFF 0xf2102004
#define FSTV0910_P2_ROLLOFF_CONTROL 0xf2100003
/* P2_DMDMODCOD */
#define RSTV0910_P2_DMDMODCOD 0xf211
-#define FSTV0910_P2_MANUAL_MODCOD 0xf2110080
-#define FSTV0910_P2_DEMOD_MODCOD 0xf211007c
+#define FSTV0910_P2_MANUAL_MODCOD 0xf2117080
+#define FSTV0910_P2_DEMOD_MODCOD 0xf211207c
#define FSTV0910_P2_DEMOD_TYPE 0xf2110003
/* P2_DSTATUS */
#define RSTV0910_P2_DSTATUS 0xf212
-#define FSTV0910_P2_CAR_LOCK 0xf2120080
-#define FSTV0910_P2_TMGLOCK_QUALITY 0xf2120060
-#define FSTV0910_P2_LOCK_DEFINITIF 0xf2120008
+#define FSTV0910_P2_CAR_LOCK 0xf2127080
+#define FSTV0910_P2_TMGLOCK_QUALITY 0xf2125060
+#define FSTV0910_P2_LOCK_DEFINITIF 0xf2123008
#define FSTV0910_P2_OVADC_DETECT 0xf2120001
/* P2_DSTATUS2 */
#define RSTV0910_P2_DSTATUS2 0xf213
-#define FSTV0910_P2_DEMOD_DELOCK 0xf2130080
-#define FSTV0910_P2_MODCODRQ_SYNCTAG 0xf2130020
-#define FSTV0910_P2_POLYPH_SATEVENT 0xf2130010
-#define FSTV0910_P2_AGC1_NOSIGNALACK 0xf2130008
-#define FSTV0910_P2_AGC2_OVERFLOW 0xf2130004
-#define FSTV0910_P2_CFR_OVERFLOW 0xf2130002
+#define FSTV0910_P2_DEMOD_DELOCK 0xf2137080
+#define FSTV0910_P2_MODCODRQ_SYNCTAG 0xf2135020
+#define FSTV0910_P2_POLYPH_SATEVENT 0xf2134010
+#define FSTV0910_P2_AGC1_NOSIGNALACK 0xf2133008
+#define FSTV0910_P2_AGC2_OVERFLOW 0xf2132004
+#define FSTV0910_P2_CFR_OVERFLOW 0xf2131002
#define FSTV0910_P2_GAMMA_OVERUNDER 0xf2130001
/* P2_DMDCFGMD */
#define RSTV0910_P2_DMDCFGMD 0xf214
-#define FSTV0910_P2_DVBS2_ENABLE 0xf2140080
-#define FSTV0910_P2_DVBS1_ENABLE 0xf2140040
-#define FSTV0910_P2_SCAN_ENABLE 0xf2140010
-#define FSTV0910_P2_CFR_AUTOSCAN 0xf2140008
+#define FSTV0910_P2_DVBS2_ENABLE 0xf2147080
+#define FSTV0910_P2_DVBS1_ENABLE 0xf2146040
+#define FSTV0910_P2_SCAN_ENABLE 0xf2144010
+#define FSTV0910_P2_CFR_AUTOSCAN 0xf2143008
#define FSTV0910_P2_TUN_RNG 0xf2140003
/* P2_DMDCFG2 */
#define RSTV0910_P2_DMDCFG2 0xf215
-#define FSTV0910_P2_S1S2_SEQUENTIAL 0xf2150040
-#define FSTV0910_P2_INFINITE_RELOCK 0xf2150010
+#define FSTV0910_P2_S1S2_SEQUENTIAL 0xf2156040
+#define FSTV0910_P2_INFINITE_RELOCK 0xf2154010
/* P2_DMDISTATE */
#define RSTV0910_P2_DMDISTATE 0xf216
-#define FSTV0910_P2_I2C_NORESETDMODE 0xf2160080
+#define FSTV0910_P2_I2C_NORESETDMODE 0xf2167080
#define FSTV0910_P2_I2C_DEMOD_MODE 0xf216001f
/* P2_DMDT0M */
@@ -613,27 +613,27 @@
/* P2_DMDSTATE */
#define RSTV0910_P2_DMDSTATE 0xf21b
-#define FSTV0910_P2_HEADER_MODE 0xf21b0060
+#define FSTV0910_P2_HEADER_MODE 0xf21b5060
/* P2_DMDFLYW */
#define RSTV0910_P2_DMDFLYW 0xf21c
-#define FSTV0910_P2_I2C_IRQVAL 0xf21c00f0
+#define FSTV0910_P2_I2C_IRQVAL 0xf21c40f0
#define FSTV0910_P2_FLYWHEEL_CPT 0xf21c000f
/* P2_DSTATUS3 */
#define RSTV0910_P2_DSTATUS3 0xf21d
-#define FSTV0910_P2_CFR_ZIGZAG 0xf21d0080
-#define FSTV0910_P2_DEMOD_CFGMODE 0xf21d0060
-#define FSTV0910_P2_GAMMA_LOWBAUDRATE 0xf21d0010
+#define FSTV0910_P2_CFR_ZIGZAG 0xf21d7080
+#define FSTV0910_P2_DEMOD_CFGMODE 0xf21d5060
+#define FSTV0910_P2_GAMMA_LOWBAUDRATE 0xf21d4010
/* P2_DMDCFG3 */
#define RSTV0910_P2_DMDCFG3 0xf21e
-#define FSTV0910_P2_NOSTOP_FIFOFULL 0xf21e0008
+#define FSTV0910_P2_NOSTOP_FIFOFULL 0xf21e3008
/* P2_DMDCFG4 */
#define RSTV0910_P2_DMDCFG4 0xf21f
-#define FSTV0910_P2_DIS_VITLOCK 0xf21f0080
-#define FSTV0910_P2_DIS_CLKENABLE 0xf21f0004
+#define FSTV0910_P2_DIS_VITLOCK 0xf21f7080
+#define FSTV0910_P2_DIS_CLKENABLE 0xf21f2004
/* P2_CORRELMANT */
#define RSTV0910_P2_CORRELMANT 0xf220
@@ -645,13 +645,13 @@
/* P2_CORRELEXP */
#define RSTV0910_P2_CORRELEXP 0xf222
-#define FSTV0910_P2_CORREL_ABSEXP 0xf22200f0
+#define FSTV0910_P2_CORREL_ABSEXP 0xf22240f0
#define FSTV0910_P2_CORREL_EXP 0xf222000f
/* P2_PLHMODCOD */
#define RSTV0910_P2_PLHMODCOD 0xf224
-#define FSTV0910_P2_SPECINV_DEMOD 0xf2240080
-#define FSTV0910_P2_PLH_MODCOD 0xf224007c
+#define FSTV0910_P2_SPECINV_DEMOD 0xf2247080
+#define FSTV0910_P2_PLH_MODCOD 0xf224207c
#define FSTV0910_P2_PLH_TYPE 0xf2240003
/* P2_DMDREG */
@@ -660,19 +660,19 @@
/* P2_AGCNADJ */
#define RSTV0910_P2_AGCNADJ 0xf226
-#define FSTV0910_P2_RADJOFF_AGC2 0xf2260080
-#define FSTV0910_P2_RADJOFF_AGC1 0xf2260040
+#define FSTV0910_P2_RADJOFF_AGC2 0xf2267080
+#define FSTV0910_P2_RADJOFF_AGC1 0xf2266040
#define FSTV0910_P2_AGC_NADJ 0xf226013f
/* P2_AGCKS */
#define RSTV0910_P2_AGCKS 0xf227
-#define FSTV0910_P2_RSADJ_MANUALCFG 0xf2270080
-#define FSTV0910_P2_RSADJ_CCMMODE 0xf2270040
+#define FSTV0910_P2_RSADJ_MANUALCFG 0xf2277080
+#define FSTV0910_P2_RSADJ_CCMMODE 0xf2276040
#define FSTV0910_P2_RADJ_SPSK 0xf227013f
/* P2_AGCKQ */
#define RSTV0910_P2_AGCKQ 0xf228
-#define FSTV0910_P2_RADJON_DVBS1 0xf2280040
+#define FSTV0910_P2_RADJON_DVBS1 0xf2286040
#define FSTV0910_P2_RADJ_QPSK 0xf228013f
/* P2_AGCK8 */
@@ -681,20 +681,20 @@
/* P2_AGCK16 */
#define RSTV0910_P2_AGCK16 0xf22a
-#define FSTV0910_P2_R2ADJOFF_16APSK 0xf22a0040
-#define FSTV0910_P2_R1ADJOFF_16APSK 0xf22a0020
+#define FSTV0910_P2_R2ADJOFF_16APSK 0xf22a6040
+#define FSTV0910_P2_R1ADJOFF_16APSK 0xf22a5020
#define FSTV0910_P2_RADJ_16APSK 0xf22a011f
/* P2_AGCK32 */
#define RSTV0910_P2_AGCK32 0xf22b
-#define FSTV0910_P2_R3ADJOFF_32APSK 0xf22b0080
-#define FSTV0910_P2_R2ADJOFF_32APSK 0xf22b0040
-#define FSTV0910_P2_R1ADJOFF_32APSK 0xf22b0020
+#define FSTV0910_P2_R3ADJOFF_32APSK 0xf22b7080
+#define FSTV0910_P2_R2ADJOFF_32APSK 0xf22b6040
+#define FSTV0910_P2_R1ADJOFF_32APSK 0xf22b5020
#define FSTV0910_P2_RADJ_32APSK 0xf22b011f
/* P2_AGC2O */
#define RSTV0910_P2_AGC2O 0xf22c
-#define FSTV0910_P2_CSTENV_MODE 0xf22c00c0
+#define FSTV0910_P2_CSTENV_MODE 0xf22c60c0
#define FSTV0910_P2_AGC2_COEF 0xf22c0007
/* P2_AGC2REF */
@@ -743,32 +743,32 @@
/* P2_CARCFG */
#define RSTV0910_P2_CARCFG 0xf238
-#define FSTV0910_P2_ROTAON 0xf2380004
+#define FSTV0910_P2_ROTAON 0xf2382004
#define FSTV0910_P2_PH_DET_ALGO 0xf2380003
/* P2_ACLC */
#define RSTV0910_P2_ACLC 0xf239
-#define FSTV0910_P2_CAR_ALPHA_MANT 0xf2390030
+#define FSTV0910_P2_CAR_ALPHA_MANT 0xf2394030
#define FSTV0910_P2_CAR_ALPHA_EXP 0xf239000f
/* P2_BCLC */
#define RSTV0910_P2_BCLC 0xf23a
-#define FSTV0910_P2_CAR_BETA_MANT 0xf23a0030
+#define FSTV0910_P2_CAR_BETA_MANT 0xf23a4030
#define FSTV0910_P2_CAR_BETA_EXP 0xf23a000f
/* P2_ACLCS2 */
#define RSTV0910_P2_ACLCS2 0xf23b
-#define FSTV0910_P2_CARS2_APLHA_MANTISSE 0xf23b0030
+#define FSTV0910_P2_CARS2_APLHA_MANTISSE 0xf23b4030
#define FSTV0910_P2_CARS2_ALPHA_EXP 0xf23b000f
/* P2_BCLCS2 */
#define RSTV0910_P2_BCLCS2 0xf23c
-#define FSTV0910_P2_CARS2_BETA_MANTISSE 0xf23c0030
+#define FSTV0910_P2_CARS2_BETA_MANTISSE 0xf23c4030
#define FSTV0910_P2_CARS2_BETA_EXP 0xf23c000f
/* P2_CARFREQ */
#define RSTV0910_P2_CARFREQ 0xf23d
-#define FSTV0910_P2_KC_COARSE_EXP 0xf23d00f0
+#define FSTV0910_P2_KC_COARSE_EXP 0xf23d40f0
#define FSTV0910_P2_BETA_FREQ 0xf23d000f
/* P2_CARHDR */
@@ -821,7 +821,7 @@
/* P2_CFRINC1 */
#define RSTV0910_P2_CFRINC1 0xf24a
-#define FSTV0910_P2_MANUAL_CFRINC 0xf24a0080
+#define FSTV0910_P2_MANUAL_CFRINC 0xf24a7080
#define FSTV0910_P2_CFR_INC1 0xf24a003f
/* P2_CFRINC0 */
@@ -846,18 +846,18 @@
/* P2_TMGCFG */
#define RSTV0910_P2_TMGCFG 0xf250
-#define FSTV0910_P2_TMGLOCK_BETA 0xf25000c0
-#define FSTV0910_P2_DO_TIMING_CORR 0xf2500010
+#define FSTV0910_P2_TMGLOCK_BETA 0xf25060c0
+#define FSTV0910_P2_DO_TIMING_CORR 0xf2504010
#define FSTV0910_P2_TMG_MINFREQ 0xf2500003
/* P2_RTC */
#define RSTV0910_P2_RTC 0xf251
-#define FSTV0910_P2_TMGALPHA_EXP 0xf25100f0
+#define FSTV0910_P2_TMGALPHA_EXP 0xf25140f0
#define FSTV0910_P2_TMGBETA_EXP 0xf251000f
/* P2_RTCS2 */
#define RSTV0910_P2_RTCS2 0xf252
-#define FSTV0910_P2_TMGALPHAS2_EXP 0xf25200f0
+#define FSTV0910_P2_TMGALPHAS2_EXP 0xf25240f0
#define FSTV0910_P2_TMGBETAS2_EXP 0xf252000f
/* P2_TMGTHRISE */
@@ -878,7 +878,7 @@
/* P2_KTTMG */
#define RSTV0910_P2_KTTMG 0xf257
-#define FSTV0910_P2_KT_TMG_EXP 0xf25700f0
+#define FSTV0910_P2_KT_TMG_EXP 0xf25740f0
/* P2_KREFTMG */
#define RSTV0910_P2_KREFTMG 0xf258
@@ -886,12 +886,12 @@
/* P2_SFRSTEP */
#define RSTV0910_P2_SFRSTEP 0xf259
-#define FSTV0910_P2_SFR_SCANSTEP 0xf25900f0
+#define FSTV0910_P2_SFR_SCANSTEP 0xf25940f0
#define FSTV0910_P2_SFR_CENTERSTEP 0xf259000f
/* P2_TMGCFG2 */
#define RSTV0910_P2_TMGCFG2 0xf25a
-#define FSTV0910_P2_DIS_AUTOSAMP 0xf25a0008
+#define FSTV0910_P2_DIS_AUTOSAMP 0xf25a3008
#define FSTV0910_P2_SFRRATIO_FINE 0xf25a0001
/* P2_KREFTMG2 */
@@ -900,9 +900,9 @@
/* P2_TMGCFG3 */
#define RSTV0910_P2_TMGCFG3 0xf25d
-#define FSTV0910_P2_CONT_TMGCENTER 0xf25d0008
-#define FSTV0910_P2_AUTO_GUP 0xf25d0004
-#define FSTV0910_P2_AUTO_GLOW 0xf25d0002
+#define FSTV0910_P2_CONT_TMGCENTER 0xf25d3008
+#define FSTV0910_P2_AUTO_GUP 0xf25d2004
+#define FSTV0910_P2_AUTO_GLOW 0xf25d1002
/* P2_SFRINIT1 */
#define RSTV0910_P2_SFRINIT1 0xf25e
@@ -966,11 +966,11 @@
/* P2_TMGOBS */
#define RSTV0910_P2_TMGOBS 0xf26d
-#define FSTV0910_P2_ROLLOFF_STATUS 0xf26d00c0
+#define FSTV0910_P2_ROLLOFF_STATUS 0xf26d60c0
/* P2_EQUALCFG */
#define RSTV0910_P2_EQUALCFG 0xf26f
-#define FSTV0910_P2_EQUAL_ON 0xf26f0040
+#define FSTV0910_P2_EQUAL_ON 0xf26f6040
#define FSTV0910_P2_MU_EQUALDFE 0xf26f0007
/* P2_EQUAI1 */
@@ -1095,33 +1095,33 @@
/* P2_NOSCFGF1 */
#define RSTV0910_P2_NOSCFGF1 0xf28e
-#define FSTV0910_P2_LOWNOISE_MESURE 0xf28e0080
-#define FSTV0910_P2_NOS_DELFRAME 0xf28e0040
-#define FSTV0910_P2_NOSDATA_MODE 0xf28e0030
-#define FSTV0910_P2_FRAMESEL_TYPESEL 0xf28e000c
+#define FSTV0910_P2_LOWNOISE_MESURE 0xf28e7080
+#define FSTV0910_P2_NOS_DELFRAME 0xf28e6040
+#define FSTV0910_P2_NOSDATA_MODE 0xf28e4030
+#define FSTV0910_P2_FRAMESEL_TYPESEL 0xf28e200c
#define FSTV0910_P2_FRAMESEL_TYPE 0xf28e0003
/* P2_NOSCFGF2 */
#define RSTV0910_P2_NOSCFGF2 0xf28f
-#define FSTV0910_P2_DIS_NOSPILOTS 0xf28f0080
-#define FSTV0910_P2_FRAMESEL_MODCODSEL 0xf28f0060
+#define FSTV0910_P2_DIS_NOSPILOTS 0xf28f7080
+#define FSTV0910_P2_FRAMESEL_MODCODSEL 0xf28f5060
#define FSTV0910_P2_FRAMESEL_MODCOD 0xf28f001f
/* P2_CAR2CFG */
#define RSTV0910_P2_CAR2CFG 0xf290
-#define FSTV0910_P2_ROTA2ON 0xf2900004
+#define FSTV0910_P2_ROTA2ON 0xf2902004
#define FSTV0910_P2_PH_DET_ALGO2 0xf2900003
/* P2_CFR2CFR1 */
#define RSTV0910_P2_CFR2CFR1 0xf291
-#define FSTV0910_P2_EN_S2CAR2CENTER 0xf2910020
+#define FSTV0910_P2_EN_S2CAR2CENTER 0xf2915020
#define FSTV0910_P2_CFR2TOCFR1_BETA 0xf2910007
/* P2_CAR3CFG */
#define RSTV0910_P2_CAR3CFG 0xf292
-#define FSTV0910_P2_CARRIER23_MODE 0xf29200c0
-#define FSTV0910_P2_CAR3INTERM_DVBS1 0xf2920020
-#define FSTV0910_P2_ABAMPLIF_MODE 0xf2920018
+#define FSTV0910_P2_CARRIER23_MODE 0xf29260c0
+#define FSTV0910_P2_CAR3INTERM_DVBS1 0xf2925020
+#define FSTV0910_P2_ABAMPLIF_MODE 0xf2923018
#define FSTV0910_P2_CARRIER3_ALPHA3DL 0xf2920007
/* P2_CFR22 */
@@ -1138,50 +1138,50 @@
/* P2_ACLC2S2Q */
#define RSTV0910_P2_ACLC2S2Q 0xf297
-#define FSTV0910_P2_ENAB_SPSKSYMB 0xf2970080
-#define FSTV0910_P2_CAR2S2_Q_ALPH_M 0xf2970030
+#define FSTV0910_P2_ENAB_SPSKSYMB 0xf2977080
+#define FSTV0910_P2_CAR2S2_Q_ALPH_M 0xf2974030
#define FSTV0910_P2_CAR2S2_Q_ALPH_E 0xf297000f
/* P2_ACLC2S28 */
#define RSTV0910_P2_ACLC2S28 0xf298
-#define FSTV0910_P2_CAR2S2_8_ALPH_M 0xf2980030
+#define FSTV0910_P2_CAR2S2_8_ALPH_M 0xf2984030
#define FSTV0910_P2_CAR2S2_8_ALPH_E 0xf298000f
/* P2_ACLC2S216A */
#define RSTV0910_P2_ACLC2S216A 0xf299
-#define FSTV0910_P2_CAR2S2_16A_ALPH_M 0xf2990030
+#define FSTV0910_P2_CAR2S2_16A_ALPH_M 0xf2994030
#define FSTV0910_P2_CAR2S2_16A_ALPH_E 0xf299000f
/* P2_ACLC2S232A */
#define RSTV0910_P2_ACLC2S232A 0xf29a
-#define FSTV0910_P2_CAR2S2_32A_ALPH_M 0xf29a0030
+#define FSTV0910_P2_CAR2S2_32A_ALPH_M 0xf29a4030
#define FSTV0910_P2_CAR2S2_32A_ALPH_E 0xf29a000f
/* P2_BCLC2S2Q */
#define RSTV0910_P2_BCLC2S2Q 0xf29c
-#define FSTV0910_P2_CAR2S2_Q_BETA_M 0xf29c0030
+#define FSTV0910_P2_CAR2S2_Q_BETA_M 0xf29c4030
#define FSTV0910_P2_CAR2S2_Q_BETA_E 0xf29c000f
/* P2_BCLC2S28 */
#define RSTV0910_P2_BCLC2S28 0xf29d
-#define FSTV0910_P2_CAR2S2_8_BETA_M 0xf29d0030
+#define FSTV0910_P2_CAR2S2_8_BETA_M 0xf29d4030
#define FSTV0910_P2_CAR2S2_8_BETA_E 0xf29d000f
/* P2_BCLC2S216A */
#define RSTV0910_P2_BCLC2S216A 0xf29e
-#define FSTV0910_P2_DVBS2S216A_NIP 0xf29e0080
-#define FSTV0910_P2_CAR2S2_16A_BETA_M 0xf29e0030
+#define FSTV0910_P2_DVBS2S216A_NIP 0xf29e7080
+#define FSTV0910_P2_CAR2S2_16A_BETA_M 0xf29e4030
#define FSTV0910_P2_CAR2S2_16A_BETA_E 0xf29e000f
/* P2_BCLC2S232A */
#define RSTV0910_P2_BCLC2S232A 0xf29f
-#define FSTV0910_P2_DVBS2S232A_NIP 0xf29f0080
-#define FSTV0910_P2_CAR2S2_32A_BETA_M 0xf29f0030
+#define FSTV0910_P2_DVBS2S232A_NIP 0xf29f7080
+#define FSTV0910_P2_CAR2S2_32A_BETA_M 0xf29f4030
#define FSTV0910_P2_CAR2S2_32A_BETA_E 0xf29f000f
/* P2_PLROOT2 */
#define RSTV0910_P2_PLROOT2 0xf2ac
-#define FSTV0910_P2_PLSCRAMB_MODE 0xf2ac000c
+#define FSTV0910_P2_PLSCRAMB_MODE 0xf2ac200c
#define FSTV0910_P2_PLSCRAMB_ROOT2 0xf2ac0003
/* P2_PLROOT1 */
@@ -1198,100 +1198,100 @@
/* P2_MODCODLST1 */
#define RSTV0910_P2_MODCODLST1 0xf2b1
-#define FSTV0910_P2_SYMBRATE_FILTER 0xf2b10008
-#define FSTV0910_P2_NRESET_MODCODLST 0xf2b10004
+#define FSTV0910_P2_SYMBRATE_FILTER 0xf2b13008
+#define FSTV0910_P2_NRESET_MODCODLST 0xf2b12004
#define FSTV0910_P2_DIS_32PSK_9_10 0xf2b10003
/* P2_MODCODLST2 */
#define RSTV0910_P2_MODCODLST2 0xf2b2
-#define FSTV0910_P2_DIS_32PSK_8_9 0xf2b200f0
+#define FSTV0910_P2_DIS_32PSK_8_9 0xf2b240f0
#define FSTV0910_P2_DIS_32PSK_5_6 0xf2b2000f
/* P2_MODCODLST3 */
#define RSTV0910_P2_MODCODLST3 0xf2b3
-#define FSTV0910_P2_DIS_32PSK_4_5 0xf2b300f0
+#define FSTV0910_P2_DIS_32PSK_4_5 0xf2b340f0
#define FSTV0910_P2_DIS_32PSK_3_4 0xf2b3000f
/* P2_MODCODLST4 */
#define RSTV0910_P2_MODCODLST4 0xf2b4
-#define FSTV0910_P2_DUMMYPL_PILOT 0xf2b40080
-#define FSTV0910_P2_DUMMYPL_NOPILOT 0xf2b40040
-#define FSTV0910_P2_DIS_16PSK_9_10 0xf2b40030
+#define FSTV0910_P2_DUMMYPL_PILOT 0xf2b47080
+#define FSTV0910_P2_DUMMYPL_NOPILOT 0xf2b46040
+#define FSTV0910_P2_DIS_16PSK_9_10 0xf2b44030
#define FSTV0910_P2_DIS_16PSK_8_9 0xf2b4000f
/* P2_MODCODLST5 */
#define RSTV0910_P2_MODCODLST5 0xf2b5
-#define FSTV0910_P2_DIS_16PSK_5_6 0xf2b500f0
+#define FSTV0910_P2_DIS_16PSK_5_6 0xf2b540f0
#define FSTV0910_P2_DIS_16PSK_4_5 0xf2b5000f
/* P2_MODCODLST6 */
#define RSTV0910_P2_MODCODLST6 0xf2b6
-#define FSTV0910_P2_DIS_16PSK_3_4 0xf2b600f0
+#define FSTV0910_P2_DIS_16PSK_3_4 0xf2b640f0
#define FSTV0910_P2_DIS_16PSK_2_3 0xf2b6000f
/* P2_MODCODLST7 */
#define RSTV0910_P2_MODCODLST7 0xf2b7
-#define FSTV0910_P2_MODCOD_NNOSFILTER 0xf2b70080
-#define FSTV0910_P2_DIS_8PSK_9_10 0xf2b70030
+#define FSTV0910_P2_MODCOD_NNOSFILTER 0xf2b77080
+#define FSTV0910_P2_DIS_8PSK_9_10 0xf2b74030
#define FSTV0910_P2_DIS_8PSK_8_9 0xf2b7000f
/* P2_MODCODLST8 */
#define RSTV0910_P2_MODCODLST8 0xf2b8
-#define FSTV0910_P2_DIS_8PSK_5_6 0xf2b800f0
+#define FSTV0910_P2_DIS_8PSK_5_6 0xf2b840f0
#define FSTV0910_P2_DIS_8PSK_3_4 0xf2b8000f
/* P2_MODCODLST9 */
#define RSTV0910_P2_MODCODLST9 0xf2b9
-#define FSTV0910_P2_DIS_8PSK_2_3 0xf2b900f0
+#define FSTV0910_P2_DIS_8PSK_2_3 0xf2b940f0
#define FSTV0910_P2_DIS_8PSK_3_5 0xf2b9000f
/* P2_MODCODLSTA */
#define RSTV0910_P2_MODCODLSTA 0xf2ba
-#define FSTV0910_P2_NOSFILTER_LIMITE 0xf2ba0080
-#define FSTV0910_P2_DIS_QPSK_9_10 0xf2ba0030
+#define FSTV0910_P2_NOSFILTER_LIMITE 0xf2ba7080
+#define FSTV0910_P2_DIS_QPSK_9_10 0xf2ba4030
#define FSTV0910_P2_DIS_QPSK_8_9 0xf2ba000f
/* P2_MODCODLSTB */
#define RSTV0910_P2_MODCODLSTB 0xf2bb
-#define FSTV0910_P2_DIS_QPSK_5_6 0xf2bb00f0
+#define FSTV0910_P2_DIS_QPSK_5_6 0xf2bb40f0
#define FSTV0910_P2_DIS_QPSK_4_5 0xf2bb000f
/* P2_MODCODLSTC */
#define RSTV0910_P2_MODCODLSTC 0xf2bc
-#define FSTV0910_P2_DIS_QPSK_3_4 0xf2bc00f0
+#define FSTV0910_P2_DIS_QPSK_3_4 0xf2bc40f0
#define FSTV0910_P2_DIS_QPSK_2_3 0xf2bc000f
/* P2_MODCODLSTD */
#define RSTV0910_P2_MODCODLSTD 0xf2bd
-#define FSTV0910_P2_DIS_QPSK_3_5 0xf2bd00f0
+#define FSTV0910_P2_DIS_QPSK_3_5 0xf2bd40f0
#define FSTV0910_P2_DIS_QPSK_1_2 0xf2bd000f
/* P2_MODCODLSTE */
#define RSTV0910_P2_MODCODLSTE 0xf2be
-#define FSTV0910_P2_DIS_QPSK_2_5 0xf2be00f0
+#define FSTV0910_P2_DIS_QPSK_2_5 0xf2be40f0
#define FSTV0910_P2_DIS_QPSK_1_3 0xf2be000f
/* P2_MODCODLSTF */
#define RSTV0910_P2_MODCODLSTF 0xf2bf
-#define FSTV0910_P2_DIS_QPSK_1_4 0xf2bf00f0
-#define FSTV0910_P2_DEMOD_INVMODLST 0xf2bf0008
-#define FSTV0910_P2_DEMODOUT_ENABLE 0xf2bf0004
-#define FSTV0910_P2_DDEMOD_NSET 0xf2bf0002
+#define FSTV0910_P2_DIS_QPSK_1_4 0xf2bf40f0
+#define FSTV0910_P2_DEMOD_INVMODLST 0xf2bf3008
+#define FSTV0910_P2_DEMODOUT_ENABLE 0xf2bf2004
+#define FSTV0910_P2_DDEMOD_NSET 0xf2bf1002
#define FSTV0910_P2_MODCOD_NSTOCK 0xf2bf0001
/* P2_GAUSSR0 */
#define RSTV0910_P2_GAUSSR0 0xf2c0
-#define FSTV0910_P2_EN_CCIMODE 0xf2c00080
+#define FSTV0910_P2_EN_CCIMODE 0xf2c07080
#define FSTV0910_P2_R0_GAUSSIEN 0xf2c0007f
/* P2_CCIR0 */
#define RSTV0910_P2_CCIR0 0xf2c1
-#define FSTV0910_P2_CCIDETECT_PLHONLY 0xf2c10080
+#define FSTV0910_P2_CCIDETECT_PLHONLY 0xf2c17080
#define FSTV0910_P2_R0_CCI 0xf2c1007f
/* P2_CCIQUANT */
#define RSTV0910_P2_CCIQUANT 0xf2c2
-#define FSTV0910_P2_CCI_BETA 0xf2c200e0
+#define FSTV0910_P2_CCI_BETA 0xf2c250e0
#define FSTV0910_P2_CCI_QUANT 0xf2c2001f
/* P2_CCITHRES */
@@ -1304,24 +1304,24 @@
/* P2_DSTATUS4 */
#define RSTV0910_P2_DSTATUS4 0xf2c5
-#define FSTV0910_P2_RAINFADE_DETECT 0xf2c50080
-#define FSTV0910_P2_NOTHRES2_FAIL 0xf2c50040
-#define FSTV0910_P2_NOTHRES1_FAIL 0xf2c50020
-#define FSTV0910_P2_DMDPROG_ERROR 0xf2c50004
-#define FSTV0910_P2_CSTENV_DETECT 0xf2c50002
+#define FSTV0910_P2_RAINFADE_DETECT 0xf2c57080
+#define FSTV0910_P2_NOTHRES2_FAIL 0xf2c56040
+#define FSTV0910_P2_NOTHRES1_FAIL 0xf2c55020
+#define FSTV0910_P2_DMDPROG_ERROR 0xf2c52004
+#define FSTV0910_P2_CSTENV_DETECT 0xf2c51002
#define FSTV0910_P2_DETECTION_TRIAX 0xf2c50001
/* P2_DMDRESCFG */
#define RSTV0910_P2_DMDRESCFG 0xf2c6
-#define FSTV0910_P2_DMDRES_RESET 0xf2c60080
-#define FSTV0910_P2_DMDRES_STRALL 0xf2c60008
-#define FSTV0910_P2_DMDRES_NEWONLY 0xf2c60004
-#define FSTV0910_P2_DMDRES_NOSTORE 0xf2c60002
+#define FSTV0910_P2_DMDRES_RESET 0xf2c67080
+#define FSTV0910_P2_DMDRES_STRALL 0xf2c63008
+#define FSTV0910_P2_DMDRES_NEWONLY 0xf2c62004
+#define FSTV0910_P2_DMDRES_NOSTORE 0xf2c61002
/* P2_DMDRESADR */
#define RSTV0910_P2_DMDRESADR 0xf2c7
-#define FSTV0910_P2_DMDRES_VALIDCFR 0xf2c70040
-#define FSTV0910_P2_DMDRES_MEMFULL 0xf2c70030
+#define FSTV0910_P2_DMDRES_VALIDCFR 0xf2c76040
+#define FSTV0910_P2_DMDRES_MEMFULL 0xf2c74030
#define FSTV0910_P2_DMDRES_RESNBR 0xf2c7000f
/* P2_DMDRESDATA7 */
@@ -1390,29 +1390,29 @@
/* P2_FFECFG */
#define RSTV0910_P2_FFECFG 0xf2d8
-#define FSTV0910_P2_EQUALFFE_ON 0xf2d80040
-#define FSTV0910_P2_EQUAL_USEDSYMB 0xf2d80030
+#define FSTV0910_P2_EQUALFFE_ON 0xf2d86040
+#define FSTV0910_P2_EQUAL_USEDSYMB 0xf2d84030
#define FSTV0910_P2_MU_EQUALFFE 0xf2d80007
/* P2_TNRCFG2 */
#define RSTV0910_P2_TNRCFG2 0xf2e1
-#define FSTV0910_P2_TUN_IQSWAP 0xf2e10080
+#define FSTV0910_P2_TUN_IQSWAP 0xf2e17080
/* P2_SMAPCOEF7 */
#define RSTV0910_P2_SMAPCOEF7 0xf300
-#define FSTV0910_P2_DIS_QSCALE 0xf3000080
+#define FSTV0910_P2_DIS_QSCALE 0xf3007080
#define FSTV0910_P2_SMAPCOEF_Q_LLR12 0xf300017f
/* P2_SMAPCOEF6 */
#define RSTV0910_P2_SMAPCOEF6 0xf301
-#define FSTV0910_P2_DIS_AGC2SCALE 0xf3010080
-#define FSTV0910_P2_ADJ_8PSKLLR1 0xf3010004
-#define FSTV0910_P2_OLD_8PSKLLR1 0xf3010002
+#define FSTV0910_P2_DIS_AGC2SCALE 0xf3017080
+#define FSTV0910_P2_ADJ_8PSKLLR1 0xf3012004
+#define FSTV0910_P2_OLD_8PSKLLR1 0xf3011002
#define FSTV0910_P2_DIS_AB8PSK 0xf3010001
/* P2_SMAPCOEF5 */
#define RSTV0910_P2_SMAPCOEF5 0xf302
-#define FSTV0910_P2_DIS_8SCALE 0xf3020080
+#define FSTV0910_P2_DIS_8SCALE 0xf3027080
#define FSTV0910_P2_SMAPCOEF_8P_LLR23 0xf302017f
/* P2_SMAPCOEF4 */
@@ -1425,17 +1425,17 @@
/* P2_SMAPCOEF2 */
#define RSTV0910_P2_SMAPCOEF2 0xf305
-#define FSTV0910_P2_SMAPCOEF_32APSK_R2R3 0xf30501f0
+#define FSTV0910_P2_SMAPCOEF_32APSK_R2R3 0xf30541f0
#define FSTV0910_P2_SMAPCOEF_32APSK_LLR2 0xf305010f
/* P2_SMAPCOEF1 */
#define RSTV0910_P2_SMAPCOEF1 0xf306
-#define FSTV0910_P2_DIS_16SCALE 0xf3060080
+#define FSTV0910_P2_DIS_16SCALE 0xf3067080
#define FSTV0910_P2_SMAPCOEF_32_LLR34 0xf306017f
/* P2_SMAPCOEF0 */
#define RSTV0910_P2_SMAPCOEF0 0xf307
-#define FSTV0910_P2_DIS_32SCALE 0xf3070080
+#define FSTV0910_P2_DIS_32SCALE 0xf3077080
#define FSTV0910_P2_SMAPCOEF_32_LLR15 0xf307017f
/* P2_NOSTHRES1 */
@@ -1452,20 +1452,20 @@
/* P2_RAINFADE */
#define RSTV0910_P2_RAINFADE 0xf30c
-#define FSTV0910_P2_NOSTHRES_DATAT 0xf30c0080
-#define FSTV0910_P2_RAINFADE_CNLIMIT 0xf30c0070
+#define FSTV0910_P2_NOSTHRES_DATAT 0xf30c7080
+#define FSTV0910_P2_RAINFADE_CNLIMIT 0xf30c4070
#define FSTV0910_P2_RAINFADE_TIMEOUT 0xf30c0007
/* P2_NOSRAMCFG */
#define RSTV0910_P2_NOSRAMCFG 0xf30d
-#define FSTV0910_P2_NOSRAM_ACTIVATION 0xf30d0030
-#define FSTV0910_P2_NOSRAM_CNRONLY 0xf30d0008
+#define FSTV0910_P2_NOSRAM_ACTIVATION 0xf30d4030
+#define FSTV0910_P2_NOSRAM_CNRONLY 0xf30d3008
#define FSTV0910_P2_NOSRAM_LGNCNR1 0xf30d0007
/* P2_NOSRAMPOS */
#define RSTV0910_P2_NOSRAMPOS 0xf30e
-#define FSTV0910_P2_NOSRAM_LGNCNR0 0xf30e00f0
-#define FSTV0910_P2_NOSRAM_VALIDE 0xf30e0004
+#define FSTV0910_P2_NOSRAM_LGNCNR0 0xf30e40f0
+#define FSTV0910_P2_NOSRAM_VALIDE 0xf30e2004
#define FSTV0910_P2_NOSRAM_CNRVAL1 0xf30e0003
/* P2_NOSRAMVAL */
@@ -1494,16 +1494,16 @@
/* P2_VITSCALE */
#define RSTV0910_P2_VITSCALE 0xf332
-#define FSTV0910_P2_NVTH_NOSRANGE 0xf3320080
-#define FSTV0910_P2_VERROR_MAXMODE 0xf3320040
-#define FSTV0910_P2_NSLOWSN_LOCKED 0xf3320008
-#define FSTV0910_P2_DIS_RSFLOCK 0xf3320002
+#define FSTV0910_P2_NVTH_NOSRANGE 0xf3327080
+#define FSTV0910_P2_VERROR_MAXMODE 0xf3326040
+#define FSTV0910_P2_NSLOWSN_LOCKED 0xf3323008
+#define FSTV0910_P2_DIS_RSFLOCK 0xf3321002
/* P2_FECM */
#define RSTV0910_P2_FECM 0xf333
-#define FSTV0910_P2_DSS_DVB 0xf3330080
-#define FSTV0910_P2_DSS_SRCH 0xf3330010
-#define FSTV0910_P2_SYNCVIT 0xf3330002
+#define FSTV0910_P2_DSS_DVB 0xf3337080
+#define FSTV0910_P2_DSS_SRCH 0xf3334010
+#define FSTV0910_P2_SYNCVIT 0xf3331002
#define FSTV0910_P2_IQINV 0xf3330001
/* P2_VTH12 */
@@ -1540,26 +1540,26 @@
/* P2_PRVIT */
#define RSTV0910_P2_PRVIT 0xf33c
-#define FSTV0910_P2_DIS_VTHLOCK 0xf33c0040
-#define FSTV0910_P2_E7_8VIT 0xf33c0020
-#define FSTV0910_P2_E6_7VIT 0xf33c0010
-#define FSTV0910_P2_E5_6VIT 0xf33c0008
-#define FSTV0910_P2_E3_4VIT 0xf33c0004
-#define FSTV0910_P2_E2_3VIT 0xf33c0002
+#define FSTV0910_P2_DIS_VTHLOCK 0xf33c6040
+#define FSTV0910_P2_E7_8VIT 0xf33c5020
+#define FSTV0910_P2_E6_7VIT 0xf33c4010
+#define FSTV0910_P2_E5_6VIT 0xf33c3008
+#define FSTV0910_P2_E3_4VIT 0xf33c2004
+#define FSTV0910_P2_E2_3VIT 0xf33c1002
#define FSTV0910_P2_E1_2VIT 0xf33c0001
/* P2_VAVSRVIT */
#define RSTV0910_P2_VAVSRVIT 0xf33d
-#define FSTV0910_P2_AMVIT 0xf33d0080
-#define FSTV0910_P2_FROZENVIT 0xf33d0040
-#define FSTV0910_P2_SNVIT 0xf33d0030
-#define FSTV0910_P2_TOVVIT 0xf33d000c
+#define FSTV0910_P2_AMVIT 0xf33d7080
+#define FSTV0910_P2_FROZENVIT 0xf33d6040
+#define FSTV0910_P2_SNVIT 0xf33d4030
+#define FSTV0910_P2_TOVVIT 0xf33d200c
#define FSTV0910_P2_HYPVIT 0xf33d0003
/* P2_VSTATUSVIT */
#define RSTV0910_P2_VSTATUSVIT 0xf33e
-#define FSTV0910_P2_PRFVIT 0xf33e0010
-#define FSTV0910_P2_LOCKEDVIT 0xf33e0008
+#define FSTV0910_P2_PRFVIT 0xf33e4010
+#define FSTV0910_P2_LOCKEDVIT 0xf33e3008
/* P2_VTHINUSE */
#define RSTV0910_P2_VTHINUSE 0xf33f
@@ -1599,32 +1599,32 @@
/* P2_PDELCTRL0 */
#define RSTV0910_P2_PDELCTRL0 0xf34f
-#define FSTV0910_P2_ISIOBS_MODE 0xf34f0030
+#define FSTV0910_P2_ISIOBS_MODE 0xf34f4030
/* P2_PDELCTRL1 */
#define RSTV0910_P2_PDELCTRL1 0xf350
-#define FSTV0910_P2_INV_MISMASK 0xf3500080
-#define FSTV0910_P2_FILTER_EN 0xf3500020
-#define FSTV0910_P2_HYSTEN 0xf3500008
-#define FSTV0910_P2_HYSTSWRST 0xf3500004
-#define FSTV0910_P2_EN_MIS00 0xf3500002
+#define FSTV0910_P2_INV_MISMASK 0xf3507080
+#define FSTV0910_P2_FILTER_EN 0xf3505020
+#define FSTV0910_P2_HYSTEN 0xf3503008
+#define FSTV0910_P2_HYSTSWRST 0xf3502004
+#define FSTV0910_P2_EN_MIS00 0xf3501002
#define FSTV0910_P2_ALGOSWRST 0xf3500001
/* P2_PDELCTRL2 */
#define RSTV0910_P2_PDELCTRL2 0xf351
-#define FSTV0910_P2_FORCE_CONTINUOUS 0xf3510080
-#define FSTV0910_P2_RESET_UPKO_COUNT 0xf3510040
-#define FSTV0910_P2_USER_PKTDELIN_NB 0xf3510020
-#define FSTV0910_P2_FRAME_MODE 0xf3510002
+#define FSTV0910_P2_FORCE_CONTINUOUS 0xf3517080
+#define FSTV0910_P2_RESET_UPKO_COUNT 0xf3516040
+#define FSTV0910_P2_USER_PKTDELIN_NB 0xf3515020
+#define FSTV0910_P2_FRAME_MODE 0xf3511002
/* P2_HYSTTHRESH */
#define RSTV0910_P2_HYSTTHRESH 0xf354
-#define FSTV0910_P2_DELIN_LOCKTHRES 0xf35400f0
+#define FSTV0910_P2_DELIN_LOCKTHRES 0xf35440f0
#define FSTV0910_P2_DELIN_UNLOCKTHRES 0xf354000f
/* P2_UPLCCST0 */
#define RSTV0910_P2_UPLCCST0 0xf358
-#define FSTV0910_P2_UPL_CST0 0xf35800f8
+#define FSTV0910_P2_UPL_CST0 0xf35830f8
#define FSTV0910_P2_UPL_MODE 0xf3580007
/* P2_ISIENTRY */
@@ -1673,16 +1673,16 @@
/* P2_PDELSTATUS1 */
#define RSTV0910_P2_PDELSTATUS1 0xf369
-#define FSTV0910_P2_PKTDELIN_DELOCK 0xf3690080
-#define FSTV0910_P2_SYNCDUPDFL_BADDFL 0xf3690040
-#define FSTV0910_P2_UNACCEPTED_STREAM 0xf3690010
-#define FSTV0910_P2_BCH_ERROR_FLAG 0xf3690008
-#define FSTV0910_P2_PKTDELIN_LOCK 0xf3690002
+#define FSTV0910_P2_PKTDELIN_DELOCK 0xf3697080
+#define FSTV0910_P2_SYNCDUPDFL_BADDFL 0xf3696040
+#define FSTV0910_P2_UNACCEPTED_STREAM 0xf3694010
+#define FSTV0910_P2_BCH_ERROR_FLAG 0xf3693008
+#define FSTV0910_P2_PKTDELIN_LOCK 0xf3691002
#define FSTV0910_P2_FIRST_LOCK 0xf3690001
/* P2_PDELSTATUS2 */
#define RSTV0910_P2_PDELSTATUS2 0xf36a
-#define FSTV0910_P2_FRAME_MODCOD 0xf36a007c
+#define FSTV0910_P2_FRAME_MODCOD 0xf36a207c
#define FSTV0910_P2_FRAME_TYPE 0xf36a0003
/* P2_BBFCRCKO1 */
@@ -1703,92 +1703,92 @@
/* P2_PDELCTRL3 */
#define RSTV0910_P2_PDELCTRL3 0xf36f
-#define FSTV0910_P2_NOFIFO_BCHERR 0xf36f0020
-#define FSTV0910_P2_PKTDELIN_DELACMERR 0xf36f0010
+#define FSTV0910_P2_NOFIFO_BCHERR 0xf36f5020
+#define FSTV0910_P2_PKTDELIN_DELACMERR 0xf36f4010
/* P2_TSSTATEM */
#define RSTV0910_P2_TSSTATEM 0xf370
-#define FSTV0910_P2_TSDIL_ON 0xf3700080
-#define FSTV0910_P2_TSRS_ON 0xf3700020
-#define FSTV0910_P2_TSDESCRAMB_ON 0xf3700010
-#define FSTV0910_P2_TSFRAME_MODE 0xf3700008
-#define FSTV0910_P2_TS_DISABLE 0xf3700004
-#define FSTV0910_P2_TSACM_MODE 0xf3700002
+#define FSTV0910_P2_TSDIL_ON 0xf3707080
+#define FSTV0910_P2_TSRS_ON 0xf3705020
+#define FSTV0910_P2_TSDESCRAMB_ON 0xf3704010
+#define FSTV0910_P2_TSFRAME_MODE 0xf3703008
+#define FSTV0910_P2_TS_DISABLE 0xf3702004
+#define FSTV0910_P2_TSACM_MODE 0xf3701002
#define FSTV0910_P2_TSOUT_NOSYNC 0xf3700001
/* P2_TSSTATEL */
#define RSTV0910_P2_TSSTATEL 0xf371
-#define FSTV0910_P2_TSNOSYNCBYTE 0xf3710080
-#define FSTV0910_P2_TSPARITY_ON 0xf3710040
-#define FSTV0910_P2_TSISSYI_ON 0xf3710008
-#define FSTV0910_P2_TSNPD_ON 0xf3710004
-#define FSTV0910_P2_TSCRC8_ON 0xf3710002
+#define FSTV0910_P2_TSNOSYNCBYTE 0xf3717080
+#define FSTV0910_P2_TSPARITY_ON 0xf3716040
+#define FSTV0910_P2_TSISSYI_ON 0xf3713008
+#define FSTV0910_P2_TSNPD_ON 0xf3712004
+#define FSTV0910_P2_TSCRC8_ON 0xf3711002
#define FSTV0910_P2_TSDSS_PACKET 0xf3710001
/* P2_TSCFGH */
#define RSTV0910_P2_TSCFGH 0xf372
-#define FSTV0910_P2_TSFIFO_DVBCI 0xf3720080
-#define FSTV0910_P2_TSFIFO_SERIAL 0xf3720040
-#define FSTV0910_P2_TSFIFO_TEIUPDATE 0xf3720020
-#define FSTV0910_P2_TSFIFO_DUTY50 0xf3720010
-#define FSTV0910_P2_TSFIFO_HSGNLOUT 0xf3720008
-#define FSTV0910_P2_TSFIFO_ERRMODE 0xf3720006
+#define FSTV0910_P2_TSFIFO_DVBCI 0xf3727080
+#define FSTV0910_P2_TSFIFO_SERIAL 0xf3726040
+#define FSTV0910_P2_TSFIFO_TEIUPDATE 0xf3725020
+#define FSTV0910_P2_TSFIFO_DUTY50 0xf3724010
+#define FSTV0910_P2_TSFIFO_HSGNLOUT 0xf3723008
+#define FSTV0910_P2_TSFIFO_ERRMODE 0xf3721006
#define FSTV0910_P2_RST_HWARE 0xf3720001
/* P2_TSCFGM */
#define RSTV0910_P2_TSCFGM 0xf373
-#define FSTV0910_P2_TSFIFO_MANSPEED 0xf37300c0
-#define FSTV0910_P2_TSFIFO_PERMDATA 0xf3730020
-#define FSTV0910_P2_TSFIFO_NONEWSGNL 0xf3730010
+#define FSTV0910_P2_TSFIFO_MANSPEED 0xf37360c0
+#define FSTV0910_P2_TSFIFO_PERMDATA 0xf3735020
+#define FSTV0910_P2_TSFIFO_NONEWSGNL 0xf3734010
#define FSTV0910_P2_TSFIFO_INVDATA 0xf3730001
/* P2_TSCFGL */
#define RSTV0910_P2_TSCFGL 0xf374
-#define FSTV0910_P2_TSFIFO_BCLKDEL1CK 0xf37400c0
-#define FSTV0910_P2_BCHERROR_MODE 0xf3740030
-#define FSTV0910_P2_TSFIFO_NSGNL2DATA 0xf3740008
-#define FSTV0910_P2_TSFIFO_EMBINDVB 0xf3740004
+#define FSTV0910_P2_TSFIFO_BCLKDEL1CK 0xf37460c0
+#define FSTV0910_P2_BCHERROR_MODE 0xf3744030
+#define FSTV0910_P2_TSFIFO_NSGNL2DATA 0xf3743008
+#define FSTV0910_P2_TSFIFO_EMBINDVB 0xf3742004
#define FSTV0910_P2_TSFIFO_BITSPEED 0xf3740003
/* P2_TSSYNC */
#define RSTV0910_P2_TSSYNC 0xf375
-#define FSTV0910_P2_TSFIFO_SYNCMODE 0xf3750018
+#define FSTV0910_P2_TSFIFO_SYNCMODE 0xf3753018
/* P2_TSINSDELH */
#define RSTV0910_P2_TSINSDELH 0xf376
-#define FSTV0910_P2_TSDEL_SYNCBYTE 0xf3760080
-#define FSTV0910_P2_TSDEL_XXHEADER 0xf3760040
-#define FSTV0910_P2_TSDEL_DATAFIELD 0xf3760010
-#define FSTV0910_P2_TSINSDEL_RSPARITY 0xf3760002
+#define FSTV0910_P2_TSDEL_SYNCBYTE 0xf3767080
+#define FSTV0910_P2_TSDEL_XXHEADER 0xf3766040
+#define FSTV0910_P2_TSDEL_DATAFIELD 0xf3764010
+#define FSTV0910_P2_TSINSDEL_RSPARITY 0xf3761002
#define FSTV0910_P2_TSINSDEL_CRC8 0xf3760001
/* P2_TSINSDELM */
#define RSTV0910_P2_TSINSDELM 0xf377
-#define FSTV0910_P2_TSINS_EMODCOD 0xf3770010
-#define FSTV0910_P2_TSINS_TOKEN 0xf3770008
-#define FSTV0910_P2_TSINS_XXXERR 0xf3770004
-#define FSTV0910_P2_TSINS_MATYPE 0xf3770002
+#define FSTV0910_P2_TSINS_EMODCOD 0xf3774010
+#define FSTV0910_P2_TSINS_TOKEN 0xf3773008
+#define FSTV0910_P2_TSINS_XXXERR 0xf3772004
+#define FSTV0910_P2_TSINS_MATYPE 0xf3771002
#define FSTV0910_P2_TSINS_UPL 0xf3770001
/* P2_TSINSDELL */
#define RSTV0910_P2_TSINSDELL 0xf378
-#define FSTV0910_P2_TSINS_DFL 0xf3780080
-#define FSTV0910_P2_TSINS_SYNCD 0xf3780040
-#define FSTV0910_P2_TSINS_BLOCLEN 0xf3780020
-#define FSTV0910_P2_TSINS_SIGPCOUNT 0xf3780010
-#define FSTV0910_P2_TSINS_FIFO 0xf3780008
-#define FSTV0910_P2_TSINS_REALPACK 0xf3780004
-#define FSTV0910_P2_TSINS_TSCONFIG 0xf3780002
+#define FSTV0910_P2_TSINS_DFL 0xf3787080
+#define FSTV0910_P2_TSINS_SYNCD 0xf3786040
+#define FSTV0910_P2_TSINS_BLOCLEN 0xf3785020
+#define FSTV0910_P2_TSINS_SIGPCOUNT 0xf3784010
+#define FSTV0910_P2_TSINS_FIFO 0xf3783008
+#define FSTV0910_P2_TSINS_REALPACK 0xf3782004
+#define FSTV0910_P2_TSINS_TSCONFIG 0xf3781002
#define FSTV0910_P2_TSINS_LATENCY 0xf3780001
/* P2_TSDIVN */
#define RSTV0910_P2_TSDIVN 0xf379
-#define FSTV0910_P2_TSFIFO_SPEEDMODE 0xf37900c0
+#define FSTV0910_P2_TSFIFO_SPEEDMODE 0xf37960c0
#define FSTV0910_P2_TSFIFO_RISEOK 0xf3790007
/* P2_TSCFG4 */
#define RSTV0910_P2_TSCFG4 0xf37a
-#define FSTV0910_P2_TSFIFO_TSSPEEDMODE 0xf37a00c0
+#define FSTV0910_P2_TSFIFO_TSSPEEDMODE 0xf37a60c0
/* P2_TSSPEED */
#define RSTV0910_P2_TSSPEED 0xf380
@@ -1796,18 +1796,18 @@
/* P2_TSSTATUS */
#define RSTV0910_P2_TSSTATUS 0xf381
-#define FSTV0910_P2_TSFIFO_LINEOK 0xf3810080
-#define FSTV0910_P2_TSFIFO_ERROR 0xf3810040
-#define FSTV0910_P2_TSFIFO_NOSYNC 0xf3810010
-#define FSTV0910_P2_TSREGUL_ERROR 0xf3810004
+#define FSTV0910_P2_TSFIFO_LINEOK 0xf3817080
+#define FSTV0910_P2_TSFIFO_ERROR 0xf3816040
+#define FSTV0910_P2_TSFIFO_NOSYNC 0xf3814010
+#define FSTV0910_P2_TSREGUL_ERROR 0xf3812004
#define FSTV0910_P2_DIL_READY 0xf3810001
/* P2_TSSTATUS2 */
#define RSTV0910_P2_TSSTATUS2 0xf382
-#define FSTV0910_P2_TSFIFO_DEMODSEL 0xf3820080
-#define FSTV0910_P2_TSFIFOSPEED_STORE 0xf3820040
-#define FSTV0910_P2_DILXX_RESET 0xf3820020
-#define FSTV0910_P2_SCRAMBDETECT 0xf3820002
+#define FSTV0910_P2_TSFIFO_DEMODSEL 0xf3827080
+#define FSTV0910_P2_TSFIFOSPEED_STORE 0xf3826040
+#define FSTV0910_P2_DILXX_RESET 0xf3825020
+#define FSTV0910_P2_SCRAMBDETECT 0xf3821002
/* P2_TSBITRATE1 */
#define RSTV0910_P2_TSBITRATE1 0xf383
@@ -1819,7 +1819,7 @@
/* P2_TSPACKLEN1 */
#define RSTV0910_P2_TSPACKLEN1 0xf385
-#define FSTV0910_P2_TSFIFO_PACKCPT 0xf38500e0
+#define FSTV0910_P2_TSFIFO_PACKCPT 0xf38550e0
/* P2_TSDLY2 */
#define RSTV0910_P2_TSDLY2 0xf389
@@ -1839,8 +1839,8 @@
/* P2_TSBUFSTAT2 */
#define RSTV0910_P2_TSBUFSTAT2 0xf38d
-#define FSTV0910_P2_TSISCR_3BYTES 0xf38d0080
-#define FSTV0910_P2_TSISCR_NEWDATA 0xf38d0040
+#define FSTV0910_P2_TSISCR_3BYTES 0xf38d7080
+#define FSTV0910_P2_TSISCR_NEWDATA 0xf38d6040
#define FSTV0910_P2_TSISCR_BUFSTAT2 0xf38d003f
/* P2_TSBUFSTAT1 */
@@ -1853,13 +1853,13 @@
/* P2_TSDEBUGL */
#define RSTV0910_P2_TSDEBUGL 0xf391
-#define FSTV0910_P2_TSFIFO_ERROR_EVNT 0xf3910004
+#define FSTV0910_P2_TSFIFO_ERROR_EVNT 0xf3912004
#define FSTV0910_P2_TSFIFO_OVERFLOWM 0xf3910001
/* P2_TSDLYSET2 */
#define RSTV0910_P2_TSDLYSET2 0xf392
-#define FSTV0910_P2_SOFFIFO_OFFSET 0xf39200c0
-#define FSTV0910_P2_HYSTERESIS_THRESHOLD 0xf3920030
+#define FSTV0910_P2_SOFFIFO_OFFSET 0xf39260c0
+#define FSTV0910_P2_HYSTERESIS_THRESHOLD 0xf3924030
#define FSTV0910_P2_SOFFIFO_SYMBOFFS2 0xf392000f
/* P2_TSDLYSET1 */
@@ -1872,12 +1872,12 @@
/* P2_ERRCTRL1 */
#define RSTV0910_P2_ERRCTRL1 0xf398
-#define FSTV0910_P2_ERR_SOURCE1 0xf39800f0
+#define FSTV0910_P2_ERR_SOURCE1 0xf39840f0
#define FSTV0910_P2_NUM_EVENT1 0xf3980007
/* P2_ERRCNT12 */
#define RSTV0910_P2_ERRCNT12 0xf399
-#define FSTV0910_P2_ERRCNT1_OLDVALUE 0xf3990080
+#define FSTV0910_P2_ERRCNT1_OLDVALUE 0xf3997080
#define FSTV0910_P2_ERR_CNT12 0xf399007f
/* P2_ERRCNT11 */
@@ -1890,12 +1890,12 @@
/* P2_ERRCTRL2 */
#define RSTV0910_P2_ERRCTRL2 0xf39c
-#define FSTV0910_P2_ERR_SOURCE2 0xf39c00f0
+#define FSTV0910_P2_ERR_SOURCE2 0xf39c40f0
#define FSTV0910_P2_NUM_EVENT2 0xf39c0007
/* P2_ERRCNT22 */
#define RSTV0910_P2_ERRCNT22 0xf39d
-#define FSTV0910_P2_ERRCNT2_OLDVALUE 0xf39d0080
+#define FSTV0910_P2_ERRCNT2_OLDVALUE 0xf39d7080
#define FSTV0910_P2_ERR_CNT22 0xf39d007f
/* P2_ERRCNT21 */
@@ -1908,39 +1908,39 @@
/* P2_FECSPY */
#define RSTV0910_P2_FECSPY 0xf3a0
-#define FSTV0910_P2_SPY_ENABLE 0xf3a00080
-#define FSTV0910_P2_NO_SYNCBYTE 0xf3a00040
-#define FSTV0910_P2_SERIAL_MODE 0xf3a00020
-#define FSTV0910_P2_UNUSUAL_PACKET 0xf3a00010
-#define FSTV0910_P2_BERMETER_DATAMODE 0xf3a0000c
-#define FSTV0910_P2_BERMETER_LMODE 0xf3a00002
+#define FSTV0910_P2_SPY_ENABLE 0xf3a07080
+#define FSTV0910_P2_NO_SYNCBYTE 0xf3a06040
+#define FSTV0910_P2_SERIAL_MODE 0xf3a05020
+#define FSTV0910_P2_UNUSUAL_PACKET 0xf3a04010
+#define FSTV0910_P2_BERMETER_DATAMODE 0xf3a0200c
+#define FSTV0910_P2_BERMETER_LMODE 0xf3a01002
#define FSTV0910_P2_BERMETER_RESET 0xf3a00001
/* P2_FSPYCFG */
#define RSTV0910_P2_FSPYCFG 0xf3a1
-#define FSTV0910_P2_FECSPY_INPUT 0xf3a100c0
-#define FSTV0910_P2_RST_ON_ERROR 0xf3a10020
-#define FSTV0910_P2_ONE_SHOT 0xf3a10010
-#define FSTV0910_P2_I2C_MODE 0xf3a1000c
+#define FSTV0910_P2_FECSPY_INPUT 0xf3a160c0
+#define FSTV0910_P2_RST_ON_ERROR 0xf3a15020
+#define FSTV0910_P2_ONE_SHOT 0xf3a14010
+#define FSTV0910_P2_I2C_MODE 0xf3a1200c
#define FSTV0910_P2_SPY_HYSTERESIS 0xf3a10003
/* P2_FSPYDATA */
#define RSTV0910_P2_FSPYDATA 0xf3a2
-#define FSTV0910_P2_SPY_STUFFING 0xf3a20080
-#define FSTV0910_P2_SPY_CNULLPKT 0xf3a20020
+#define FSTV0910_P2_SPY_STUFFING 0xf3a27080
+#define FSTV0910_P2_SPY_CNULLPKT 0xf3a25020
#define FSTV0910_P2_SPY_OUTDATA_MODE 0xf3a2001f
/* P2_FSPYOUT */
#define RSTV0910_P2_FSPYOUT 0xf3a3
-#define FSTV0910_P2_FSPY_DIRECT 0xf3a30080
+#define FSTV0910_P2_FSPY_DIRECT 0xf3a37080
#define FSTV0910_P2_STUFF_MODE 0xf3a30007
/* P2_FSTATUS */
#define RSTV0910_P2_FSTATUS 0xf3a4
-#define FSTV0910_P2_SPY_ENDSIM 0xf3a40080
-#define FSTV0910_P2_VALID_SIM 0xf3a40040
-#define FSTV0910_P2_FOUND_SIGNAL 0xf3a40020
-#define FSTV0910_P2_DSS_SYNCBYTE 0xf3a40010
+#define FSTV0910_P2_SPY_ENDSIM 0xf3a47080
+#define FSTV0910_P2_VALID_SIM 0xf3a46040
+#define FSTV0910_P2_FOUND_SIGNAL 0xf3a45020
+#define FSTV0910_P2_DSS_SYNCBYTE 0xf3a44010
#define FSTV0910_P2_RESULT_STATE 0xf3a4000f
/* P2_FBERCPT4 */
@@ -1977,8 +1977,8 @@
/* P2_FSPYBER */
#define RSTV0910_P2_FSPYBER 0xf3b2
-#define FSTV0910_P2_FSPYBER_SYNCBYTE 0xf3b20010
-#define FSTV0910_P2_FSPYBER_UNSYNC 0xf3b20008
+#define FSTV0910_P2_FSPYBER_SYNCBYTE 0xf3b24010
+#define FSTV0910_P2_FSPYBER_UNSYNC 0xf3b23008
#define FSTV0910_P2_FSPYBER_CTIME 0xf3b20007
/* P2_SFERROR */
@@ -1987,60 +1987,60 @@
/* P2_SFECSTATUS */
#define RSTV0910_P2_SFECSTATUS 0xf3c3
-#define FSTV0910_P2_SFEC_ON 0xf3c30080
-#define FSTV0910_P2_SFEC_OFF 0xf3c30040
-#define FSTV0910_P2_LOCKEDSFEC 0xf3c30008
-#define FSTV0910_P2_SFEC_DELOCK 0xf3c30004
-#define FSTV0910_P2_SFEC_DEMODSEL 0xf3c30002
+#define FSTV0910_P2_SFEC_ON 0xf3c37080
+#define FSTV0910_P2_SFEC_OFF 0xf3c36040
+#define FSTV0910_P2_LOCKEDSFEC 0xf3c33008
+#define FSTV0910_P2_SFEC_DELOCK 0xf3c32004
+#define FSTV0910_P2_SFEC_DEMODSEL 0xf3c31002
#define FSTV0910_P2_SFEC_OVFON 0xf3c30001
/* P2_SFKDIV12 */
#define RSTV0910_P2_SFKDIV12 0xf3c4
-#define FSTV0910_P2_SFECKDIV12_MAN 0xf3c40080
+#define FSTV0910_P2_SFECKDIV12_MAN 0xf3c47080
/* P2_SFKDIV23 */
#define RSTV0910_P2_SFKDIV23 0xf3c5
-#define FSTV0910_P2_SFECKDIV23_MAN 0xf3c50080
+#define FSTV0910_P2_SFECKDIV23_MAN 0xf3c57080
/* P2_SFKDIV34 */
#define RSTV0910_P2_SFKDIV34 0xf3c6
-#define FSTV0910_P2_SFECKDIV34_MAN 0xf3c60080
+#define FSTV0910_P2_SFECKDIV34_MAN 0xf3c67080
/* P2_SFKDIV56 */
#define RSTV0910_P2_SFKDIV56 0xf3c7
-#define FSTV0910_P2_SFECKDIV56_MAN 0xf3c70080
+#define FSTV0910_P2_SFECKDIV56_MAN 0xf3c77080
/* P2_SFKDIV67 */
#define RSTV0910_P2_SFKDIV67 0xf3c8
-#define FSTV0910_P2_SFECKDIV67_MAN 0xf3c80080
+#define FSTV0910_P2_SFECKDIV67_MAN 0xf3c87080
/* P2_SFKDIV78 */
#define RSTV0910_P2_SFKDIV78 0xf3c9
-#define FSTV0910_P2_SFECKDIV78_MAN 0xf3c90080
+#define FSTV0910_P2_SFECKDIV78_MAN 0xf3c97080
/* P2_SFSTATUS */
#define RSTV0910_P2_SFSTATUS 0xf3cc
-#define FSTV0910_P2_SFEC_LINEOK 0xf3cc0080
-#define FSTV0910_P2_SFEC_ERROR 0xf3cc0040
-#define FSTV0910_P2_SFEC_DATA7 0xf3cc0020
-#define FSTV0910_P2_SFEC_PKTDNBRFAIL 0xf3cc0010
-#define FSTV0910_P2_TSSFEC_DEMODSEL 0xf3cc0008
-#define FSTV0910_P2_SFEC_NOSYNC 0xf3cc0004
-#define FSTV0910_P2_SFEC_UNREGULA 0xf3cc0002
+#define FSTV0910_P2_SFEC_LINEOK 0xf3cc7080
+#define FSTV0910_P2_SFEC_ERROR 0xf3cc6040
+#define FSTV0910_P2_SFEC_DATA7 0xf3cc5020
+#define FSTV0910_P2_SFEC_PKTDNBRFAIL 0xf3cc4010
+#define FSTV0910_P2_TSSFEC_DEMODSEL 0xf3cc3008
+#define FSTV0910_P2_SFEC_NOSYNC 0xf3cc2004
+#define FSTV0910_P2_SFEC_UNREGULA 0xf3cc1002
#define FSTV0910_P2_SFEC_READY 0xf3cc0001
/* P2_SFDLYSET2 */
#define RSTV0910_P2_SFDLYSET2 0xf3d0
-#define FSTV0910_P2_SFEC_DISABLE 0xf3d00002
+#define FSTV0910_P2_SFEC_DISABLE 0xf3d01002
/* P2_SFERRCTRL */
#define RSTV0910_P2_SFERRCTRL 0xf3d8
-#define FSTV0910_P2_SFEC_ERR_SOURCE 0xf3d800f0
+#define FSTV0910_P2_SFEC_ERR_SOURCE 0xf3d840f0
#define FSTV0910_P2_SFEC_NUM_EVENT 0xf3d80007
/* P2_SFERRCNT2 */
#define RSTV0910_P2_SFERRCNT2 0xf3d9
-#define FSTV0910_P2_SFERRC_OLDVALUE 0xf3d90080
+#define FSTV0910_P2_SFERRC_OLDVALUE 0xf3d97080
#define FSTV0910_P2_SFEC_ERR_CNT2 0xf3d9007f
/* P2_SFERRCNT1 */
@@ -2053,13 +2053,13 @@
/* P1_IQCONST */
#define RSTV0910_P1_IQCONST 0xf400
-#define FSTV0910_P1_CONSTEL_SELECT 0xf4000060
+#define FSTV0910_P1_CONSTEL_SELECT 0xf4005060
#define FSTV0910_P1_IQSYMB_SEL 0xf400001f
/* P1_NOSCFG */
#define RSTV0910_P1_NOSCFG 0xf401
-#define FSTV0910_P1_DUMMYPL_NOSDATA 0xf4010020
-#define FSTV0910_P1_NOSPLH_BETA 0xf4010018
+#define FSTV0910_P1_DUMMYPL_NOSDATA 0xf4015020
+#define FSTV0910_P1_NOSPLH_BETA 0xf4013018
#define FSTV0910_P1_NOSDATA_BETA 0xf4010007
/* P1_ISYMB */
@@ -2072,18 +2072,18 @@
/* P1_AGC1CFG */
#define RSTV0910_P1_AGC1CFG 0xf404
-#define FSTV0910_P1_DC_FROZEN 0xf4040080
-#define FSTV0910_P1_DC_CORRECT 0xf4040040
-#define FSTV0910_P1_AMM_FROZEN 0xf4040020
-#define FSTV0910_P1_AMM_CORRECT 0xf4040010
-#define FSTV0910_P1_QUAD_FROZEN 0xf4040008
-#define FSTV0910_P1_QUAD_CORRECT 0xf4040004
+#define FSTV0910_P1_DC_FROZEN 0xf4047080
+#define FSTV0910_P1_DC_CORRECT 0xf4046040
+#define FSTV0910_P1_AMM_FROZEN 0xf4045020
+#define FSTV0910_P1_AMM_CORRECT 0xf4044010
+#define FSTV0910_P1_QUAD_FROZEN 0xf4043008
+#define FSTV0910_P1_QUAD_CORRECT 0xf4042004
/* P1_AGC1CN */
#define RSTV0910_P1_AGC1CN 0xf406
-#define FSTV0910_P1_AGC1_LOCKED 0xf4060080
-#define FSTV0910_P1_AGC1_MINPOWER 0xf4060010
-#define FSTV0910_P1_AGCOUT_FAST 0xf4060008
+#define FSTV0910_P1_AGC1_LOCKED 0xf4067080
+#define FSTV0910_P1_AGC1_MINPOWER 0xf4064010
+#define FSTV0910_P1_AGCOUT_FAST 0xf4063008
#define FSTV0910_P1_AGCIQ_BETA 0xf4060007
/* P1_AGC1REF */
@@ -2124,50 +2124,50 @@
/* P1_DEMOD */
#define RSTV0910_P1_DEMOD 0xf410
-#define FSTV0910_P1_MANUALS2_ROLLOFF 0xf4100080
-#define FSTV0910_P1_SPECINV_CONTROL 0xf4100030
-#define FSTV0910_P1_MANUALSX_ROLLOFF 0xf4100004
+#define FSTV0910_P1_MANUALS2_ROLLOFF 0xf4107080
+#define FSTV0910_P1_SPECINV_CONTROL 0xf4104030
+#define FSTV0910_P1_MANUALSX_ROLLOFF 0xf4102004
#define FSTV0910_P1_ROLLOFF_CONTROL 0xf4100003
/* P1_DMDMODCOD */
#define RSTV0910_P1_DMDMODCOD 0xf411
-#define FSTV0910_P1_MANUAL_MODCOD 0xf4110080
-#define FSTV0910_P1_DEMOD_MODCOD 0xf411007c
+#define FSTV0910_P1_MANUAL_MODCOD 0xf4117080
+#define FSTV0910_P1_DEMOD_MODCOD 0xf411207c
#define FSTV0910_P1_DEMOD_TYPE 0xf4110003
/* P1_DSTATUS */
#define RSTV0910_P1_DSTATUS 0xf412
-#define FSTV0910_P1_CAR_LOCK 0xf4120080
-#define FSTV0910_P1_TMGLOCK_QUALITY 0xf4120060
-#define FSTV0910_P1_LOCK_DEFINITIF 0xf4120008
+#define FSTV0910_P1_CAR_LOCK 0xf4127080
+#define FSTV0910_P1_TMGLOCK_QUALITY 0xf4125060
+#define FSTV0910_P1_LOCK_DEFINITIF 0xf4123008
#define FSTV0910_P1_OVADC_DETECT 0xf4120001
/* P1_DSTATUS2 */
#define RSTV0910_P1_DSTATUS2 0xf413
-#define FSTV0910_P1_DEMOD_DELOCK 0xf4130080
-#define FSTV0910_P1_MODCODRQ_SYNCTAG 0xf4130020
-#define FSTV0910_P1_POLYPH_SATEVENT 0xf4130010
-#define FSTV0910_P1_AGC1_NOSIGNALACK 0xf4130008
-#define FSTV0910_P1_AGC2_OVERFLOW 0xf4130004
-#define FSTV0910_P1_CFR_OVERFLOW 0xf4130002
+#define FSTV0910_P1_DEMOD_DELOCK 0xf4137080
+#define FSTV0910_P1_MODCODRQ_SYNCTAG 0xf4135020
+#define FSTV0910_P1_POLYPH_SATEVENT 0xf4134010
+#define FSTV0910_P1_AGC1_NOSIGNALACK 0xf4133008
+#define FSTV0910_P1_AGC2_OVERFLOW 0xf4132004
+#define FSTV0910_P1_CFR_OVERFLOW 0xf4131002
#define FSTV0910_P1_GAMMA_OVERUNDER 0xf4130001
/* P1_DMDCFGMD */
#define RSTV0910_P1_DMDCFGMD 0xf414
-#define FSTV0910_P1_DVBS2_ENABLE 0xf4140080
-#define FSTV0910_P1_DVBS1_ENABLE 0xf4140040
-#define FSTV0910_P1_SCAN_ENABLE 0xf4140010
-#define FSTV0910_P1_CFR_AUTOSCAN 0xf4140008
+#define FSTV0910_P1_DVBS2_ENABLE 0xf4147080
+#define FSTV0910_P1_DVBS1_ENABLE 0xf4146040
+#define FSTV0910_P1_SCAN_ENABLE 0xf4144010
+#define FSTV0910_P1_CFR_AUTOSCAN 0xf4143008
#define FSTV0910_P1_TUN_RNG 0xf4140003
/* P1_DMDCFG2 */
#define RSTV0910_P1_DMDCFG2 0xf415
-#define FSTV0910_P1_S1S2_SEQUENTIAL 0xf4150040
-#define FSTV0910_P1_INFINITE_RELOCK 0xf4150010
+#define FSTV0910_P1_S1S2_SEQUENTIAL 0xf4156040
+#define FSTV0910_P1_INFINITE_RELOCK 0xf4154010
/* P1_DMDISTATE */
#define RSTV0910_P1_DMDISTATE 0xf416
-#define FSTV0910_P1_I2C_NORESETDMODE 0xf4160080
+#define FSTV0910_P1_I2C_NORESETDMODE 0xf4167080
#define FSTV0910_P1_I2C_DEMOD_MODE 0xf416001f
/* P1_DMDT0M */
@@ -2176,27 +2176,27 @@
/* P1_DMDSTATE */
#define RSTV0910_P1_DMDSTATE 0xf41b
-#define FSTV0910_P1_HEADER_MODE 0xf41b0060
+#define FSTV0910_P1_HEADER_MODE 0xf41b5060
/* P1_DMDFLYW */
#define RSTV0910_P1_DMDFLYW 0xf41c
-#define FSTV0910_P1_I2C_IRQVAL 0xf41c00f0
+#define FSTV0910_P1_I2C_IRQVAL 0xf41c40f0
#define FSTV0910_P1_FLYWHEEL_CPT 0xf41c000f
/* P1_DSTATUS3 */
#define RSTV0910_P1_DSTATUS3 0xf41d
-#define FSTV0910_P1_CFR_ZIGZAG 0xf41d0080
-#define FSTV0910_P1_DEMOD_CFGMODE 0xf41d0060
-#define FSTV0910_P1_GAMMA_LOWBAUDRATE 0xf41d0010
+#define FSTV0910_P1_CFR_ZIGZAG 0xf41d7080
+#define FSTV0910_P1_DEMOD_CFGMODE 0xf41d5060
+#define FSTV0910_P1_GAMMA_LOWBAUDRATE 0xf41d4010
/* P1_DMDCFG3 */
#define RSTV0910_P1_DMDCFG3 0xf41e
-#define FSTV0910_P1_NOSTOP_FIFOFULL 0xf41e0008
+#define FSTV0910_P1_NOSTOP_FIFOFULL 0xf41e3008
/* P1_DMDCFG4 */
#define RSTV0910_P1_DMDCFG4 0xf41f
-#define FSTV0910_P1_DIS_VITLOCK 0xf41f0080
-#define FSTV0910_P1_DIS_CLKENABLE 0xf41f0004
+#define FSTV0910_P1_DIS_VITLOCK 0xf41f7080
+#define FSTV0910_P1_DIS_CLKENABLE 0xf41f2004
/* P1_CORRELMANT */
#define RSTV0910_P1_CORRELMANT 0xf420
@@ -2208,13 +2208,13 @@
/* P1_CORRELEXP */
#define RSTV0910_P1_CORRELEXP 0xf422
-#define FSTV0910_P1_CORREL_ABSEXP 0xf42200f0
+#define FSTV0910_P1_CORREL_ABSEXP 0xf42240f0
#define FSTV0910_P1_CORREL_EXP 0xf422000f
/* P1_PLHMODCOD */
#define RSTV0910_P1_PLHMODCOD 0xf424
-#define FSTV0910_P1_SPECINV_DEMOD 0xf4240080
-#define FSTV0910_P1_PLH_MODCOD 0xf424007c
+#define FSTV0910_P1_SPECINV_DEMOD 0xf4247080
+#define FSTV0910_P1_PLH_MODCOD 0xf424207c
#define FSTV0910_P1_PLH_TYPE 0xf4240003
/* P1_DMDREG */
@@ -2223,19 +2223,19 @@
/* P1_AGCNADJ */
#define RSTV0910_P1_AGCNADJ 0xf426
-#define FSTV0910_P1_RADJOFF_AGC2 0xf4260080
-#define FSTV0910_P1_RADJOFF_AGC1 0xf4260040
+#define FSTV0910_P1_RADJOFF_AGC2 0xf4267080
+#define FSTV0910_P1_RADJOFF_AGC1 0xf4266040
#define FSTV0910_P1_AGC_NADJ 0xf426013f
/* P1_AGCKS */
#define RSTV0910_P1_AGCKS 0xf427
-#define FSTV0910_P1_RSADJ_MANUALCFG 0xf4270080
-#define FSTV0910_P1_RSADJ_CCMMODE 0xf4270040
+#define FSTV0910_P1_RSADJ_MANUALCFG 0xf4277080
+#define FSTV0910_P1_RSADJ_CCMMODE 0xf4276040
#define FSTV0910_P1_RADJ_SPSK 0xf427013f
/* P1_AGCKQ */
#define RSTV0910_P1_AGCKQ 0xf428
-#define FSTV0910_P1_RADJON_DVBS1 0xf4280040
+#define FSTV0910_P1_RADJON_DVBS1 0xf4286040
#define FSTV0910_P1_RADJ_QPSK 0xf428013f
/* P1_AGCK8 */
@@ -2244,20 +2244,20 @@
/* P1_AGCK16 */
#define RSTV0910_P1_AGCK16 0xf42a
-#define FSTV0910_P1_R2ADJOFF_16APSK 0xf42a0040
-#define FSTV0910_P1_R1ADJOFF_16APSK 0xf42a0020
+#define FSTV0910_P1_R2ADJOFF_16APSK 0xf42a6040
+#define FSTV0910_P1_R1ADJOFF_16APSK 0xf42a5020
#define FSTV0910_P1_RADJ_16APSK 0xf42a011f
/* P1_AGCK32 */
#define RSTV0910_P1_AGCK32 0xf42b
-#define FSTV0910_P1_R3ADJOFF_32APSK 0xf42b0080
-#define FSTV0910_P1_R2ADJOFF_32APSK 0xf42b0040
-#define FSTV0910_P1_R1ADJOFF_32APSK 0xf42b0020
+#define FSTV0910_P1_R3ADJOFF_32APSK 0xf42b7080
+#define FSTV0910_P1_R2ADJOFF_32APSK 0xf42b6040
+#define FSTV0910_P1_R1ADJOFF_32APSK 0xf42b5020
#define FSTV0910_P1_RADJ_32APSK 0xf42b011f
/* P1_AGC2O */
#define RSTV0910_P1_AGC2O 0xf42c
-#define FSTV0910_P1_CSTENV_MODE 0xf42c00c0
+#define FSTV0910_P1_CSTENV_MODE 0xf42c60c0
#define FSTV0910_P1_AGC2_COEF 0xf42c0007
/* P1_AGC2REF */
@@ -2306,32 +2306,32 @@
/* P1_CARCFG */
#define RSTV0910_P1_CARCFG 0xf438
-#define FSTV0910_P1_ROTAON 0xf4380004
+#define FSTV0910_P1_ROTAON 0xf4382004
#define FSTV0910_P1_PH_DET_ALGO 0xf4380003
/* P1_ACLC */
#define RSTV0910_P1_ACLC 0xf439
-#define FSTV0910_P1_CAR_ALPHA_MANT 0xf4390030
+#define FSTV0910_P1_CAR_ALPHA_MANT 0xf4394030
#define FSTV0910_P1_CAR_ALPHA_EXP 0xf439000f
/* P1_BCLC */
#define RSTV0910_P1_BCLC 0xf43a
-#define FSTV0910_P1_CAR_BETA_MANT 0xf43a0030
+#define FSTV0910_P1_CAR_BETA_MANT 0xf43a4030
#define FSTV0910_P1_CAR_BETA_EXP 0xf43a000f
/* P1_ACLCS2 */
#define RSTV0910_P1_ACLCS2 0xf43b
-#define FSTV0910_P1_CARS2_APLHA_MANTISSE 0xf43b0030
+#define FSTV0910_P1_CARS2_APLHA_MANTISSE 0xf43b4030
#define FSTV0910_P1_CARS2_ALPHA_EXP 0xf43b000f
/* P1_BCLCS2 */
#define RSTV0910_P1_BCLCS2 0xf43c
-#define FSTV0910_P1_CARS2_BETA_MANTISSE 0xf43c0030
+#define FSTV0910_P1_CARS2_BETA_MANTISSE 0xf43c4030
#define FSTV0910_P1_CARS2_BETA_EXP 0xf43c000f
/* P1_CARFREQ */
#define RSTV0910_P1_CARFREQ 0xf43d
-#define FSTV0910_P1_KC_COARSE_EXP 0xf43d00f0
+#define FSTV0910_P1_KC_COARSE_EXP 0xf43d40f0
#define FSTV0910_P1_BETA_FREQ 0xf43d000f
/* P1_CARHDR */
@@ -2384,7 +2384,7 @@
/* P1_CFRINC1 */
#define RSTV0910_P1_CFRINC1 0xf44a
-#define FSTV0910_P1_MANUAL_CFRINC 0xf44a0080
+#define FSTV0910_P1_MANUAL_CFRINC 0xf44a7080
#define FSTV0910_P1_CFR_INC1 0xf44a003f
/* P1_CFRINC0 */
@@ -2409,18 +2409,18 @@
/* P1_TMGCFG */
#define RSTV0910_P1_TMGCFG 0xf450
-#define FSTV0910_P1_TMGLOCK_BETA 0xf45000c0
-#define FSTV0910_P1_DO_TIMING_CORR 0xf4500010
+#define FSTV0910_P1_TMGLOCK_BETA 0xf45060c0
+#define FSTV0910_P1_DO_TIMING_CORR 0xf4504010
#define FSTV0910_P1_TMG_MINFREQ 0xf4500003
/* P1_RTC */
#define RSTV0910_P1_RTC 0xf451
-#define FSTV0910_P1_TMGALPHA_EXP 0xf45100f0
+#define FSTV0910_P1_TMGALPHA_EXP 0xf45140f0
#define FSTV0910_P1_TMGBETA_EXP 0xf451000f
/* P1_RTCS2 */
#define RSTV0910_P1_RTCS2 0xf452
-#define FSTV0910_P1_TMGALPHAS2_EXP 0xf45200f0
+#define FSTV0910_P1_TMGALPHAS2_EXP 0xf45240f0
#define FSTV0910_P1_TMGBETAS2_EXP 0xf452000f
/* P1_TMGTHRISE */
@@ -2441,7 +2441,7 @@
/* P1_KTTMG */
#define RSTV0910_P1_KTTMG 0xf457
-#define FSTV0910_P1_KT_TMG_EXP 0xf45700f0
+#define FSTV0910_P1_KT_TMG_EXP 0xf45740f0
/* P1_KREFTMG */
#define RSTV0910_P1_KREFTMG 0xf458
@@ -2449,12 +2449,12 @@
/* P1_SFRSTEP */
#define RSTV0910_P1_SFRSTEP 0xf459
-#define FSTV0910_P1_SFR_SCANSTEP 0xf45900f0
+#define FSTV0910_P1_SFR_SCANSTEP 0xf45940f0
#define FSTV0910_P1_SFR_CENTERSTEP 0xf459000f
/* P1_TMGCFG2 */
#define RSTV0910_P1_TMGCFG2 0xf45a
-#define FSTV0910_P1_DIS_AUTOSAMP 0xf45a0008
+#define FSTV0910_P1_DIS_AUTOSAMP 0xf45a3008
#define FSTV0910_P1_SFRRATIO_FINE 0xf45a0001
/* P1_KREFTMG2 */
@@ -2463,9 +2463,9 @@
/* P1_TMGCFG3 */
#define RSTV0910_P1_TMGCFG3 0xf45d
-#define FSTV0910_P1_CONT_TMGCENTER 0xf45d0008
-#define FSTV0910_P1_AUTO_GUP 0xf45d0004
-#define FSTV0910_P1_AUTO_GLOW 0xf45d0002
+#define FSTV0910_P1_CONT_TMGCENTER 0xf45d3008
+#define FSTV0910_P1_AUTO_GUP 0xf45d2004
+#define FSTV0910_P1_AUTO_GLOW 0xf45d1002
/* P1_SFRINIT1 */
#define RSTV0910_P1_SFRINIT1 0xf45e
@@ -2529,11 +2529,11 @@
/* P1_TMGOBS */
#define RSTV0910_P1_TMGOBS 0xf46d
-#define FSTV0910_P1_ROLLOFF_STATUS 0xf46d00c0
+#define FSTV0910_P1_ROLLOFF_STATUS 0xf46d60c0
/* P1_EQUALCFG */
#define RSTV0910_P1_EQUALCFG 0xf46f
-#define FSTV0910_P1_EQUAL_ON 0xf46f0040
+#define FSTV0910_P1_EQUAL_ON 0xf46f6040
#define FSTV0910_P1_MU_EQUALDFE 0xf46f0007
/* P1_EQUAI1 */
@@ -2658,33 +2658,33 @@
/* P1_NOSCFGF1 */
#define RSTV0910_P1_NOSCFGF1 0xf48e
-#define FSTV0910_P1_LOWNOISE_MESURE 0xf48e0080
-#define FSTV0910_P1_NOS_DELFRAME 0xf48e0040
-#define FSTV0910_P1_NOSDATA_MODE 0xf48e0030
-#define FSTV0910_P1_FRAMESEL_TYPESEL 0xf48e000c
+#define FSTV0910_P1_LOWNOISE_MESURE 0xf48e7080
+#define FSTV0910_P1_NOS_DELFRAME 0xf48e6040
+#define FSTV0910_P1_NOSDATA_MODE 0xf48e4030
+#define FSTV0910_P1_FRAMESEL_TYPESEL 0xf48e200c
#define FSTV0910_P1_FRAMESEL_TYPE 0xf48e0003
/* P1_NOSCFGF2 */
#define RSTV0910_P1_NOSCFGF2 0xf48f
-#define FSTV0910_P1_DIS_NOSPILOTS 0xf48f0080
-#define FSTV0910_P1_FRAMESEL_MODCODSEL 0xf48f0060
+#define FSTV0910_P1_DIS_NOSPILOTS 0xf48f7080
+#define FSTV0910_P1_FRAMESEL_MODCODSEL 0xf48f5060
#define FSTV0910_P1_FRAMESEL_MODCOD 0xf48f001f
/* P1_CAR2CFG */
#define RSTV0910_P1_CAR2CFG 0xf490
-#define FSTV0910_P1_ROTA2ON 0xf4900004
+#define FSTV0910_P1_ROTA2ON 0xf4902004
#define FSTV0910_P1_PH_DET_ALGO2 0xf4900003
/* P1_CFR2CFR1 */
#define RSTV0910_P1_CFR2CFR1 0xf491
-#define FSTV0910_P1_EN_S2CAR2CENTER 0xf4910020
+#define FSTV0910_P1_EN_S2CAR2CENTER 0xf4915020
#define FSTV0910_P1_CFR2TOCFR1_BETA 0xf4910007
/* P1_CAR3CFG */
#define RSTV0910_P1_CAR3CFG 0xf492
-#define FSTV0910_P1_CARRIER23_MODE 0xf49200c0
-#define FSTV0910_P1_CAR3INTERM_DVBS1 0xf4920020
-#define FSTV0910_P1_ABAMPLIF_MODE 0xf4920018
+#define FSTV0910_P1_CARRIER23_MODE 0xf49260c0
+#define FSTV0910_P1_CAR3INTERM_DVBS1 0xf4925020
+#define FSTV0910_P1_ABAMPLIF_MODE 0xf4923018
#define FSTV0910_P1_CARRIER3_ALPHA3DL 0xf4920007
/* P1_CFR22 */
@@ -2701,50 +2701,50 @@
/* P1_ACLC2S2Q */
#define RSTV0910_P1_ACLC2S2Q 0xf497
-#define FSTV0910_P1_ENAB_SPSKSYMB 0xf4970080
-#define FSTV0910_P1_CAR2S2_Q_ALPH_M 0xf4970030
+#define FSTV0910_P1_ENAB_SPSKSYMB 0xf4977080
+#define FSTV0910_P1_CAR2S2_Q_ALPH_M 0xf4974030
#define FSTV0910_P1_CAR2S2_Q_ALPH_E 0xf497000f
/* P1_ACLC2S28 */
#define RSTV0910_P1_ACLC2S28 0xf498
-#define FSTV0910_P1_CAR2S2_8_ALPH_M 0xf4980030
+#define FSTV0910_P1_CAR2S2_8_ALPH_M 0xf4984030
#define FSTV0910_P1_CAR2S2_8_ALPH_E 0xf498000f
/* P1_ACLC2S216A */
#define RSTV0910_P1_ACLC2S216A 0xf499
-#define FSTV0910_P1_CAR2S2_16A_ALPH_M 0xf4990030
+#define FSTV0910_P1_CAR2S2_16A_ALPH_M 0xf4994030
#define FSTV0910_P1_CAR2S2_16A_ALPH_E 0xf499000f
/* P1_ACLC2S232A */
#define RSTV0910_P1_ACLC2S232A 0xf49a
-#define FSTV0910_P1_CAR2S2_32A_ALPH_M 0xf49a0030
+#define FSTV0910_P1_CAR2S2_32A_ALPH_M 0xf49a4030
#define FSTV0910_P1_CAR2S2_32A_ALPH_E 0xf49a000f
/* P1_BCLC2S2Q */
#define RSTV0910_P1_BCLC2S2Q 0xf49c
-#define FSTV0910_P1_CAR2S2_Q_BETA_M 0xf49c0030
+#define FSTV0910_P1_CAR2S2_Q_BETA_M 0xf49c4030
#define FSTV0910_P1_CAR2S2_Q_BETA_E 0xf49c000f
/* P1_BCLC2S28 */
#define RSTV0910_P1_BCLC2S28 0xf49d
-#define FSTV0910_P1_CAR2S2_8_BETA_M 0xf49d0030
+#define FSTV0910_P1_CAR2S2_8_BETA_M 0xf49d4030
#define FSTV0910_P1_CAR2S2_8_BETA_E 0xf49d000f
/* P1_BCLC2S216A */
#define RSTV0910_P1_BCLC2S216A 0xf49e
-#define FSTV0910_P1_DVBS2S216A_NIP 0xf49e0080
-#define FSTV0910_P1_CAR2S2_16A_BETA_M 0xf49e0030
+#define FSTV0910_P1_DVBS2S216A_NIP 0xf49e7080
+#define FSTV0910_P1_CAR2S2_16A_BETA_M 0xf49e4030
#define FSTV0910_P1_CAR2S2_16A_BETA_E 0xf49e000f
/* P1_BCLC2S232A */
#define RSTV0910_P1_BCLC2S232A 0xf49f
-#define FSTV0910_P1_DVBS2S232A_NIP 0xf49f0080
-#define FSTV0910_P1_CAR2S2_32A_BETA_M 0xf49f0030
+#define FSTV0910_P1_DVBS2S232A_NIP 0xf49f7080
+#define FSTV0910_P1_CAR2S2_32A_BETA_M 0xf49f4030
#define FSTV0910_P1_CAR2S2_32A_BETA_E 0xf49f000f
/* P1_PLROOT2 */
#define RSTV0910_P1_PLROOT2 0xf4ac
-#define FSTV0910_P1_PLSCRAMB_MODE 0xf4ac000c
+#define FSTV0910_P1_PLSCRAMB_MODE 0xf4ac200c
#define FSTV0910_P1_PLSCRAMB_ROOT2 0xf4ac0003
/* P1_PLROOT1 */
@@ -2761,100 +2761,100 @@
/* P1_MODCODLST1 */
#define RSTV0910_P1_MODCODLST1 0xf4b1
-#define FSTV0910_P1_SYMBRATE_FILTER 0xf4b10008
-#define FSTV0910_P1_NRESET_MODCODLST 0xf4b10004
+#define FSTV0910_P1_SYMBRATE_FILTER 0xf4b13008
+#define FSTV0910_P1_NRESET_MODCODLST 0xf4b12004
#define FSTV0910_P1_DIS_32PSK_9_10 0xf4b10003
/* P1_MODCODLST2 */
#define RSTV0910_P1_MODCODLST2 0xf4b2
-#define FSTV0910_P1_DIS_32PSK_8_9 0xf4b200f0
+#define FSTV0910_P1_DIS_32PSK_8_9 0xf4b240f0
#define FSTV0910_P1_DIS_32PSK_5_6 0xf4b2000f
/* P1_MODCODLST3 */
#define RSTV0910_P1_MODCODLST3 0xf4b3
-#define FSTV0910_P1_DIS_32PSK_4_5 0xf4b300f0
+#define FSTV0910_P1_DIS_32PSK_4_5 0xf4b340f0
#define FSTV0910_P1_DIS_32PSK_3_4 0xf4b3000f
/* P1_MODCODLST4 */
#define RSTV0910_P1_MODCODLST4 0xf4b4
-#define FSTV0910_P1_DUMMYPL_PILOT 0xf4b40080
-#define FSTV0910_P1_DUMMYPL_NOPILOT 0xf4b40040
-#define FSTV0910_P1_DIS_16PSK_9_10 0xf4b40030
+#define FSTV0910_P1_DUMMYPL_PILOT 0xf4b47080
+#define FSTV0910_P1_DUMMYPL_NOPILOT 0xf4b46040
+#define FSTV0910_P1_DIS_16PSK_9_10 0xf4b44030
#define FSTV0910_P1_DIS_16PSK_8_9 0xf4b4000f
/* P1_MODCODLST5 */
#define RSTV0910_P1_MODCODLST5 0xf4b5
-#define FSTV0910_P1_DIS_16PSK_5_6 0xf4b500f0
+#define FSTV0910_P1_DIS_16PSK_5_6 0xf4b540f0
#define FSTV0910_P1_DIS_16PSK_4_5 0xf4b5000f
/* P1_MODCODLST6 */
#define RSTV0910_P1_MODCODLST6 0xf4b6
-#define FSTV0910_P1_DIS_16PSK_3_4 0xf4b600f0
+#define FSTV0910_P1_DIS_16PSK_3_4 0xf4b640f0
#define FSTV0910_P1_DIS_16PSK_2_3 0xf4b6000f
/* P1_MODCODLST7 */
#define RSTV0910_P1_MODCODLST7 0xf4b7
-#define FSTV0910_P1_MODCOD_NNOSFILTER 0xf4b70080
-#define FSTV0910_P1_DIS_8PSK_9_10 0xf4b70030
+#define FSTV0910_P1_MODCOD_NNOSFILTER 0xf4b77080
+#define FSTV0910_P1_DIS_8PSK_9_10 0xf4b74030
#define FSTV0910_P1_DIS_8PSK_8_9 0xf4b7000f
/* P1_MODCODLST8 */
#define RSTV0910_P1_MODCODLST8 0xf4b8
-#define FSTV0910_P1_DIS_8PSK_5_6 0xf4b800f0
+#define FSTV0910_P1_DIS_8PSK_5_6 0xf4b840f0
#define FSTV0910_P1_DIS_8PSK_3_4 0xf4b8000f
/* P1_MODCODLST9 */
#define RSTV0910_P1_MODCODLST9 0xf4b9
-#define FSTV0910_P1_DIS_8PSK_2_3 0xf4b900f0
+#define FSTV0910_P1_DIS_8PSK_2_3 0xf4b940f0
#define FSTV0910_P1_DIS_8PSK_3_5 0xf4b9000f
/* P1_MODCODLSTA */
#define RSTV0910_P1_MODCODLSTA 0xf4ba
-#define FSTV0910_P1_NOSFILTER_LIMITE 0xf4ba0080
-#define FSTV0910_P1_DIS_QPSK_9_10 0xf4ba0030
+#define FSTV0910_P1_NOSFILTER_LIMITE 0xf4ba7080
+#define FSTV0910_P1_DIS_QPSK_9_10 0xf4ba4030
#define FSTV0910_P1_DIS_QPSK_8_9 0xf4ba000f
/* P1_MODCODLSTB */
#define RSTV0910_P1_MODCODLSTB 0xf4bb
-#define FSTV0910_P1_DIS_QPSK_5_6 0xf4bb00f0
+#define FSTV0910_P1_DIS_QPSK_5_6 0xf4bb40f0
#define FSTV0910_P1_DIS_QPSK_4_5 0xf4bb000f
/* P1_MODCODLSTC */
#define RSTV0910_P1_MODCODLSTC 0xf4bc
-#define FSTV0910_P1_DIS_QPSK_3_4 0xf4bc00f0
+#define FSTV0910_P1_DIS_QPSK_3_4 0xf4bc40f0
#define FSTV0910_P1_DIS_QPSK_2_3 0xf4bc000f
/* P1_MODCODLSTD */
#define RSTV0910_P1_MODCODLSTD 0xf4bd
-#define FSTV0910_P1_DIS_QPSK_3_5 0xf4bd00f0
+#define FSTV0910_P1_DIS_QPSK_3_5 0xf4bd40f0
#define FSTV0910_P1_DIS_QPSK_1_2 0xf4bd000f
/* P1_MODCODLSTE */
#define RSTV0910_P1_MODCODLSTE 0xf4be
-#define FSTV0910_P1_DIS_QPSK_2_5 0xf4be00f0
+#define FSTV0910_P1_DIS_QPSK_2_5 0xf4be40f0
#define FSTV0910_P1_DIS_QPSK_1_3 0xf4be000f
/* P1_MODCODLSTF */
#define RSTV0910_P1_MODCODLSTF 0xf4bf
-#define FSTV0910_P1_DIS_QPSK_1_4 0xf4bf00f0
-#define FSTV0910_P1_DEMOD_INVMODLST 0xf4bf0008
-#define FSTV0910_P1_DEMODOUT_ENABLE 0xf4bf0004
-#define FSTV0910_P1_DDEMOD_NSET 0xf4bf0002
+#define FSTV0910_P1_DIS_QPSK_1_4 0xf4bf40f0
+#define FSTV0910_P1_DEMOD_INVMODLST 0xf4bf3008
+#define FSTV0910_P1_DEMODOUT_ENABLE 0xf4bf2004
+#define FSTV0910_P1_DDEMOD_NSET 0xf4bf1002
#define FSTV0910_P1_MODCOD_NSTOCK 0xf4bf0001
/* P1_GAUSSR0 */
#define RSTV0910_P1_GAUSSR0 0xf4c0
-#define FSTV0910_P1_EN_CCIMODE 0xf4c00080
+#define FSTV0910_P1_EN_CCIMODE 0xf4c07080
#define FSTV0910_P1_R0_GAUSSIEN 0xf4c0007f
/* P1_CCIR0 */
#define RSTV0910_P1_CCIR0 0xf4c1
-#define FSTV0910_P1_CCIDETECT_PLHONLY 0xf4c10080
+#define FSTV0910_P1_CCIDETECT_PLHONLY 0xf4c17080
#define FSTV0910_P1_R0_CCI 0xf4c1007f
/* P1_CCIQUANT */
#define RSTV0910_P1_CCIQUANT 0xf4c2
-#define FSTV0910_P1_CCI_BETA 0xf4c200e0
+#define FSTV0910_P1_CCI_BETA 0xf4c250e0
#define FSTV0910_P1_CCI_QUANT 0xf4c2001f
/* P1_CCITHRES */
@@ -2867,24 +2867,24 @@
/* P1_DSTATUS4 */
#define RSTV0910_P1_DSTATUS4 0xf4c5
-#define FSTV0910_P1_RAINFADE_DETECT 0xf4c50080
-#define FSTV0910_P1_NOTHRES2_FAIL 0xf4c50040
-#define FSTV0910_P1_NOTHRES1_FAIL 0xf4c50020
-#define FSTV0910_P1_DMDPROG_ERROR 0xf4c50004
-#define FSTV0910_P1_CSTENV_DETECT 0xf4c50002
+#define FSTV0910_P1_RAINFADE_DETECT 0xf4c57080
+#define FSTV0910_P1_NOTHRES2_FAIL 0xf4c56040
+#define FSTV0910_P1_NOTHRES1_FAIL 0xf4c55020
+#define FSTV0910_P1_DMDPROG_ERROR 0xf4c52004
+#define FSTV0910_P1_CSTENV_DETECT 0xf4c51002
#define FSTV0910_P1_DETECTION_TRIAX 0xf4c50001
/* P1_DMDRESCFG */
#define RSTV0910_P1_DMDRESCFG 0xf4c6
-#define FSTV0910_P1_DMDRES_RESET 0xf4c60080
-#define FSTV0910_P1_DMDRES_STRALL 0xf4c60008
-#define FSTV0910_P1_DMDRES_NEWONLY 0xf4c60004
-#define FSTV0910_P1_DMDRES_NOSTORE 0xf4c60002
+#define FSTV0910_P1_DMDRES_RESET 0xf4c67080
+#define FSTV0910_P1_DMDRES_STRALL 0xf4c63008
+#define FSTV0910_P1_DMDRES_NEWONLY 0xf4c62004
+#define FSTV0910_P1_DMDRES_NOSTORE 0xf4c61002
/* P1_DMDRESADR */
#define RSTV0910_P1_DMDRESADR 0xf4c7
-#define FSTV0910_P1_DMDRES_VALIDCFR 0xf4c70040
-#define FSTV0910_P1_DMDRES_MEMFULL 0xf4c70030
+#define FSTV0910_P1_DMDRES_VALIDCFR 0xf4c76040
+#define FSTV0910_P1_DMDRES_MEMFULL 0xf4c74030
#define FSTV0910_P1_DMDRES_RESNBR 0xf4c7000f
/* P1_DMDRESDATA7 */
@@ -2953,29 +2953,29 @@
/* P1_FFECFG */
#define RSTV0910_P1_FFECFG 0xf4d8
-#define FSTV0910_P1_EQUALFFE_ON 0xf4d80040
-#define FSTV0910_P1_EQUAL_USEDSYMB 0xf4d80030
+#define FSTV0910_P1_EQUALFFE_ON 0xf4d86040
+#define FSTV0910_P1_EQUAL_USEDSYMB 0xf4d84030
#define FSTV0910_P1_MU_EQUALFFE 0xf4d80007
/* P1_TNRCFG2 */
#define RSTV0910_P1_TNRCFG2 0xf4e1
-#define FSTV0910_P1_TUN_IQSWAP 0xf4e10080
+#define FSTV0910_P1_TUN_IQSWAP 0xf4e17080
/* P1_SMAPCOEF7 */
#define RSTV0910_P1_SMAPCOEF7 0xf500
-#define FSTV0910_P1_DIS_QSCALE 0xf5000080
+#define FSTV0910_P1_DIS_QSCALE 0xf5007080
#define FSTV0910_P1_SMAPCOEF_Q_LLR12 0xf500017f
/* P1_SMAPCOEF6 */
#define RSTV0910_P1_SMAPCOEF6 0xf501
-#define FSTV0910_P1_DIS_AGC2SCALE 0xf5010080
-#define FSTV0910_P1_ADJ_8PSKLLR1 0xf5010004
-#define FSTV0910_P1_OLD_8PSKLLR1 0xf5010002
+#define FSTV0910_P1_DIS_AGC2SCALE 0xf5017080
+#define FSTV0910_P1_ADJ_8PSKLLR1 0xf5012004
+#define FSTV0910_P1_OLD_8PSKLLR1 0xf5011002
#define FSTV0910_P1_DIS_AB8PSK 0xf5010001
/* P1_SMAPCOEF5 */
#define RSTV0910_P1_SMAPCOEF5 0xf502
-#define FSTV0910_P1_DIS_8SCALE 0xf5020080
+#define FSTV0910_P1_DIS_8SCALE 0xf5027080
#define FSTV0910_P1_SMAPCOEF_8P_LLR23 0xf502017f
/* P1_SMAPCOEF4 */
@@ -2988,17 +2988,17 @@
/* P1_SMAPCOEF2 */
#define RSTV0910_P1_SMAPCOEF2 0xf505
-#define FSTV0910_P1_SMAPCOEF_32APSK_R2R3 0xf50501f0
+#define FSTV0910_P1_SMAPCOEF_32APSK_R2R3 0xf50541f0
#define FSTV0910_P1_SMAPCOEF_32APSK_LLR2 0xf505010f
/* P1_SMAPCOEF1 */
#define RSTV0910_P1_SMAPCOEF1 0xf506
-#define FSTV0910_P1_DIS_16SCALE 0xf5060080
+#define FSTV0910_P1_DIS_16SCALE 0xf5067080
#define FSTV0910_P1_SMAPCOEF_32_LLR34 0xf506017f
/* P1_SMAPCOEF0 */
#define RSTV0910_P1_SMAPCOEF0 0xf507
-#define FSTV0910_P1_DIS_32SCALE 0xf5070080
+#define FSTV0910_P1_DIS_32SCALE 0xf5077080
#define FSTV0910_P1_SMAPCOEF_32_LLR15 0xf507017f
/* P1_NOSTHRES1 */
@@ -3015,20 +3015,20 @@
/* P1_RAINFADE */
#define RSTV0910_P1_RAINFADE 0xf50c
-#define FSTV0910_P1_NOSTHRES_DATAT 0xf50c0080
-#define FSTV0910_P1_RAINFADE_CNLIMIT 0xf50c0070
+#define FSTV0910_P1_NOSTHRES_DATAT 0xf50c7080
+#define FSTV0910_P1_RAINFADE_CNLIMIT 0xf50c4070
#define FSTV0910_P1_RAINFADE_TIMEOUT 0xf50c0007
/* P1_NOSRAMCFG */
#define RSTV0910_P1_NOSRAMCFG 0xf50d
-#define FSTV0910_P1_NOSRAM_ACTIVATION 0xf50d0030
-#define FSTV0910_P1_NOSRAM_CNRONLY 0xf50d0008
+#define FSTV0910_P1_NOSRAM_ACTIVATION 0xf50d4030
+#define FSTV0910_P1_NOSRAM_CNRONLY 0xf50d3008
#define FSTV0910_P1_NOSRAM_LGNCNR1 0xf50d0007
/* P1_NOSRAMPOS */
#define RSTV0910_P1_NOSRAMPOS 0xf50e
-#define FSTV0910_P1_NOSRAM_LGNCNR0 0xf50e00f0
-#define FSTV0910_P1_NOSRAM_VALIDE 0xf50e0004
+#define FSTV0910_P1_NOSRAM_LGNCNR0 0xf50e40f0
+#define FSTV0910_P1_NOSRAM_VALIDE 0xf50e2004
#define FSTV0910_P1_NOSRAM_CNRVAL1 0xf50e0003
/* P1_NOSRAMVAL */
@@ -3057,16 +3057,16 @@
/* P1_VITSCALE */
#define RSTV0910_P1_VITSCALE 0xf532
-#define FSTV0910_P1_NVTH_NOSRANGE 0xf5320080
-#define FSTV0910_P1_VERROR_MAXMODE 0xf5320040
-#define FSTV0910_P1_NSLOWSN_LOCKED 0xf5320008
-#define FSTV0910_P1_DIS_RSFLOCK 0xf5320002
+#define FSTV0910_P1_NVTH_NOSRANGE 0xf5327080
+#define FSTV0910_P1_VERROR_MAXMODE 0xf5326040
+#define FSTV0910_P1_NSLOWSN_LOCKED 0xf5323008
+#define FSTV0910_P1_DIS_RSFLOCK 0xf5321002
/* P1_FECM */
#define RSTV0910_P1_FECM 0xf533
-#define FSTV0910_P1_DSS_DVB 0xf5330080
-#define FSTV0910_P1_DSS_SRCH 0xf5330010
-#define FSTV0910_P1_SYNCVIT 0xf5330002
+#define FSTV0910_P1_DSS_DVB 0xf5337080
+#define FSTV0910_P1_DSS_SRCH 0xf5334010
+#define FSTV0910_P1_SYNCVIT 0xf5331002
#define FSTV0910_P1_IQINV 0xf5330001
/* P1_VTH12 */
@@ -3103,26 +3103,26 @@
/* P1_PRVIT */
#define RSTV0910_P1_PRVIT 0xf53c
-#define FSTV0910_P1_DIS_VTHLOCK 0xf53c0040
-#define FSTV0910_P1_E7_8VIT 0xf53c0020
-#define FSTV0910_P1_E6_7VIT 0xf53c0010
-#define FSTV0910_P1_E5_6VIT 0xf53c0008
-#define FSTV0910_P1_E3_4VIT 0xf53c0004
-#define FSTV0910_P1_E2_3VIT 0xf53c0002
+#define FSTV0910_P1_DIS_VTHLOCK 0xf53c6040
+#define FSTV0910_P1_E7_8VIT 0xf53c5020
+#define FSTV0910_P1_E6_7VIT 0xf53c4010
+#define FSTV0910_P1_E5_6VIT 0xf53c3008
+#define FSTV0910_P1_E3_4VIT 0xf53c2004
+#define FSTV0910_P1_E2_3VIT 0xf53c1002
#define FSTV0910_P1_E1_2VIT 0xf53c0001
/* P1_VAVSRVIT */
#define RSTV0910_P1_VAVSRVIT 0xf53d
-#define FSTV0910_P1_AMVIT 0xf53d0080
-#define FSTV0910_P1_FROZENVIT 0xf53d0040
-#define FSTV0910_P1_SNVIT 0xf53d0030
-#define FSTV0910_P1_TOVVIT 0xf53d000c
+#define FSTV0910_P1_AMVIT 0xf53d7080
+#define FSTV0910_P1_FROZENVIT 0xf53d6040
+#define FSTV0910_P1_SNVIT 0xf53d4030
+#define FSTV0910_P1_TOVVIT 0xf53d200c
#define FSTV0910_P1_HYPVIT 0xf53d0003
/* P1_VSTATUSVIT */
#define RSTV0910_P1_VSTATUSVIT 0xf53e
-#define FSTV0910_P1_PRFVIT 0xf53e0010
-#define FSTV0910_P1_LOCKEDVIT 0xf53e0008
+#define FSTV0910_P1_PRFVIT 0xf53e4010
+#define FSTV0910_P1_LOCKEDVIT 0xf53e3008
/* P1_VTHINUSE */
#define RSTV0910_P1_VTHINUSE 0xf53f
@@ -3162,32 +3162,32 @@
/* P1_PDELCTRL0 */
#define RSTV0910_P1_PDELCTRL0 0xf54f
-#define FSTV0910_P1_ISIOBS_MODE 0xf54f0030
+#define FSTV0910_P1_ISIOBS_MODE 0xf54f4030
/* P1_PDELCTRL1 */
#define RSTV0910_P1_PDELCTRL1 0xf550
-#define FSTV0910_P1_INV_MISMASK 0xf5500080
-#define FSTV0910_P1_FILTER_EN 0xf5500020
-#define FSTV0910_P1_HYSTEN 0xf5500008
-#define FSTV0910_P1_HYSTSWRST 0xf5500004
-#define FSTV0910_P1_EN_MIS00 0xf5500002
+#define FSTV0910_P1_INV_MISMASK 0xf5507080
+#define FSTV0910_P1_FILTER_EN 0xf5505020
+#define FSTV0910_P1_HYSTEN 0xf5503008
+#define FSTV0910_P1_HYSTSWRST 0xf5502004
+#define FSTV0910_P1_EN_MIS00 0xf5501002
#define FSTV0910_P1_ALGOSWRST 0xf5500001
/* P1_PDELCTRL2 */
#define RSTV0910_P1_PDELCTRL2 0xf551
-#define FSTV0910_P1_FORCE_CONTINUOUS 0xf5510080
-#define FSTV0910_P1_RESET_UPKO_COUNT 0xf5510040
-#define FSTV0910_P1_USER_PKTDELIN_NB 0xf5510020
-#define FSTV0910_P1_FRAME_MODE 0xf5510002
+#define FSTV0910_P1_FORCE_CONTINUOUS 0xf5517080
+#define FSTV0910_P1_RESET_UPKO_COUNT 0xf5516040
+#define FSTV0910_P1_USER_PKTDELIN_NB 0xf5515020
+#define FSTV0910_P1_FRAME_MODE 0xf5511002
/* P1_HYSTTHRESH */
#define RSTV0910_P1_HYSTTHRESH 0xf554
-#define FSTV0910_P1_DELIN_LOCKTHRES 0xf55400f0
+#define FSTV0910_P1_DELIN_LOCKTHRES 0xf55440f0
#define FSTV0910_P1_DELIN_UNLOCKTHRES 0xf554000f
/* P1_UPLCCST0 */
#define RSTV0910_P1_UPLCCST0 0xf558
-#define FSTV0910_P1_UPL_CST0 0xf55800f8
+#define FSTV0910_P1_UPL_CST0 0xf55830f8
#define FSTV0910_P1_UPL_MODE 0xf5580007
/* P1_ISIENTRY */
@@ -3236,16 +3236,16 @@
/* P1_PDELSTATUS1 */
#define RSTV0910_P1_PDELSTATUS1 0xf569
-#define FSTV0910_P1_PKTDELIN_DELOCK 0xf5690080
-#define FSTV0910_P1_SYNCDUPDFL_BADDFL 0xf5690040
-#define FSTV0910_P1_UNACCEPTED_STREAM 0xf5690010
-#define FSTV0910_P1_BCH_ERROR_FLAG 0xf5690008
-#define FSTV0910_P1_PKTDELIN_LOCK 0xf5690002
+#define FSTV0910_P1_PKTDELIN_DELOCK 0xf5697080
+#define FSTV0910_P1_SYNCDUPDFL_BADDFL 0xf5696040
+#define FSTV0910_P1_UNACCEPTED_STREAM 0xf5694010
+#define FSTV0910_P1_BCH_ERROR_FLAG 0xf5693008
+#define FSTV0910_P1_PKTDELIN_LOCK 0xf5691002
#define FSTV0910_P1_FIRST_LOCK 0xf5690001
/* P1_PDELSTATUS2 */
#define RSTV0910_P1_PDELSTATUS2 0xf56a
-#define FSTV0910_P1_FRAME_MODCOD 0xf56a007c
+#define FSTV0910_P1_FRAME_MODCOD 0xf56a207c
#define FSTV0910_P1_FRAME_TYPE 0xf56a0003
/* P1_BBFCRCKO1 */
@@ -3266,92 +3266,92 @@
/* P1_PDELCTRL3 */
#define RSTV0910_P1_PDELCTRL3 0xf56f
-#define FSTV0910_P1_NOFIFO_BCHERR 0xf56f0020
-#define FSTV0910_P1_PKTDELIN_DELACMERR 0xf56f0010
+#define FSTV0910_P1_NOFIFO_BCHERR 0xf56f5020
+#define FSTV0910_P1_PKTDELIN_DELACMERR 0xf56f4010
/* P1_TSSTATEM */
#define RSTV0910_P1_TSSTATEM 0xf570
-#define FSTV0910_P1_TSDIL_ON 0xf5700080
-#define FSTV0910_P1_TSRS_ON 0xf5700020
-#define FSTV0910_P1_TSDESCRAMB_ON 0xf5700010
-#define FSTV0910_P1_TSFRAME_MODE 0xf5700008
-#define FSTV0910_P1_TS_DISABLE 0xf5700004
-#define FSTV0910_P1_TSACM_MODE 0xf5700002
+#define FSTV0910_P1_TSDIL_ON 0xf5707080
+#define FSTV0910_P1_TSRS_ON 0xf5705020
+#define FSTV0910_P1_TSDESCRAMB_ON 0xf5704010
+#define FSTV0910_P1_TSFRAME_MODE 0xf5703008
+#define FSTV0910_P1_TS_DISABLE 0xf5702004
+#define FSTV0910_P1_TSACM_MODE 0xf5701002
#define FSTV0910_P1_TSOUT_NOSYNC 0xf5700001
/* P1_TSSTATEL */
#define RSTV0910_P1_TSSTATEL 0xf571
-#define FSTV0910_P1_TSNOSYNCBYTE 0xf5710080
-#define FSTV0910_P1_TSPARITY_ON 0xf5710040
-#define FSTV0910_P1_TSISSYI_ON 0xf5710008
-#define FSTV0910_P1_TSNPD_ON 0xf5710004
-#define FSTV0910_P1_TSCRC8_ON 0xf5710002
+#define FSTV0910_P1_TSNOSYNCBYTE 0xf5717080
+#define FSTV0910_P1_TSPARITY_ON 0xf5716040
+#define FSTV0910_P1_TSISSYI_ON 0xf5713008
+#define FSTV0910_P1_TSNPD_ON 0xf5712004
+#define FSTV0910_P1_TSCRC8_ON 0xf5711002
#define FSTV0910_P1_TSDSS_PACKET 0xf5710001
/* P1_TSCFGH */
#define RSTV0910_P1_TSCFGH 0xf572
-#define FSTV0910_P1_TSFIFO_DVBCI 0xf5720080
-#define FSTV0910_P1_TSFIFO_SERIAL 0xf5720040
-#define FSTV0910_P1_TSFIFO_TEIUPDATE 0xf5720020
-#define FSTV0910_P1_TSFIFO_DUTY50 0xf5720010
-#define FSTV0910_P1_TSFIFO_HSGNLOUT 0xf5720008
-#define FSTV0910_P1_TSFIFO_ERRMODE 0xf5720006
+#define FSTV0910_P1_TSFIFO_DVBCI 0xf5727080
+#define FSTV0910_P1_TSFIFO_SERIAL 0xf5726040
+#define FSTV0910_P1_TSFIFO_TEIUPDATE 0xf5725020
+#define FSTV0910_P1_TSFIFO_DUTY50 0xf5724010
+#define FSTV0910_P1_TSFIFO_HSGNLOUT 0xf5723008
+#define FSTV0910_P1_TSFIFO_ERRMODE 0xf5721006
#define FSTV0910_P1_RST_HWARE 0xf5720001
/* P1_TSCFGM */
#define RSTV0910_P1_TSCFGM 0xf573
-#define FSTV0910_P1_TSFIFO_MANSPEED 0xf57300c0
-#define FSTV0910_P1_TSFIFO_PERMDATA 0xf5730020
-#define FSTV0910_P1_TSFIFO_NONEWSGNL 0xf5730010
+#define FSTV0910_P1_TSFIFO_MANSPEED 0xf57360c0
+#define FSTV0910_P1_TSFIFO_PERMDATA 0xf5735020
+#define FSTV0910_P1_TSFIFO_NONEWSGNL 0xf5734010
#define FSTV0910_P1_TSFIFO_INVDATA 0xf5730001
/* P1_TSCFGL */
#define RSTV0910_P1_TSCFGL 0xf574
-#define FSTV0910_P1_TSFIFO_BCLKDEL1CK 0xf57400c0
-#define FSTV0910_P1_BCHERROR_MODE 0xf5740030
-#define FSTV0910_P1_TSFIFO_NSGNL2DATA 0xf5740008
-#define FSTV0910_P1_TSFIFO_EMBINDVB 0xf5740004
+#define FSTV0910_P1_TSFIFO_BCLKDEL1CK 0xf57460c0
+#define FSTV0910_P1_BCHERROR_MODE 0xf5744030
+#define FSTV0910_P1_TSFIFO_NSGNL2DATA 0xf5743008
+#define FSTV0910_P1_TSFIFO_EMBINDVB 0xf5742004
#define FSTV0910_P1_TSFIFO_BITSPEED 0xf5740003
/* P1_TSSYNC */
#define RSTV0910_P1_TSSYNC 0xf575
-#define FSTV0910_P1_TSFIFO_SYNCMODE 0xf5750018
+#define FSTV0910_P1_TSFIFO_SYNCMODE 0xf5753018
/* P1_TSINSDELH */
#define RSTV0910_P1_TSINSDELH 0xf576
-#define FSTV0910_P1_TSDEL_SYNCBYTE 0xf5760080
-#define FSTV0910_P1_TSDEL_XXHEADER 0xf5760040
-#define FSTV0910_P1_TSDEL_DATAFIELD 0xf5760010
-#define FSTV0910_P1_TSINSDEL_RSPARITY 0xf5760002
+#define FSTV0910_P1_TSDEL_SYNCBYTE 0xf5767080
+#define FSTV0910_P1_TSDEL_XXHEADER 0xf5766040
+#define FSTV0910_P1_TSDEL_DATAFIELD 0xf5764010
+#define FSTV0910_P1_TSINSDEL_RSPARITY 0xf5761002
#define FSTV0910_P1_TSINSDEL_CRC8 0xf5760001
/* P1_TSINSDELM */
#define RSTV0910_P1_TSINSDELM 0xf577
-#define FSTV0910_P1_TSINS_EMODCOD 0xf5770010
-#define FSTV0910_P1_TSINS_TOKEN 0xf5770008
-#define FSTV0910_P1_TSINS_XXXERR 0xf5770004
-#define FSTV0910_P1_TSINS_MATYPE 0xf5770002
+#define FSTV0910_P1_TSINS_EMODCOD 0xf5774010
+#define FSTV0910_P1_TSINS_TOKEN 0xf5773008
+#define FSTV0910_P1_TSINS_XXXERR 0xf5772004
+#define FSTV0910_P1_TSINS_MATYPE 0xf5771002
#define FSTV0910_P1_TSINS_UPL 0xf5770001
/* P1_TSINSDELL */
#define RSTV0910_P1_TSINSDELL 0xf578
-#define FSTV0910_P1_TSINS_DFL 0xf5780080
-#define FSTV0910_P1_TSINS_SYNCD 0xf5780040
-#define FSTV0910_P1_TSINS_BLOCLEN 0xf5780020
-#define FSTV0910_P1_TSINS_SIGPCOUNT 0xf5780010
-#define FSTV0910_P1_TSINS_FIFO 0xf5780008
-#define FSTV0910_P1_TSINS_REALPACK 0xf5780004
-#define FSTV0910_P1_TSINS_TSCONFIG 0xf5780002
+#define FSTV0910_P1_TSINS_DFL 0xf5787080
+#define FSTV0910_P1_TSINS_SYNCD 0xf5786040
+#define FSTV0910_P1_TSINS_BLOCLEN 0xf5785020
+#define FSTV0910_P1_TSINS_SIGPCOUNT 0xf5784010
+#define FSTV0910_P1_TSINS_FIFO 0xf5783008
+#define FSTV0910_P1_TSINS_REALPACK 0xf5782004
+#define FSTV0910_P1_TSINS_TSCONFIG 0xf5781002
#define FSTV0910_P1_TSINS_LATENCY 0xf5780001
/* P1_TSDIVN */
#define RSTV0910_P1_TSDIVN 0xf579
-#define FSTV0910_P1_TSFIFO_SPEEDMODE 0xf57900c0
+#define FSTV0910_P1_TSFIFO_SPEEDMODE 0xf57960c0
#define FSTV0910_P1_TSFIFO_RISEOK 0xf5790007
/* P1_TSCFG4 */
#define RSTV0910_P1_TSCFG4 0xf57a
-#define FSTV0910_P1_TSFIFO_TSSPEEDMODE 0xf57a00c0
+#define FSTV0910_P1_TSFIFO_TSSPEEDMODE 0xf57a60c0
/* P1_TSSPEED */
#define RSTV0910_P1_TSSPEED 0xf580
@@ -3359,18 +3359,18 @@
/* P1_TSSTATUS */
#define RSTV0910_P1_TSSTATUS 0xf581
-#define FSTV0910_P1_TSFIFO_LINEOK 0xf5810080
-#define FSTV0910_P1_TSFIFO_ERROR 0xf5810040
-#define FSTV0910_P1_TSFIFO_NOSYNC 0xf5810010
-#define FSTV0910_P1_TSREGUL_ERROR 0xf5810004
+#define FSTV0910_P1_TSFIFO_LINEOK 0xf5817080
+#define FSTV0910_P1_TSFIFO_ERROR 0xf5816040
+#define FSTV0910_P1_TSFIFO_NOSYNC 0xf5814010
+#define FSTV0910_P1_TSREGUL_ERROR 0xf5812004
#define FSTV0910_P1_DIL_READY 0xf5810001
/* P1_TSSTATUS2 */
#define RSTV0910_P1_TSSTATUS2 0xf582
-#define FSTV0910_P1_TSFIFO_DEMODSEL 0xf5820080
-#define FSTV0910_P1_TSFIFOSPEED_STORE 0xf5820040
-#define FSTV0910_P1_DILXX_RESET 0xf5820020
-#define FSTV0910_P1_SCRAMBDETECT 0xf5820002
+#define FSTV0910_P1_TSFIFO_DEMODSEL 0xf5827080
+#define FSTV0910_P1_TSFIFOSPEED_STORE 0xf5826040
+#define FSTV0910_P1_DILXX_RESET 0xf5825020
+#define FSTV0910_P1_SCRAMBDETECT 0xf5821002
/* P1_TSBITRATE1 */
#define RSTV0910_P1_TSBITRATE1 0xf583
@@ -3382,7 +3382,7 @@
/* P1_TSPACKLEN1 */
#define RSTV0910_P1_TSPACKLEN1 0xf585
-#define FSTV0910_P1_TSFIFO_PACKCPT 0xf58500e0
+#define FSTV0910_P1_TSFIFO_PACKCPT 0xf58550e0
/* P1_TSDLY2 */
#define RSTV0910_P1_TSDLY2 0xf589
@@ -3402,8 +3402,8 @@
/* P1_TSBUFSTAT2 */
#define RSTV0910_P1_TSBUFSTAT2 0xf58d
-#define FSTV0910_P1_TSISCR_3BYTES 0xf58d0080
-#define FSTV0910_P1_TSISCR_NEWDATA 0xf58d0040
+#define FSTV0910_P1_TSISCR_3BYTES 0xf58d7080
+#define FSTV0910_P1_TSISCR_NEWDATA 0xf58d6040
#define FSTV0910_P1_TSISCR_BUFSTAT2 0xf58d003f
/* P1_TSBUFSTAT1 */
@@ -3416,13 +3416,13 @@
/* P1_TSDEBUGL */
#define RSTV0910_P1_TSDEBUGL 0xf591
-#define FSTV0910_P1_TSFIFO_ERROR_EVNT 0xf5910004
+#define FSTV0910_P1_TSFIFO_ERROR_EVNT 0xf5912004
#define FSTV0910_P1_TSFIFO_OVERFLOWM 0xf5910001
/* P1_TSDLYSET2 */
#define RSTV0910_P1_TSDLYSET2 0xf592
-#define FSTV0910_P1_SOFFIFO_OFFSET 0xf59200c0
-#define FSTV0910_P1_HYSTERESIS_THRESHOLD 0xf5920030
+#define FSTV0910_P1_SOFFIFO_OFFSET 0xf59260c0
+#define FSTV0910_P1_HYSTERESIS_THRESHOLD 0xf5924030
#define FSTV0910_P1_SOFFIFO_SYMBOFFS2 0xf592000f
/* P1_TSDLYSET1 */
@@ -3435,12 +3435,12 @@
/* P1_ERRCTRL1 */
#define RSTV0910_P1_ERRCTRL1 0xf598
-#define FSTV0910_P1_ERR_SOURCE1 0xf59800f0
+#define FSTV0910_P1_ERR_SOURCE1 0xf59840f0
#define FSTV0910_P1_NUM_EVENT1 0xf5980007
/* P1_ERRCNT12 */
#define RSTV0910_P1_ERRCNT12 0xf599
-#define FSTV0910_P1_ERRCNT1_OLDVALUE 0xf5990080
+#define FSTV0910_P1_ERRCNT1_OLDVALUE 0xf5997080
#define FSTV0910_P1_ERR_CNT12 0xf599007f
/* P1_ERRCNT11 */
@@ -3453,12 +3453,12 @@
/* P1_ERRCTRL2 */
#define RSTV0910_P1_ERRCTRL2 0xf59c
-#define FSTV0910_P1_ERR_SOURCE2 0xf59c00f0
+#define FSTV0910_P1_ERR_SOURCE2 0xf59c40f0
#define FSTV0910_P1_NUM_EVENT2 0xf59c0007
/* P1_ERRCNT22 */
#define RSTV0910_P1_ERRCNT22 0xf59d
-#define FSTV0910_P1_ERRCNT2_OLDVALUE 0xf59d0080
+#define FSTV0910_P1_ERRCNT2_OLDVALUE 0xf59d7080
#define FSTV0910_P1_ERR_CNT22 0xf59d007f
/* P1_ERRCNT21 */
@@ -3471,39 +3471,39 @@
/* P1_FECSPY */
#define RSTV0910_P1_FECSPY 0xf5a0
-#define FSTV0910_P1_SPY_ENABLE 0xf5a00080
-#define FSTV0910_P1_NO_SYNCBYTE 0xf5a00040
-#define FSTV0910_P1_SERIAL_MODE 0xf5a00020
-#define FSTV0910_P1_UNUSUAL_PACKET 0xf5a00010
-#define FSTV0910_P1_BERMETER_DATAMODE 0xf5a0000c
-#define FSTV0910_P1_BERMETER_LMODE 0xf5a00002
+#define FSTV0910_P1_SPY_ENABLE 0xf5a07080
+#define FSTV0910_P1_NO_SYNCBYTE 0xf5a06040
+#define FSTV0910_P1_SERIAL_MODE 0xf5a05020
+#define FSTV0910_P1_UNUSUAL_PACKET 0xf5a04010
+#define FSTV0910_P1_BERMETER_DATAMODE 0xf5a0200c
+#define FSTV0910_P1_BERMETER_LMODE 0xf5a01002
#define FSTV0910_P1_BERMETER_RESET 0xf5a00001
/* P1_FSPYCFG */
#define RSTV0910_P1_FSPYCFG 0xf5a1
-#define FSTV0910_P1_FECSPY_INPUT 0xf5a100c0
-#define FSTV0910_P1_RST_ON_ERROR 0xf5a10020
-#define FSTV0910_P1_ONE_SHOT 0xf5a10010
-#define FSTV0910_P1_I2C_MODE 0xf5a1000c
+#define FSTV0910_P1_FECSPY_INPUT 0xf5a160c0
+#define FSTV0910_P1_RST_ON_ERROR 0xf5a15020
+#define FSTV0910_P1_ONE_SHOT 0xf5a14010
+#define FSTV0910_P1_I2C_MODE 0xf5a1200c
#define FSTV0910_P1_SPY_HYSTERESIS 0xf5a10003
/* P1_FSPYDATA */
#define RSTV0910_P1_FSPYDATA 0xf5a2
-#define FSTV0910_P1_SPY_STUFFING 0xf5a20080
-#define FSTV0910_P1_SPY_CNULLPKT 0xf5a20020
+#define FSTV0910_P1_SPY_STUFFING 0xf5a27080
+#define FSTV0910_P1_SPY_CNULLPKT 0xf5a25020
#define FSTV0910_P1_SPY_OUTDATA_MODE 0xf5a2001f
/* P1_FSPYOUT */
#define RSTV0910_P1_FSPYOUT 0xf5a3
-#define FSTV0910_P1_FSPY_DIRECT 0xf5a30080
+#define FSTV0910_P1_FSPY_DIRECT 0xf5a37080
#define FSTV0910_P1_STUFF_MODE 0xf5a30007
/* P1_FSTATUS */
#define RSTV0910_P1_FSTATUS 0xf5a4
-#define FSTV0910_P1_SPY_ENDSIM 0xf5a40080
-#define FSTV0910_P1_VALID_SIM 0xf5a40040
-#define FSTV0910_P1_FOUND_SIGNAL 0xf5a40020
-#define FSTV0910_P1_DSS_SYNCBYTE 0xf5a40010
+#define FSTV0910_P1_SPY_ENDSIM 0xf5a47080
+#define FSTV0910_P1_VALID_SIM 0xf5a46040
+#define FSTV0910_P1_FOUND_SIGNAL 0xf5a45020
+#define FSTV0910_P1_DSS_SYNCBYTE 0xf5a44010
#define FSTV0910_P1_RESULT_STATE 0xf5a4000f
/* P1_FBERCPT4 */
@@ -3540,8 +3540,8 @@
/* P1_FSPYBER */
#define RSTV0910_P1_FSPYBER 0xf5b2
-#define FSTV0910_P1_FSPYBER_SYNCBYTE 0xf5b20010
-#define FSTV0910_P1_FSPYBER_UNSYNC 0xf5b20008
+#define FSTV0910_P1_FSPYBER_SYNCBYTE 0xf5b24010
+#define FSTV0910_P1_FSPYBER_UNSYNC 0xf5b23008
#define FSTV0910_P1_FSPYBER_CTIME 0xf5b20007
/* P1_SFERROR */
@@ -3550,60 +3550,60 @@
/* P1_SFECSTATUS */
#define RSTV0910_P1_SFECSTATUS 0xf5c3
-#define FSTV0910_P1_SFEC_ON 0xf5c30080
-#define FSTV0910_P1_SFEC_OFF 0xf5c30040
-#define FSTV0910_P1_LOCKEDSFEC 0xf5c30008
-#define FSTV0910_P1_SFEC_DELOCK 0xf5c30004
-#define FSTV0910_P1_SFEC_DEMODSEL 0xf5c30002
+#define FSTV0910_P1_SFEC_ON 0xf5c37080
+#define FSTV0910_P1_SFEC_OFF 0xf5c36040
+#define FSTV0910_P1_LOCKEDSFEC 0xf5c33008
+#define FSTV0910_P1_SFEC_DELOCK 0xf5c32004
+#define FSTV0910_P1_SFEC_DEMODSEL 0xf5c31002
#define FSTV0910_P1_SFEC_OVFON 0xf5c30001
/* P1_SFKDIV12 */
#define RSTV0910_P1_SFKDIV12 0xf5c4
-#define FSTV0910_P1_SFECKDIV12_MAN 0xf5c40080
+#define FSTV0910_P1_SFECKDIV12_MAN 0xf5c47080
/* P1_SFKDIV23 */
#define RSTV0910_P1_SFKDIV23 0xf5c5
-#define FSTV0910_P1_SFECKDIV23_MAN 0xf5c50080
+#define FSTV0910_P1_SFECKDIV23_MAN 0xf5c57080
/* P1_SFKDIV34 */
#define RSTV0910_P1_SFKDIV34 0xf5c6
-#define FSTV0910_P1_SFECKDIV34_MAN 0xf5c60080
+#define FSTV0910_P1_SFECKDIV34_MAN 0xf5c67080
/* P1_SFKDIV56 */
#define RSTV0910_P1_SFKDIV56 0xf5c7
-#define FSTV0910_P1_SFECKDIV56_MAN 0xf5c70080
+#define FSTV0910_P1_SFECKDIV56_MAN 0xf5c77080
/* P1_SFKDIV67 */
#define RSTV0910_P1_SFKDIV67 0xf5c8
-#define FSTV0910_P1_SFECKDIV67_MAN 0xf5c80080
+#define FSTV0910_P1_SFECKDIV67_MAN 0xf5c87080
/* P1_SFKDIV78 */
#define RSTV0910_P1_SFKDIV78 0xf5c9
-#define FSTV0910_P1_SFECKDIV78_MAN 0xf5c90080
+#define FSTV0910_P1_SFECKDIV78_MAN 0xf5c97080
/* P1_SFSTATUS */
#define RSTV0910_P1_SFSTATUS 0xf5cc
-#define FSTV0910_P1_SFEC_LINEOK 0xf5cc0080
-#define FSTV0910_P1_SFEC_ERROR 0xf5cc0040
-#define FSTV0910_P1_SFEC_DATA7 0xf5cc0020
-#define FSTV0910_P1_SFEC_PKTDNBRFAIL 0xf5cc0010
-#define FSTV0910_P1_TSSFEC_DEMODSEL 0xf5cc0008
-#define FSTV0910_P1_SFEC_NOSYNC 0xf5cc0004
-#define FSTV0910_P1_SFEC_UNREGULA 0xf5cc0002
+#define FSTV0910_P1_SFEC_LINEOK 0xf5cc7080
+#define FSTV0910_P1_SFEC_ERROR 0xf5cc6040
+#define FSTV0910_P1_SFEC_DATA7 0xf5cc5020
+#define FSTV0910_P1_SFEC_PKTDNBRFAIL 0xf5cc4010
+#define FSTV0910_P1_TSSFEC_DEMODSEL 0xf5cc3008
+#define FSTV0910_P1_SFEC_NOSYNC 0xf5cc2004
+#define FSTV0910_P1_SFEC_UNREGULA 0xf5cc1002
#define FSTV0910_P1_SFEC_READY 0xf5cc0001
/* P1_SFDLYSET2 */
#define RSTV0910_P1_SFDLYSET2 0xf5d0
-#define FSTV0910_P1_SFEC_DISABLE 0xf5d00002
+#define FSTV0910_P1_SFEC_DISABLE 0xf5d01002
/* P1_SFERRCTRL */
#define RSTV0910_P1_SFERRCTRL 0xf5d8
-#define FSTV0910_P1_SFEC_ERR_SOURCE 0xf5d800f0
+#define FSTV0910_P1_SFEC_ERR_SOURCE 0xf5d840f0
#define FSTV0910_P1_SFEC_NUM_EVENT 0xf5d80007
/* P1_SFERRCNT2 */
#define RSTV0910_P1_SFERRCNT2 0xf5d9
-#define FSTV0910_P1_SFERRC_OLDVALUE 0xf5d90080
+#define FSTV0910_P1_SFERRC_OLDVALUE 0xf5d97080
#define FSTV0910_P1_SFEC_ERR_CNT2 0xf5d9007f
/* P1_SFERRCNT1 */
@@ -3616,66 +3616,66 @@
/* RCCFG2 */
#define RSTV0910_RCCFG2 0xf600
-#define FSTV0910_TSRCFIFO_DVBCI 0xf6000080
-#define FSTV0910_TSRCFIFO_SERIAL 0xf6000040
-#define FSTV0910_TSRCFIFO_DISABLE 0xf6000020
-#define FSTV0910_TSFIFO_2TORC 0xf6000010
-#define FSTV0910_TSRCFIFO_HSGNLOUT 0xf6000008
-#define FSTV0910_TSRCFIFO_ERRMODE 0xf6000006
+#define FSTV0910_TSRCFIFO_DVBCI 0xf6007080
+#define FSTV0910_TSRCFIFO_SERIAL 0xf6006040
+#define FSTV0910_TSRCFIFO_DISABLE 0xf6005020
+#define FSTV0910_TSFIFO_2TORC 0xf6004010
+#define FSTV0910_TSRCFIFO_HSGNLOUT 0xf6003008
+#define FSTV0910_TSRCFIFO_ERRMODE 0xf6001006
/* RCCFG1 */
#define RSTV0910_RCCFG1 0xf601
-#define FSTV0910_TSRCFIFO_MANSPEED 0xf60100c0
-#define FSTV0910_TSRCFIFO_PERMDATA 0xf6010020
-#define FSTV0910_TSRCFIFO_NONEWSGNL 0xf6010010
+#define FSTV0910_TSRCFIFO_MANSPEED 0xf60160c0
+#define FSTV0910_TSRCFIFO_PERMDATA 0xf6015020
+#define FSTV0910_TSRCFIFO_NONEWSGNL 0xf6014010
#define FSTV0910_TSRCFIFO_INVDATA 0xf6010001
/* RCCFG0 */
#define RSTV0910_RCCFG0 0xf602
-#define FSTV0910_TSRCFIFO_BCLKDEL1CK 0xf60200c0
-#define FSTV0910_TSRCFIFO_DUTY50 0xf6020010
-#define FSTV0910_TSRCFIFO_NSGNL2DATA 0xf6020008
-#define FSTV0910_TSRCFIFO_NPDSGNL 0xf6020004
+#define FSTV0910_TSRCFIFO_BCLKDEL1CK 0xf60260c0
+#define FSTV0910_TSRCFIFO_DUTY50 0xf6024010
+#define FSTV0910_TSRCFIFO_NSGNL2DATA 0xf6023008
+#define FSTV0910_TSRCFIFO_NPDSGNL 0xf6022004
/* RCINSDEL2 */
#define RSTV0910_RCINSDEL2 0xf603
-#define FSTV0910_TSRCDEL_SYNCBYTE 0xf6030080
-#define FSTV0910_TSRCDEL_XXHEADER 0xf6030040
-#define FSTV0910_TSRCDEL_BBHEADER 0xf6030020
-#define FSTV0910_TSRCDEL_DATAFIELD 0xf6030010
-#define FSTV0910_TSRCINSDEL_ISCR 0xf6030008
-#define FSTV0910_TSRCINSDEL_NPD 0xf6030004
-#define FSTV0910_TSRCINSDEL_RSPARITY 0xf6030002
+#define FSTV0910_TSRCDEL_SYNCBYTE 0xf6037080
+#define FSTV0910_TSRCDEL_XXHEADER 0xf6036040
+#define FSTV0910_TSRCDEL_BBHEADER 0xf6035020
+#define FSTV0910_TSRCDEL_DATAFIELD 0xf6034010
+#define FSTV0910_TSRCINSDEL_ISCR 0xf6033008
+#define FSTV0910_TSRCINSDEL_NPD 0xf6032004
+#define FSTV0910_TSRCINSDEL_RSPARITY 0xf6031002
#define FSTV0910_TSRCINSDEL_CRC8 0xf6030001
/* RCINSDEL1 */
#define RSTV0910_RCINSDEL1 0xf604
-#define FSTV0910_TSRCINS_BBPADDING 0xf6040080
-#define FSTV0910_TSRCINS_BCHFEC 0xf6040040
-#define FSTV0910_TSRCINS_EMODCOD 0xf6040010
-#define FSTV0910_TSRCINS_TOKEN 0xf6040008
-#define FSTV0910_TSRCINS_XXXERR 0xf6040004
-#define FSTV0910_TSRCINS_MATYPE 0xf6040002
+#define FSTV0910_TSRCINS_BBPADDING 0xf6047080
+#define FSTV0910_TSRCINS_BCHFEC 0xf6046040
+#define FSTV0910_TSRCINS_EMODCOD 0xf6044010
+#define FSTV0910_TSRCINS_TOKEN 0xf6043008
+#define FSTV0910_TSRCINS_XXXERR 0xf6042004
+#define FSTV0910_TSRCINS_MATYPE 0xf6041002
#define FSTV0910_TSRCINS_UPL 0xf6040001
/* RCINSDEL0 */
#define RSTV0910_RCINSDEL0 0xf605
-#define FSTV0910_TSRCINS_DFL 0xf6050080
-#define FSTV0910_TSRCINS_SYNCD 0xf6050040
-#define FSTV0910_TSRCINS_BLOCLEN 0xf6050020
-#define FSTV0910_TSRCINS_SIGPCOUNT 0xf6050010
-#define FSTV0910_TSRCINS_FIFO 0xf6050008
-#define FSTV0910_TSRCINS_REALPACK 0xf6050004
-#define FSTV0910_TSRCINS_TSCONFIG 0xf6050002
+#define FSTV0910_TSRCINS_DFL 0xf6057080
+#define FSTV0910_TSRCINS_SYNCD 0xf6056040
+#define FSTV0910_TSRCINS_BLOCLEN 0xf6055020
+#define FSTV0910_TSRCINS_SIGPCOUNT 0xf6054010
+#define FSTV0910_TSRCINS_FIFO 0xf6053008
+#define FSTV0910_TSRCINS_REALPACK 0xf6052004
+#define FSTV0910_TSRCINS_TSCONFIG 0xf6051002
#define FSTV0910_TSRCINS_LATENCY 0xf6050001
/* RCSTATUS */
#define RSTV0910_RCSTATUS 0xf606
-#define FSTV0910_TSRCFIFO_LINEOK 0xf6060080
-#define FSTV0910_TSRCFIFO_ERROR 0xf6060040
-#define FSTV0910_TSRCREGUL_ERROR 0xf6060010
-#define FSTV0910_TSRCFIFO_DEMODSEL 0xf6060008
-#define FSTV0910_TSRCFIFOSPEED_STORE 0xf6060004
+#define FSTV0910_TSRCFIFO_LINEOK 0xf6067080
+#define FSTV0910_TSRCFIFO_ERROR 0xf6066040
+#define FSTV0910_TSRCREGUL_ERROR 0xf6064010
+#define FSTV0910_TSRCFIFO_DEMODSEL 0xf6063008
+#define FSTV0910_TSRCFIFOSPEED_STORE 0xf6062004
#define FSTV0910_TSRCSPEED_IMPOSSIBLE 0xf6060001
/* RCSPEED */
@@ -3684,47 +3684,47 @@
/* TSGENERAL */
#define RSTV0910_TSGENERAL 0xf630
-#define FSTV0910_TSFIFO_DISTS2PAR 0xf6300040
-#define FSTV0910_MUXSTREAM_OUTMODE 0xf6300008
-#define FSTV0910_TSFIFO_PERMPARAL 0xf6300006
+#define FSTV0910_TSFIFO_DISTS2PAR 0xf6306040
+#define FSTV0910_MUXSTREAM_OUTMODE 0xf6303008
+#define FSTV0910_TSFIFO_PERMPARAL 0xf6301006
/* P1_DISIRQCFG */
#define RSTV0910_P1_DISIRQCFG 0xf700
-#define FSTV0910_P1_ENRXEND 0xf7000040
-#define FSTV0910_P1_ENRXFIFO8B 0xf7000020
-#define FSTV0910_P1_ENTRFINISH 0xf7000010
-#define FSTV0910_P1_ENTIMEOUT 0xf7000008
-#define FSTV0910_P1_ENTXEND 0xf7000004
-#define FSTV0910_P1_ENTXFIFO64B 0xf7000002
+#define FSTV0910_P1_ENRXEND 0xf7006040
+#define FSTV0910_P1_ENRXFIFO8B 0xf7005020
+#define FSTV0910_P1_ENTRFINISH 0xf7004010
+#define FSTV0910_P1_ENTIMEOUT 0xf7003008
+#define FSTV0910_P1_ENTXEND 0xf7002004
+#define FSTV0910_P1_ENTXFIFO64B 0xf7001002
#define FSTV0910_P1_ENGAPBURST 0xf7000001
/* P1_DISIRQSTAT */
#define RSTV0910_P1_DISIRQSTAT 0xf701
-#define FSTV0910_P1_IRQRXEND 0xf7010040
-#define FSTV0910_P1_IRQRXFIFO8B 0xf7010020
-#define FSTV0910_P1_IRQTRFINISH 0xf7010010
-#define FSTV0910_P1_IRQTIMEOUT 0xf7010008
-#define FSTV0910_P1_IRQTXEND 0xf7010004
-#define FSTV0910_P1_IRQTXFIFO64B 0xf7010002
+#define FSTV0910_P1_IRQRXEND 0xf7016040
+#define FSTV0910_P1_IRQRXFIFO8B 0xf7015020
+#define FSTV0910_P1_IRQTRFINISH 0xf7014010
+#define FSTV0910_P1_IRQTIMEOUT 0xf7013008
+#define FSTV0910_P1_IRQTXEND 0xf7012004
+#define FSTV0910_P1_IRQTXFIFO64B 0xf7011002
#define FSTV0910_P1_IRQGAPBURST 0xf7010001
/* P1_DISTXCFG */
#define RSTV0910_P1_DISTXCFG 0xf702
-#define FSTV0910_P1_DISTX_RESET 0xf7020080
-#define FSTV0910_P1_TIM_OFF 0xf7020040
-#define FSTV0910_P1_TIM_CMD 0xf7020030
-#define FSTV0910_P1_ENVELOP 0xf7020008
-#define FSTV0910_P1_DIS_PRECHARGE 0xf7020004
+#define FSTV0910_P1_DISTX_RESET 0xf7027080
+#define FSTV0910_P1_TIM_OFF 0xf7026040
+#define FSTV0910_P1_TIM_CMD 0xf7024030
+#define FSTV0910_P1_ENVELOP 0xf7023008
+#define FSTV0910_P1_DIS_PRECHARGE 0xf7022004
#define FSTV0910_P1_DISEQC_MODE 0xf7020003
/* P1_DISTXSTATUS */
#define RSTV0910_P1_DISTXSTATUS 0xf703
-#define FSTV0910_P1_TX_FIFO_FULL 0xf7030040
-#define FSTV0910_P1_TX_IDLE 0xf7030020
-#define FSTV0910_P1_GAP_BURST 0xf7030010
-#define FSTV0910_P1_TX_FIFO64B 0xf7030008
-#define FSTV0910_P1_TX_END 0xf7030004
-#define FSTV0910_P1_TR_TIMEOUT 0xf7030002
+#define FSTV0910_P1_TX_FIFO_FULL 0xf7036040
+#define FSTV0910_P1_TX_IDLE 0xf7035020
+#define FSTV0910_P1_GAP_BURST 0xf7034010
+#define FSTV0910_P1_TX_FIFO64B 0xf7033008
+#define FSTV0910_P1_TX_END 0xf7032004
+#define FSTV0910_P1_TR_TIMEOUT 0xf7031002
#define FSTV0910_P1_TR_FINISH 0xf7030001
/* P1_DISTXBYTES */
@@ -3741,7 +3741,7 @@
/* P1_DISTIMEOCFG */
#define RSTV0910_P1_DISTIMEOCFG 0xf708
-#define FSTV0910_P1_RXCHOICE 0xf7080006
+#define FSTV0910_P1_RXCHOICE 0xf7081006
#define FSTV0910_P1_TIMEOUT_OFF 0xf7080001
/* P1_DISTIMEOUT */
@@ -3750,30 +3750,30 @@
/* P1_DISRXCFG */
#define RSTV0910_P1_DISRXCFG 0xf70a
-#define FSTV0910_P1_DISRX_RESET 0xf70a0080
-#define FSTV0910_P1_EXTENVELOP 0xf70a0040
-#define FSTV0910_P1_PINSELECT 0xf70a0038
-#define FSTV0910_P1_IGNORE_SHORT22K 0xf70a0004
-#define FSTV0910_P1_SIGNED_RXIN 0xf70a0002
+#define FSTV0910_P1_DISRX_RESET 0xf70a7080
+#define FSTV0910_P1_EXTENVELOP 0xf70a6040
+#define FSTV0910_P1_PINSELECT 0xf70a3038
+#define FSTV0910_P1_IGNORE_SHORT22K 0xf70a2004
+#define FSTV0910_P1_SIGNED_RXIN 0xf70a1002
#define FSTV0910_P1_DISRX_ON 0xf70a0001
/* P1_DISRXSTAT1 */
#define RSTV0910_P1_DISRXSTAT1 0xf70b
-#define FSTV0910_P1_RXEND 0xf70b0080
-#define FSTV0910_P1_RXACTIVE 0xf70b0040
-#define FSTV0910_P1_RXDETECT 0xf70b0020
-#define FSTV0910_P1_CONTTONE 0xf70b0010
-#define FSTV0910_P1_8BFIFOREADY 0xf70b0008
-#define FSTV0910_P1_FIFOEMPTY 0xf70b0004
+#define FSTV0910_P1_RXEND 0xf70b7080
+#define FSTV0910_P1_RXACTIVE 0xf70b6040
+#define FSTV0910_P1_RXDETECT 0xf70b5020
+#define FSTV0910_P1_CONTTONE 0xf70b4010
+#define FSTV0910_P1_8BFIFOREADY 0xf70b3008
+#define FSTV0910_P1_FIFOEMPTY 0xf70b2004
/* P1_DISRXSTAT0 */
#define RSTV0910_P1_DISRXSTAT0 0xf70c
-#define FSTV0910_P1_RXFAIL 0xf70c0080
-#define FSTV0910_P1_FIFOPFAIL 0xf70c0040
-#define FSTV0910_P1_RXNONBYTE 0xf70c0020
-#define FSTV0910_P1_FIFOOVF 0xf70c0010
-#define FSTV0910_P1_SHORT22K 0xf70c0008
-#define FSTV0910_P1_RXMSGLOST 0xf70c0004
+#define FSTV0910_P1_RXFAIL 0xf70c7080
+#define FSTV0910_P1_FIFOPFAIL 0xf70c6040
+#define FSTV0910_P1_RXNONBYTE 0xf70c5020
+#define FSTV0910_P1_FIFOOVF 0xf70c4010
+#define FSTV0910_P1_SHORT22K 0xf70c3008
+#define FSTV0910_P1_RXMSGLOST 0xf70c2004
/* P1_DISRXBYTES */
#define RSTV0910_P1_DISRXBYTES 0xf70d
@@ -3825,41 +3825,41 @@
/* P2_DISIRQCFG */
#define RSTV0910_P2_DISIRQCFG 0xf740
-#define FSTV0910_P2_ENRXEND 0xf7400040
-#define FSTV0910_P2_ENRXFIFO8B 0xf7400020
-#define FSTV0910_P2_ENTRFINISH 0xf7400010
-#define FSTV0910_P2_ENTIMEOUT 0xf7400008
-#define FSTV0910_P2_ENTXEND 0xf7400004
-#define FSTV0910_P2_ENTXFIFO64B 0xf7400002
+#define FSTV0910_P2_ENRXEND 0xf7406040
+#define FSTV0910_P2_ENRXFIFO8B 0xf7405020
+#define FSTV0910_P2_ENTRFINISH 0xf7404010
+#define FSTV0910_P2_ENTIMEOUT 0xf7403008
+#define FSTV0910_P2_ENTXEND 0xf7402004
+#define FSTV0910_P2_ENTXFIFO64B 0xf7401002
#define FSTV0910_P2_ENGAPBURST 0xf7400001
/* P2_DISIRQSTAT */
#define RSTV0910_P2_DISIRQSTAT 0xf741
-#define FSTV0910_P2_IRQRXEND 0xf7410040
-#define FSTV0910_P2_IRQRXFIFO8B 0xf7410020
-#define FSTV0910_P2_IRQTRFINISH 0xf7410010
-#define FSTV0910_P2_IRQTIMEOUT 0xf7410008
-#define FSTV0910_P2_IRQTXEND 0xf7410004
-#define FSTV0910_P2_IRQTXFIFO64B 0xf7410002
+#define FSTV0910_P2_IRQRXEND 0xf7416040
+#define FSTV0910_P2_IRQRXFIFO8B 0xf7415020
+#define FSTV0910_P2_IRQTRFINISH 0xf7414010
+#define FSTV0910_P2_IRQTIMEOUT 0xf7413008
+#define FSTV0910_P2_IRQTXEND 0xf7412004
+#define FSTV0910_P2_IRQTXFIFO64B 0xf7411002
#define FSTV0910_P2_IRQGAPBURST 0xf7410001
/* P2_DISTXCFG */
#define RSTV0910_P2_DISTXCFG 0xf742
-#define FSTV0910_P2_DISTX_RESET 0xf7420080
-#define FSTV0910_P2_TIM_OFF 0xf7420040
-#define FSTV0910_P2_TIM_CMD 0xf7420030
-#define FSTV0910_P2_ENVELOP 0xf7420008
-#define FSTV0910_P2_DIS_PRECHARGE 0xf7420004
+#define FSTV0910_P2_DISTX_RESET 0xf7427080
+#define FSTV0910_P2_TIM_OFF 0xf7426040
+#define FSTV0910_P2_TIM_CMD 0xf7424030
+#define FSTV0910_P2_ENVELOP 0xf7423008
+#define FSTV0910_P2_DIS_PRECHARGE 0xf7422004
#define FSTV0910_P2_DISEQC_MODE 0xf7420003
/* P2_DISTXSTATUS */
#define RSTV0910_P2_DISTXSTATUS 0xf743
-#define FSTV0910_P2_TX_FIFO_FULL 0xf7430040
-#define FSTV0910_P2_TX_IDLE 0xf7430020
-#define FSTV0910_P2_GAP_BURST 0xf7430010
-#define FSTV0910_P2_TX_FIFO64B 0xf7430008
-#define FSTV0910_P2_TX_END 0xf7430004
-#define FSTV0910_P2_TR_TIMEOUT 0xf7430002
+#define FSTV0910_P2_TX_FIFO_FULL 0xf7436040
+#define FSTV0910_P2_TX_IDLE 0xf7435020
+#define FSTV0910_P2_GAP_BURST 0xf7434010
+#define FSTV0910_P2_TX_FIFO64B 0xf7433008
+#define FSTV0910_P2_TX_END 0xf7432004
+#define FSTV0910_P2_TR_TIMEOUT 0xf7431002
#define FSTV0910_P2_TR_FINISH 0xf7430001
/* P2_DISTXBYTES */
@@ -3876,7 +3876,7 @@
/* P2_DISTIMEOCFG */
#define RSTV0910_P2_DISTIMEOCFG 0xf748
-#define FSTV0910_P2_RXCHOICE 0xf7480006
+#define FSTV0910_P2_RXCHOICE 0xf7481006
#define FSTV0910_P2_TIMEOUT_OFF 0xf7480001
/* P2_DISTIMEOUT */
@@ -3885,30 +3885,30 @@
/* P2_DISRXCFG */
#define RSTV0910_P2_DISRXCFG 0xf74a
-#define FSTV0910_P2_DISRX_RESET 0xf74a0080
-#define FSTV0910_P2_EXTENVELOP 0xf74a0040
-#define FSTV0910_P2_PINSELECT 0xf74a0038
-#define FSTV0910_P2_IGNORE_SHORT22K 0xf74a0004
-#define FSTV0910_P2_SIGNED_RXIN 0xf74a0002
+#define FSTV0910_P2_DISRX_RESET 0xf74a7080
+#define FSTV0910_P2_EXTENVELOP 0xf74a6040
+#define FSTV0910_P2_PINSELECT 0xf74a3038
+#define FSTV0910_P2_IGNORE_SHORT22K 0xf74a2004
+#define FSTV0910_P2_SIGNED_RXIN 0xf74a1002
#define FSTV0910_P2_DISRX_ON 0xf74a0001
/* P2_DISRXSTAT1 */
#define RSTV0910_P2_DISRXSTAT1 0xf74b
-#define FSTV0910_P2_RXEND 0xf74b0080
-#define FSTV0910_P2_RXACTIVE 0xf74b0040
-#define FSTV0910_P2_RXDETECT 0xf74b0020
-#define FSTV0910_P2_CONTTONE 0xf74b0010
-#define FSTV0910_P2_8BFIFOREADY 0xf74b0008
-#define FSTV0910_P2_FIFOEMPTY 0xf74b0004
+#define FSTV0910_P2_RXEND 0xf74b7080
+#define FSTV0910_P2_RXACTIVE 0xf74b6040
+#define FSTV0910_P2_RXDETECT 0xf74b5020
+#define FSTV0910_P2_CONTTONE 0xf74b4010
+#define FSTV0910_P2_8BFIFOREADY 0xf74b3008
+#define FSTV0910_P2_FIFOEMPTY 0xf74b2004
/* P2_DISRXSTAT0 */
#define RSTV0910_P2_DISRXSTAT0 0xf74c
-#define FSTV0910_P2_RXFAIL 0xf74c0080
-#define FSTV0910_P2_FIFOPFAIL 0xf74c0040
-#define FSTV0910_P2_RXNONBYTE 0xf74c0020
-#define FSTV0910_P2_FIFOOVF 0xf74c0010
-#define FSTV0910_P2_SHORT22K 0xf74c0008
-#define FSTV0910_P2_RXMSGLOST 0xf74c0004
+#define FSTV0910_P2_RXFAIL 0xf74c7080
+#define FSTV0910_P2_FIFOPFAIL 0xf74c6040
+#define FSTV0910_P2_RXNONBYTE 0xf74c5020
+#define FSTV0910_P2_FIFOOVF 0xf74c4010
+#define FSTV0910_P2_SHORT22K 0xf74c3008
+#define FSTV0910_P2_RXMSGLOST 0xf74c2004
/* P2_DISRXBYTES */
#define RSTV0910_P2_DISRXBYTES 0xf74d
@@ -4168,75 +4168,75 @@
/* SELSATUR6 */
#define RSTV0910_SELSATUR6 0xfa34
-#define FSTV0910_SSAT_SF27 0xfa340008
-#define FSTV0910_SSAT_SF26 0xfa340004
-#define FSTV0910_SSAT_SF25 0xfa340002
+#define FSTV0910_SSAT_SF27 0xfa343008
+#define FSTV0910_SSAT_SF26 0xfa342004
+#define FSTV0910_SSAT_SF25 0xfa341002
#define FSTV0910_SSAT_SF24 0xfa340001
/* SELSATUR5 */
#define RSTV0910_SELSATUR5 0xfa35
-#define FSTV0910_SSAT_SF22 0xfa350080
-#define FSTV0910_SSAT_SF21 0xfa350040
-#define FSTV0910_SSAT_SF20 0xfa350020
-#define FSTV0910_SSAT_SF19 0xfa350010
-#define FSTV0910_SSAT_SF18 0xfa350008
-#define FSTV0910_SSAT_SF16 0xfa350004
-#define FSTV0910_SSAT_SF15 0xfa350002
+#define FSTV0910_SSAT_SF22 0xfa357080
+#define FSTV0910_SSAT_SF21 0xfa356040
+#define FSTV0910_SSAT_SF20 0xfa355020
+#define FSTV0910_SSAT_SF19 0xfa354010
+#define FSTV0910_SSAT_SF18 0xfa353008
+#define FSTV0910_SSAT_SF16 0xfa352004
+#define FSTV0910_SSAT_SF15 0xfa351002
#define FSTV0910_SSAT_SF14 0xfa350001
/* SELSATUR4 */
#define RSTV0910_SELSATUR4 0xfa36
-#define FSTV0910_SSAT_SF13 0xfa360080
-#define FSTV0910_SSAT_SF12 0xfa360040
-#define FSTV0910_SSAT_SF10 0xfa360020
-#define FSTV0910_SSAT_SF9 0xfa360010
-#define FSTV0910_SSAT_SF8 0xfa360008
-#define FSTV0910_SSAT_SF7 0xfa360004
-#define FSTV0910_SSAT_SF6 0xfa360002
+#define FSTV0910_SSAT_SF13 0xfa367080
+#define FSTV0910_SSAT_SF12 0xfa366040
+#define FSTV0910_SSAT_SF10 0xfa365020
+#define FSTV0910_SSAT_SF9 0xfa364010
+#define FSTV0910_SSAT_SF8 0xfa363008
+#define FSTV0910_SSAT_SF7 0xfa362004
+#define FSTV0910_SSAT_SF6 0xfa361002
#define FSTV0910_SSAT_SF5 0xfa360001
/* SELSATUR3 */
#define RSTV0910_SELSATUR3 0xfa37
-#define FSTV0910_SSAT_SF4 0xfa370080
-#define FSTV0910_SSAT_SF3 0xfa370040
-#define FSTV0910_SSAT_SF2 0xfa370020
-#define FSTV0910_SSAT_SF1 0xfa370010
-#define FSTV0910_SSAT_NF28 0xfa370008
-#define FSTV0910_SSAT_NF27 0xfa370004
-#define FSTV0910_SSAT_NF26 0xfa370002
+#define FSTV0910_SSAT_SF4 0xfa377080
+#define FSTV0910_SSAT_SF3 0xfa376040
+#define FSTV0910_SSAT_SF2 0xfa375020
+#define FSTV0910_SSAT_SF1 0xfa374010
+#define FSTV0910_SSAT_NF28 0xfa373008
+#define FSTV0910_SSAT_NF27 0xfa372004
+#define FSTV0910_SSAT_NF26 0xfa371002
#define FSTV0910_SSAT_NF25 0xfa370001
/* SELSATUR2 */
#define RSTV0910_SELSATUR2 0xfa38
-#define FSTV0910_SSAT_NF24 0xfa380080
-#define FSTV0910_SSAT_NF23 0xfa380040
-#define FSTV0910_SSAT_NF22 0xfa380020
-#define FSTV0910_SSAT_NF21 0xfa380010
-#define FSTV0910_SSAT_NF20 0xfa380008
-#define FSTV0910_SSAT_NF19 0xfa380004
-#define FSTV0910_SSAT_NF18 0xfa380002
+#define FSTV0910_SSAT_NF24 0xfa387080
+#define FSTV0910_SSAT_NF23 0xfa386040
+#define FSTV0910_SSAT_NF22 0xfa385020
+#define FSTV0910_SSAT_NF21 0xfa384010
+#define FSTV0910_SSAT_NF20 0xfa383008
+#define FSTV0910_SSAT_NF19 0xfa382004
+#define FSTV0910_SSAT_NF18 0xfa381002
#define FSTV0910_SSAT_NF17 0xfa380001
/* SELSATUR1 */
#define RSTV0910_SELSATUR1 0xfa39
-#define FSTV0910_SSAT_NF16 0xfa390080
-#define FSTV0910_SSAT_NF15 0xfa390040
-#define FSTV0910_SSAT_NF14 0xfa390020
-#define FSTV0910_SSAT_NF13 0xfa390010
-#define FSTV0910_SSAT_NF12 0xfa390008
-#define FSTV0910_SSAT_NF11 0xfa390004
-#define FSTV0910_SSAT_NF10 0xfa390002
+#define FSTV0910_SSAT_NF16 0xfa397080
+#define FSTV0910_SSAT_NF15 0xfa396040
+#define FSTV0910_SSAT_NF14 0xfa395020
+#define FSTV0910_SSAT_NF13 0xfa394010
+#define FSTV0910_SSAT_NF12 0xfa393008
+#define FSTV0910_SSAT_NF11 0xfa392004
+#define FSTV0910_SSAT_NF10 0xfa391002
#define FSTV0910_SSAT_NF9 0xfa390001
/* SELSATUR0 */
#define RSTV0910_SELSATUR0 0xfa3a
-#define FSTV0910_SSAT_NF8 0xfa3a0080
-#define FSTV0910_SSAT_NF7 0xfa3a0040
-#define FSTV0910_SSAT_NF6 0xfa3a0020
-#define FSTV0910_SSAT_NF5 0xfa3a0010
-#define FSTV0910_SSAT_NF4 0xfa3a0008
-#define FSTV0910_SSAT_NF3 0xfa3a0004
-#define FSTV0910_SSAT_NF2 0xfa3a0002
+#define FSTV0910_SSAT_NF8 0xfa3a7080
+#define FSTV0910_SSAT_NF7 0xfa3a6040
+#define FSTV0910_SSAT_NF6 0xfa3a5020
+#define FSTV0910_SSAT_NF5 0xfa3a4010
+#define FSTV0910_SSAT_NF4 0xfa3a3008
+#define FSTV0910_SSAT_NF3 0xfa3a2004
+#define FSTV0910_SSAT_NF2 0xfa3a1002
#define FSTV0910_SSAT_NF1 0xfa3a0001
/* GAINLLR_NF1 */
@@ -4449,14 +4449,14 @@
/* CFGEXT */
#define RSTV0910_CFGEXT 0xfa80
-#define FSTV0910_BYPBCH 0xfa800040
-#define FSTV0910_BYPLDPC 0xfa800020
-#define FSTV0910_SHORTMULT 0xfa800004
+#define FSTV0910_BYPBCH 0xfa806040
+#define FSTV0910_BYPLDPC 0xfa805020
+#define FSTV0910_SHORTMULT 0xfa802004
/* GENCFG */
#define RSTV0910_GENCFG 0xfa86
-#define FSTV0910_BROADCAST 0xfa860010
-#define FSTV0910_CROSSINPUT 0xfa860002
+#define FSTV0910_BROADCAST 0xfa864010
+#define FSTV0910_CROSSINPUT 0xfa861002
#define FSTV0910_DDEMOD 0xfa860001
/* LDPCERR1 */
@@ -4469,7 +4469,7 @@
/* BCHERR */
#define RSTV0910_BCHERR 0xfa98
-#define FSTV0910_ERRORFLAG 0xfa980010
+#define FSTV0910_ERRORFLAG 0xfa984010
#define FSTV0910_BCH_ERRORS_COUNTER 0xfa98000f
/* P1_MAXEXTRAITER */
@@ -4706,22 +4706,22 @@
/* TSTRES0 */
#define RSTV0910_TSTRES0 0xff11
-#define FSTV0910_FRESFEC 0xff110080
-#define FSTV0910_FRESSYM1 0xff110008
-#define FSTV0910_FRESSYM2 0xff110004
+#define FSTV0910_FRESFEC 0xff117080
+#define FSTV0910_FRESSYM1 0xff113008
+#define FSTV0910_FRESSYM2 0xff112004
/* TSTOUT */
#define RSTV0910_TSTOUT 0xff12
-#define FSTV0910_TS 0xff12003e
+#define FSTV0910_TS 0xff12103e
#define FSTV0910_TEST_OUT 0xff120001
/* TSTIN */
#define RSTV0910_TSTIN 0xff13
-#define FSTV0910_TEST_IN 0xff130080
+#define FSTV0910_TEST_IN 0xff137080
/* P2_TSTDMD */
#define RSTV0910_P2_TSTDMD 0xff20
-#define FSTV0910_P2_CFRINIT_INVZIGZAG 0xff200008
+#define FSTV0910_P2_CFRINIT_INVZIGZAG 0xff203008
/* P2_TCTL1 */
#define RSTV0910_P2_TCTL1 0xff24
@@ -4729,15 +4729,15 @@
/* P2_TCTL4 */
#define RSTV0910_P2_TCTL4 0xff28
-#define FSTV0910_P2_CFR2TOCFR1_DVBS1 0xff2800c0
+#define FSTV0910_P2_CFR2TOCFR1_DVBS1 0xff2860c0
/* P2_TPKTDELIN */
#define RSTV0910_P2_TPKTDELIN 0xff37
-#define FSTV0910_P2_CFG_RSPARITYON 0xff370080
+#define FSTV0910_P2_CFG_RSPARITYON 0xff377080
/* P1_TSTDMD */
#define RSTV0910_P1_TSTDMD 0xff40
-#define FSTV0910_P1_CFRINIT_INVZIGZAG 0xff400008
+#define FSTV0910_P1_CFRINIT_INVZIGZAG 0xff403008
/* P1_TCTL1 */
#define RSTV0910_P1_TCTL1 0xff44
@@ -4745,16 +4745,16 @@
/* P1_TCTL4 */
#define RSTV0910_P1_TCTL4 0xff48
-#define FSTV0910_P1_CFR2TOCFR1_DVBS1 0xff4800c0
+#define FSTV0910_P1_CFR2TOCFR1_DVBS1 0xff4860c0
/* P1_TPKTDELIN */
#define RSTV0910_P1_TPKTDELIN 0xff57
-#define FSTV0910_P1_CFG_RSPARITYON 0xff570080
+#define FSTV0910_P1_CFG_RSPARITYON 0xff577080
/* TSTTSRS */
#define RSTV0910_TSTTSRS 0xff6d
-#define FSTV0910_TSTRS_DISRS2 0xff6d0002
+#define FSTV0910_TSTRS_DISRS2 0xff6d1002
#define FSTV0910_TSTRS_DISRS1 0xff6d0001
-#define STV0910_NBREGS 975
-#define STV0910_NBFIELDS 1818
+#define STV0910_NBREGS 975
+#define STV0910_NBFIELDS 1818
diff --git a/drivers/media/dvb-frontends/stv6110.h b/drivers/media/dvb-frontends/stv6110.h
index ab73124c0dec..ecfc1faba15c 100644
--- a/drivers/media/dvb-frontends/stv6110.h
+++ b/drivers/media/dvb-frontends/stv6110.h
@@ -22,7 +22,7 @@
#define __DVB_STV6110_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/* registers */
#define RSTV6110_CTRL1 0
diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c
index 66eba38f1014..d8950028d021 100644
--- a/drivers/media/dvb-frontends/stv6110x.c
+++ b/drivers/media/dvb-frontends/stv6110x.c
@@ -26,7 +26,7 @@
#include <linux/slab.h>
#include <linux/string.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "stv6110x_reg.h"
#include "stv6110x.h"
@@ -46,7 +46,7 @@ static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
u8 b0[] = { reg };
u8 b1[] = { 0 };
struct i2c_msg msg[] = {
- { .addr = config->addr, .flags = 0, .buf = b0, .len = 1 },
+ { .addr = config->addr, .flags = 0, .buf = b0, .len = 1 },
{ .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }
};
@@ -97,7 +97,9 @@ static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 da
static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
{
- return stv6110x_write_regs(stv6110x, reg, &data, 1);
+ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+ return stv6110x_write_regs(stv6110x, reg, &tmp, 1);
}
static int stv6110x_init(struct dvb_frontend *fe)
diff --git a/drivers/media/dvb-frontends/stv6110x_priv.h b/drivers/media/dvb-frontends/stv6110x_priv.h
index a993aba27b7e..109dfaf4ba42 100644
--- a/drivers/media/dvb-frontends/stv6110x_priv.h
+++ b/drivers/media/dvb-frontends/stv6110x_priv.h
@@ -48,11 +48,11 @@
#define STV6110x_SETFIELD(mask, bitf, val) \
(mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) << \
- STV6110x_OFFST_##bitf))) | \
+ STV6110x_OFFST_##bitf))) | \
(val << STV6110x_OFFST_##bitf))
#define STV6110x_GETFIELD(bitf, val) \
- ((val >> STV6110x_OFFST_##bitf) & \
+ ((val >> STV6110x_OFFST_##bitf) & \
((1 << STV6110x_WIDTH_##bitf) - 1))
#define MAKEWORD16(a, b) (((a) << 8) | (b))
@@ -68,7 +68,7 @@
struct stv6110x_state {
struct i2c_adapter *i2c;
const struct stv6110x_config *config;
- u8 regs[8];
+ u8 regs[8];
const struct stv6110x_devctl *devctl;
};
diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c
index e3e90070e293..9b715b6fe152 100644
--- a/drivers/media/dvb-frontends/stv6111.c
+++ b/drivers/media/dvb-frontends/stv6111.c
@@ -25,7 +25,7 @@
#include "stv6111.h"
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct stv {
struct i2c_adapter *i2c;
@@ -424,6 +424,7 @@ static int set_bandwidth(struct dvb_frontend *fe, u32 cutoff_frequency)
{
struct stv *state = fe->tuner_priv;
u32 index = (cutoff_frequency + 999999) / 1000000;
+ int stat = 0;
if (index < 6)
index = 6;
@@ -435,12 +436,14 @@ static int set_bandwidth(struct dvb_frontend *fe, u32 cutoff_frequency)
state->reg[0x08] = (state->reg[0x08] & ~0xFC) | ((index - 6) << 2);
state->reg[0x09] = (state->reg[0x09] & ~0x0C) | 0x08;
if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- write_regs(state, 0x08, 2);
- wait_for_call_done(state, 0x08);
- if (fe->ops.i2c_gate_ctrl)
+ stat = fe->ops.i2c_gate_ctrl(fe, 1);
+ if (!stat) {
+ write_regs(state, 0x08, 2);
+ wait_for_call_done(state, 0x08);
+ }
+ if (fe->ops.i2c_gate_ctrl && !stat)
fe->ops.i2c_gate_ctrl(fe, 0);
- return 0;
+ return stat;
}
static int set_lof(struct stv *state, u32 local_frequency, u32 cutoff_frequency)
@@ -518,6 +521,7 @@ static int set_params(struct dvb_frontend *fe)
struct stv *state = fe->tuner_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
u32 freq, cutoff;
+ int stat = 0;
if (p->delivery_system != SYS_DVBS && p->delivery_system != SYS_DVBS2)
return -EINVAL;
@@ -526,9 +530,10 @@ static int set_params(struct dvb_frontend *fe)
cutoff = 5000000 + muldiv32(p->symbol_rate, 135, 200);
if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- set_lof(state, freq, cutoff);
- if (fe->ops.i2c_gate_ctrl)
+ stat = fe->ops.i2c_gate_ctrl(fe, 1);
+ if (!stat)
+ set_lof(state, freq, cutoff);
+ if (fe->ops.i2c_gate_ctrl && !stat)
fe->ops.i2c_gate_ctrl(fe, 0);
return 0;
}
@@ -575,14 +580,17 @@ static int get_rf_strength(struct dvb_frontend *fe, u16 *st)
if ((state->reg[0x03] & 0x60) == 0) {
/* RF Mode, Read AGC ADC */
u8 reg = 0;
+ int stat = 0;
if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- write_reg(state, 0x02, state->reg[0x02] | 0x20);
- read_reg(state, 2, &reg);
- if (reg & 0x20)
+ stat = fe->ops.i2c_gate_ctrl(fe, 1);
+ if (!stat) {
+ write_reg(state, 0x02, state->reg[0x02] | 0x20);
read_reg(state, 2, &reg);
- if (fe->ops.i2c_gate_ctrl)
+ if (reg & 0x20)
+ read_reg(state, 2, &reg);
+ }
+ if (fe->ops.i2c_gate_ctrl && !stat)
fe->ops.i2c_gate_ctrl(fe, 0);
if ((state->reg[0x02] & 0x80) == 0)
@@ -652,7 +660,8 @@ struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, u8 adr)
{
struct stv *state;
- int stat;
+ int stat = -ENODEV;
+ int gatestat = 0;
state = kzalloc(sizeof(*state), GFP_KERNEL);
if (!state)
@@ -663,9 +672,10 @@ struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe,
init_state(state);
if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- stat = attach_init(state);
- if (fe->ops.i2c_gate_ctrl)
+ gatestat = fe->ops.i2c_gate_ctrl(fe, 1);
+ if (!gatestat)
+ stat = attach_init(state);
+ if (fe->ops.i2c_gate_ctrl && !gatestat)
fe->ops.i2c_gate_ctrl(fe, 0);
if (stat < 0) {
kfree(state);
diff --git a/drivers/media/dvb-frontends/tc90522.c b/drivers/media/dvb-frontends/tc90522.c
index 4687e1546af2..5572b39614d5 100644
--- a/drivers/media/dvb-frontends/tc90522.c
+++ b/drivers/media/dvb-frontends/tc90522.c
@@ -30,7 +30,7 @@
#include <linux/kernel.h>
#include <linux/math64.h>
#include <linux/dvb/frontend.h>
-#include "dvb_math.h"
+#include <media/dvb_math.h>
#include "tc90522.h"
#define TC90522_I2C_THRU_REG 0xfe
diff --git a/drivers/media/dvb-frontends/tc90522.h b/drivers/media/dvb-frontends/tc90522.h
index b1cbddfa6ee6..10e585f32499 100644
--- a/drivers/media/dvb-frontends/tc90522.h
+++ b/drivers/media/dvb-frontends/tc90522.h
@@ -25,7 +25,7 @@
#define TC90522_H
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/* I2C device types */
#define TC90522_I2C_DEV_SAT "tc90522sat"
diff --git a/drivers/media/dvb-frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c
index 32ba8401e743..4f588ebde39d 100644
--- a/drivers/media/dvb-frontends/tda10021.c
+++ b/drivers/media/dvb-frontends/tda10021.c
@@ -29,7 +29,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda1002x.h"
diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c
index 8028007c68eb..6c84916234e3 100644
--- a/drivers/media/dvb-frontends/tda10023.c
+++ b/drivers/media/dvb-frontends/tda10023.c
@@ -35,7 +35,7 @@
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda1002x.h"
#define REG0_INIT_VAL 0x23
@@ -211,7 +211,7 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
BDRX=1<<(24+NDEC);
BDRX*=sr;
- do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */
+ do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */
BDR=(s32)BDRX;
}
diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c
index 143b39b5f6c9..de82a2558e15 100644
--- a/drivers/media/dvb-frontends/tda10048.c
+++ b/drivers/media/dvb-frontends/tda10048.c
@@ -27,8 +27,8 @@
#include <linux/delay.h>
#include <linux/math64.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
#include "tda10048.h"
#define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw"
diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c
index e674508c349c..58e3beff5adc 100644
--- a/drivers/media/dvb-frontends/tda1004x.c
+++ b/drivers/media/dvb-frontends/tda1004x.c
@@ -36,7 +36,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda1004x.h"
static int debug;
diff --git a/drivers/media/dvb-frontends/tda10071_priv.h b/drivers/media/dvb-frontends/tda10071_priv.h
index b9c3601802ba..67c46e8a7201 100644
--- a/drivers/media/dvb-frontends/tda10071_priv.h
+++ b/drivers/media/dvb-frontends/tda10071_priv.h
@@ -21,7 +21,7 @@
#ifndef TDA10071_PRIV
#define TDA10071_PRIV
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda10071.h"
#include <linux/firmware.h>
#include <linux/regmap.h>
diff --git a/drivers/media/dvb-frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c
index b6d16c05904d..1a95c521e97f 100644
--- a/drivers/media/dvb-frontends/tda10086.c
+++ b/drivers/media/dvb-frontends/tda10086.c
@@ -27,7 +27,7 @@
#include <linux/string.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda10086.h"
#define SACLK 96000000
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c
index 2d2778be2d2f..2e1d36ae943b 100644
--- a/drivers/media/dvb-frontends/tda18271c2dd.c
+++ b/drivers/media/dvb-frontends/tda18271c2dd.c
@@ -27,7 +27,7 @@
#include <linux/i2c.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda18271c2dd.h"
/* Max transfer size done by I2C transfer functions */
@@ -674,7 +674,6 @@ static int PowerScan(struct tda_state *state,
Count = 200000;
wait = true;
}
- status = status;
if (status < 0)
break;
if (CID_Gain >= CID_Target) {
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.h b/drivers/media/dvb-frontends/tda18271c2dd.h
index 289653db68e4..afeb9536e9c9 100644
--- a/drivers/media/dvb-frontends/tda18271c2dd.h
+++ b/drivers/media/dvb-frontends/tda18271c2dd.h
@@ -9,8 +9,8 @@ struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
static inline struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, u8 adr)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
- return NULL;
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
}
#endif
diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c
index a63dec44295b..3ef7140ed7f3 100644
--- a/drivers/media/dvb-frontends/tda665x.c
+++ b/drivers/media/dvb-frontends/tda665x.c
@@ -22,7 +22,7 @@
#include <linux/module.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda665x.h"
struct tda665x_state {
diff --git a/drivers/media/dvb-frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c
index aa3200d3c352..29b4f64c030c 100644
--- a/drivers/media/dvb-frontends/tda8083.c
+++ b/drivers/media/dvb-frontends/tda8083.c
@@ -30,7 +30,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda8083.h"
diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c
index 4eb294f330bc..f72a54e7eb23 100644
--- a/drivers/media/dvb-frontends/tda8261.c
+++ b/drivers/media/dvb-frontends/tda8261.c
@@ -23,7 +23,7 @@
#include <linux/module.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda8261.h"
struct tda8261_state {
diff --git a/drivers/media/dvb-frontends/tda826x.h b/drivers/media/dvb-frontends/tda826x.h
index 6a7bed12e741..0ef35ff3807f 100644
--- a/drivers/media/dvb-frontends/tda826x.h
+++ b/drivers/media/dvb-frontends/tda826x.h
@@ -24,7 +24,7 @@
#define __DVB_TDA826X_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/**
* Attach a tda826x tuner to the supplied frontend structure.
diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c
index 931e5c98da8a..c55882a8da06 100644
--- a/drivers/media/dvb-frontends/ts2020.c
+++ b/drivers/media/dvb-frontends/ts2020.c
@@ -19,7 +19,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "ts2020.h"
#include <linux/regmap.h>
#include <linux/math64.h>
@@ -368,7 +368,7 @@ static int ts2020_read_tuner_gain(struct dvb_frontend *fe, unsigned v_agc,
gain2 = clamp_t(long, gain2, 0, 13);
v_agc = clamp_t(long, v_agc, 400, 1100);
- *_gain = -(gain1 * 2330 +
+ *_gain = -((__s64)gain1 * 2330 +
gain2 * 3500 +
v_agc * 24 / 10 * 10 +
10000);
@@ -386,7 +386,7 @@ static int ts2020_read_tuner_gain(struct dvb_frontend *fe, unsigned v_agc,
gain3 = clamp_t(long, gain3, 0, 6);
v_agc = clamp_t(long, v_agc, 600, 1600);
- *_gain = -(gain1 * 2650 +
+ *_gain = -((__s64)gain1 * 2650 +
gain2 * 3380 +
gain3 * 2850 +
v_agc * 176 / 100 * 10 -
diff --git a/drivers/media/dvb-frontends/tua6100.h b/drivers/media/dvb-frontends/tua6100.h
index 6c098a894ea6..a342bd9c7fbf 100644
--- a/drivers/media/dvb-frontends/tua6100.h
+++ b/drivers/media/dvb-frontends/tua6100.h
@@ -28,7 +28,7 @@
#define __DVB_TUA6100_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#if IS_REACHABLE(CONFIG_DVB_TUA6100)
extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c);
diff --git a/drivers/media/dvb-frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c
index 178363704bd4..1d8979289915 100644
--- a/drivers/media/dvb-frontends/ves1820.c
+++ b/drivers/media/dvb-frontends/ves1820.c
@@ -27,7 +27,7 @@
#include <linux/slab.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "ves1820.h"
diff --git a/drivers/media/dvb-frontends/ves1x93.c b/drivers/media/dvb-frontends/ves1x93.c
index d0ee52f66a8e..0c7b3286b04d 100644
--- a/drivers/media/dvb-frontends/ves1x93.c
+++ b/drivers/media/dvb-frontends/ves1x93.c
@@ -30,7 +30,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "ves1x93.h"
diff --git a/drivers/media/dvb-frontends/zd1301_demod.h b/drivers/media/dvb-frontends/zd1301_demod.h
index 6cd8f6f9c415..63c13fa4a54b 100644
--- a/drivers/media/dvb-frontends/zd1301_demod.h
+++ b/drivers/media/dvb-frontends/zd1301_demod.h
@@ -19,7 +19,7 @@
#include <linux/platform_device.h>
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/**
* struct zd1301_demod_platform_data - Platform data for the zd1301_demod driver
diff --git a/drivers/media/dvb-frontends/zl10036.h b/drivers/media/dvb-frontends/zl10036.h
index ec90ca927739..a1129ab74296 100644
--- a/drivers/media/dvb-frontends/zl10036.h
+++ b/drivers/media/dvb-frontends/zl10036.h
@@ -18,7 +18,7 @@
#define DVB_ZL10036_H
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct zl10036_config {
u8 tuner_address;
diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c
index 623355fc2666..6293bd920fa6 100644
--- a/drivers/media/dvb-frontends/zl10039.c
+++ b/drivers/media/dvb-frontends/zl10039.c
@@ -21,7 +21,7 @@
#include <linux/slab.h>
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "zl10039.h"
static int debug;
@@ -134,7 +134,9 @@ static inline int zl10039_writereg(struct zl10039_state *state,
const enum zl10039_reg_addr reg,
const u8 val)
{
- return zl10039_write(state, reg, &val, 1);
+ const u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
+
+ return zl10039_write(state, reg, &tmp, 1);
}
static int zl10039_init(struct dvb_frontend *fe)
diff --git a/drivers/media/dvb-frontends/zl10353.c b/drivers/media/dvb-frontends/zl10353.c
index 1c689f7f4ab8..c9901f45deb7 100644
--- a/drivers/media/dvb-frontends/zl10353.c
+++ b/drivers/media/dvb-frontends/zl10353.c
@@ -23,7 +23,7 @@
#include <linux/slab.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "zl10353_priv.h"
#include "zl10353.h"
diff --git a/drivers/media/firewire/Makefile b/drivers/media/firewire/Makefile
index 239481344d7c..f96049f5fa90 100644
--- a/drivers/media/firewire/Makefile
+++ b/drivers/media/firewire/Makefile
@@ -2,5 +2,3 @@ obj-$(CONFIG_DVB_FIREDTV) += firedtv.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-core
diff --git a/drivers/media/firewire/firedtv-avc.c b/drivers/media/firewire/firedtv-avc.c
index 5bde6c209cd7..1c933b2cf760 100644
--- a/drivers/media/firewire/firedtv-avc.c
+++ b/drivers/media/firewire/firedtv-avc.c
@@ -24,7 +24,7 @@
#include <linux/wait.h>
#include <linux/workqueue.h>
-#include <dvb_frontend.h>
+#include <media/dvb_frontend.h>
#include "firedtv.h"
@@ -47,7 +47,7 @@
#define AVC_OPCODE_DSIT 0xc8
#define AVC_OPCODE_DSD 0xcb
-#define DESCRIPTOR_TUNER_STATUS 0x80
+#define DESCRIPTOR_TUNER_STATUS 0x80
#define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00
#define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */
@@ -688,7 +688,7 @@ int avc_tuner_get_ts(struct firedtv *fdtv)
c->operand[2] = 0xff; /* status */
c->operand[3] = 0x20; /* system id = DVB */
c->operand[4] = 0x00; /* antenna number */
- c->operand[5] = 0x0; /* system_specific_search_flags */
+ c->operand[5] = 0x0; /* system_specific_search_flags */
c->operand[6] = sl; /* system_specific_multiplex selection_length */
/*
* operand[7]: valid_flags[0]
diff --git a/drivers/media/firewire/firedtv-ci.c b/drivers/media/firewire/firedtv-ci.c
index fb8a1d2ffd24..b4ddfff74267 100644
--- a/drivers/media/firewire/firedtv-ci.c
+++ b/drivers/media/firewire/firedtv-ci.c
@@ -15,7 +15,7 @@
#include <linux/fs.h>
#include <linux/module.h>
-#include <dvbdev.h>
+#include <media/dvbdev.h>
#include "firedtv.h"
diff --git a/drivers/media/firewire/firedtv-dvb.c b/drivers/media/firewire/firedtv-dvb.c
index f710e17953e3..2f7ac79215cc 100644
--- a/drivers/media/firewire/firedtv-dvb.c
+++ b/drivers/media/firewire/firedtv-dvb.c
@@ -18,10 +18,10 @@
#include <linux/mutex.h>
#include <linux/types.h>
-#include <dmxdev.h>
-#include <dvb_demux.h>
-#include <dvbdev.h>
-#include <dvb_frontend.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvbdev.h>
+#include <media/dvb_frontend.h>
#include "firedtv.h"
diff --git a/drivers/media/firewire/firedtv-fe.c b/drivers/media/firewire/firedtv-fe.c
index 17acda6bcb6e..a2ef4ede8ebe 100644
--- a/drivers/media/firewire/firedtv-fe.c
+++ b/drivers/media/firewire/firedtv-fe.c
@@ -16,7 +16,7 @@
#include <linux/string.h>
#include <linux/types.h>
-#include <dvb_frontend.h>
+#include <media/dvb_frontend.h>
#include "firedtv.h"
@@ -165,7 +165,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
ops->read_snr = fdtv_read_snr;
ops->read_ucblocks = fdtv_read_uncorrected_blocks;
- ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd;
+ ops->diseqc_send_master_cmd = fdtv_diseqc_send_master_cmd;
ops->diseqc_send_burst = fdtv_diseqc_send_burst;
ops->set_tone = fdtv_set_tone;
ops->set_voltage = fdtv_set_voltage;
@@ -220,7 +220,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
fi->symbol_rate_min = 870000;
fi->symbol_rate_max = 6900000;
- fi->caps = FE_CAN_INVERSION_AUTO |
+ fi->caps = FE_CAN_INVERSION_AUTO |
FE_CAN_QAM_16 |
FE_CAN_QAM_32 |
FE_CAN_QAM_64 |
@@ -236,7 +236,7 @@ void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
fi->frequency_max = 861000000;
fi->frequency_stepsize = 62500;
- fi->caps = FE_CAN_INVERSION_AUTO |
+ fi->caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_2_3 |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
diff --git a/drivers/media/firewire/firedtv-fw.c b/drivers/media/firewire/firedtv-fw.c
index 247f0e7cb5f7..92f4112d2e37 100644
--- a/drivers/media/firewire/firedtv-fw.c
+++ b/drivers/media/firewire/firedtv-fw.c
@@ -21,7 +21,7 @@
#include <asm/page.h>
-#include <dvb_demux.h>
+#include <media/dvb_demux.h>
#include "firedtv.h"
diff --git a/drivers/media/firewire/firedtv.h b/drivers/media/firewire/firedtv.h
index 345d1eda8c05..876cdec8329b 100644
--- a/drivers/media/firewire/firedtv.h
+++ b/drivers/media/firewire/firedtv.h
@@ -24,12 +24,12 @@
#include <linux/wait.h>
#include <linux/workqueue.h>
-#include <demux.h>
-#include <dmxdev.h>
-#include <dvb_demux.h>
-#include <dvb_frontend.h>
-#include <dvb_net.h>
-#include <dvbdev.h>
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
struct firedtv_tuner_status {
unsigned active_system:8;
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index cb5d7ff82915..9f18cd296841 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -665,6 +665,14 @@ config VIDEO_OV7670
OV7670 VGA camera. It currently only works with the M88ALP01
controller.
+config VIDEO_OV7740
+ tristate "OmniVision OV7740 sensor support"
+ depends on I2C && VIDEO_V4L2
+ depends on MEDIA_CAMERA_SUPPORT
+ ---help---
+ This is a Video4Linux2 sensor-level driver for the OmniVision
+ OV7740 VGA camera sensor.
+
config VIDEO_OV9650
tristate "OmniVision OV9650/OV9652 sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
@@ -777,12 +785,12 @@ config VIDEO_S5K6A3
camera sensor.
config VIDEO_S5K4ECGX
- tristate "Samsung S5K4ECGX sensor support"
- depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ tristate "Samsung S5K4ECGX sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
select CRC32
- ---help---
- This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
- camera sensor with an embedded SoC image signal processor.
+ ---help---
+ This is a V4L2 sensor-level driver for Samsung S5K4ECGX 5M
+ camera sensor with an embedded SoC image signal processor.
config VIDEO_S5K5BAF
tristate "Samsung S5K5BAF sensor support"
@@ -813,14 +821,6 @@ config VIDEO_ADP1653
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.
-
config VIDEO_LM3560
tristate "LM3560 dual flash driver support"
depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index 548a9efce966..c0f94cd8d56d 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
+obj-$(CONFIG_VIDEO_OV7740) += ov7740.o
obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
obj-$(CONFIG_VIDEO_OV13858) += ov13858.o
obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
@@ -84,7 +85,6 @@ obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o
obj-$(CONFIG_VIDEO_S5K5BAF) += s5k5baf.o
obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/
obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
-obj-$(CONFIG_VIDEO_AS3645A) += as3645a.o
obj-$(CONFIG_VIDEO_LM3560) += lm3560.o
obj-$(CONFIG_VIDEO_LM3646) += lm3646.o
obj-$(CONFIG_VIDEO_SMIAPP_PLL) += smiapp-pll.o
diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c
index 6fb818a775db..25d24a3f10a7 100644
--- a/drivers/media/i2c/adv7180.c
+++ b/drivers/media/i2c/adv7180.c
@@ -1366,11 +1366,9 @@ err_media_entity_cleanup:
err_free_ctrl:
adv7180_exit_controls(state);
err_unregister_vpp_client:
- if (state->chip_info->flags & ADV7180_FLAG_I2P)
- i2c_unregister_device(state->vpp_client);
+ i2c_unregister_device(state->vpp_client);
err_unregister_csi_client:
- if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
- i2c_unregister_device(state->csi_client);
+ i2c_unregister_device(state->csi_client);
mutex_destroy(&state->mutex);
return ret;
}
@@ -1388,10 +1386,8 @@ static int adv7180_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
adv7180_exit_controls(state);
- if (state->chip_info->flags & ADV7180_FLAG_I2P)
- i2c_unregister_device(state->vpp_client);
- if (state->chip_info->flags & ADV7180_FLAG_MIPI_CSI2)
- i2c_unregister_device(state->csi_client);
+ i2c_unregister_device(state->vpp_client);
+ i2c_unregister_device(state->csi_client);
adv7180_set_power_pin(state, false);
diff --git a/drivers/media/i2c/adv7343.c b/drivers/media/i2c/adv7343.c
index 11f9029433cf..4a441ee99dd8 100644
--- a/drivers/media/i2c/adv7343.c
+++ b/drivers/media/i2c/adv7343.c
@@ -100,7 +100,7 @@ static const u8 adv7343_init_reg_val[] = {
};
/*
- * 2^32
+ * 2^32
* FSC(reg) = FSC (HZ) * --------
* 27000000
*/
diff --git a/drivers/media/i2c/adv7393.c b/drivers/media/i2c/adv7393.c
index f19ad4ecd11e..b6234c8231c9 100644
--- a/drivers/media/i2c/adv7393.c
+++ b/drivers/media/i2c/adv7393.c
@@ -103,7 +103,7 @@ static const u8 adv7393_init_reg_val[] = {
};
/*
- * 2^32
+ * 2^32
* FSC(reg) = FSC (HZ) * --------
* 27000000
*/
diff --git a/drivers/media/i2c/adv748x/adv748x-afe.c b/drivers/media/i2c/adv748x/adv748x-afe.c
index 4aa8e45b5cd3..5188178588c9 100644
--- a/drivers/media/i2c/adv748x/adv748x-afe.c
+++ b/drivers/media/i2c/adv748x/adv748x-afe.c
@@ -267,6 +267,7 @@ static int adv748x_afe_g_input_status(struct v4l2_subdev *sd, u32 *status)
ret = adv748x_afe_status(afe, status, NULL);
mutex_unlock(&state->mutex);
+
return ret;
}
diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c
index 5ee14f2c2747..fd92c9e4b519 100644
--- a/drivers/media/i2c/adv748x/adv748x-core.c
+++ b/drivers/media/i2c/adv748x/adv748x-core.c
@@ -225,10 +225,8 @@ static void adv748x_unregister_clients(struct adv748x_state *state)
{
unsigned int i;
- for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i) {
- if (state->i2c_clients[i])
- i2c_unregister_device(state->i2c_clients[i]);
- }
+ for (i = 1; i < ARRAY_SIZE(state->i2c_clients); ++i)
+ i2c_unregister_device(state->i2c_clients[i]);
}
static int adv748x_initialise_clients(struct adv748x_state *state)
@@ -646,14 +644,12 @@ static int adv748x_parse_dt(struct adv748x_state *state)
for_each_endpoint_of_node(state->dev->of_node, ep_np) {
of_graph_parse_endpoint(ep_np, &ep);
- adv_info(state, "Endpoint %s on port %d",
- of_node_full_name(ep.local_node),
- ep.port);
+ adv_info(state, "Endpoint %pOF on port %d", ep.local_node,
+ ep.port);
if (ep.port >= ADV748X_PORT_MAX) {
- adv_err(state, "Invalid endpoint %s on port %d",
- of_node_full_name(ep.local_node),
- ep.port);
+ adv_err(state, "Invalid endpoint %pOF on port %d",
+ ep.local_node, ep.port);
continue;
}
diff --git a/drivers/media/i2c/adv748x/adv748x-csi2.c b/drivers/media/i2c/adv748x/adv748x-csi2.c
index 979825d4a419..820b44ed56a8 100644
--- a/drivers/media/i2c/adv748x/adv748x-csi2.c
+++ b/drivers/media/i2c/adv748x/adv748x-csi2.c
@@ -223,13 +223,12 @@ static const struct v4l2_subdev_ops adv748x_csi2_ops = {
int adv748x_csi2_set_pixelrate(struct v4l2_subdev *sd, s64 rate)
{
- struct v4l2_ctrl *ctrl;
+ struct adv748x_csi2 *tx = adv748x_sd_to_csi2(sd);
- ctrl = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_PIXEL_RATE);
- if (!ctrl)
+ if (!tx->pixel_rate)
return -EINVAL;
- return v4l2_ctrl_s_ctrl_int64(ctrl, rate);
+ return v4l2_ctrl_s_ctrl_int64(tx->pixel_rate, rate);
}
static int adv748x_csi2_s_ctrl(struct v4l2_ctrl *ctrl)
@@ -251,8 +250,10 @@ static int adv748x_csi2_init_controls(struct adv748x_csi2 *tx)
v4l2_ctrl_handler_init(&tx->ctrl_hdl, 1);
- v4l2_ctrl_new_std(&tx->ctrl_hdl, &adv748x_csi2_ctrl_ops,
- V4L2_CID_PIXEL_RATE, 1, INT_MAX, 1, 1);
+ tx->pixel_rate = v4l2_ctrl_new_std(&tx->ctrl_hdl,
+ &adv748x_csi2_ctrl_ops,
+ V4L2_CID_PIXEL_RATE, 1, INT_MAX,
+ 1, 1);
tx->sd.ctrl_handler = &tx->ctrl_hdl;
if (tx->ctrl_hdl.error) {
diff --git a/drivers/media/i2c/adv748x/adv748x.h b/drivers/media/i2c/adv748x/adv748x.h
index cc4151b5b31e..6789e2f3bc8c 100644
--- a/drivers/media/i2c/adv748x/adv748x.h
+++ b/drivers/media/i2c/adv748x/adv748x.h
@@ -97,6 +97,7 @@ struct adv748x_csi2 {
struct media_pad pads[ADV748X_CSI2_NR_PADS];
struct v4l2_ctrl_handler ctrl_hdl;
+ struct v4l2_ctrl *pixel_rate;
struct v4l2_subdev sd;
};
diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
index c786cd125417..1544920ec52d 100644
--- a/drivers/media/i2c/adv7604.c
+++ b/drivers/media/i2c/adv7604.c
@@ -1982,6 +1982,7 @@ static void adv76xx_cec_tx_raw_status(struct v4l2_subdev *sd, u8 tx_raw_status)
__func__);
cec_transmit_done(state->cec_adap, CEC_TX_STATUS_ARB_LOST,
1, 0, 0, 0);
+ return;
}
if (tx_raw_status & 0x04) {
u8 status;
diff --git a/drivers/media/i2c/as3645a.c b/drivers/media/i2c/as3645a.c
deleted file mode 100644
index af5db71a0888..000000000000
--- a/drivers/media/i2c/as3645a.c
+++ /dev/null
@@ -1,880 +0,0 @@
-/*
- * drivers/media/i2c/as3645a.c - AS3645A and LM3555 flash controllers driver
- *
- * Copyright (C) 2008-2011 Nokia Corporation
- * Copyright (c) 2011, Intel Corporation.
- *
- * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * 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.
- *
- * TODO:
- * - Check hardware FSTROBE control when sensor driver add support for this
- *
- */
-
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include <media/i2c/as3645a.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-device.h>
-
-#define AS_TIMER_MS_TO_CODE(t) (((t) - 100) / 50)
-#define AS_TIMER_CODE_TO_MS(c) (50 * (c) + 100)
-
-/* Register definitions */
-
-/* Read-only Design info register: Reset state: xxxx 0001 */
-#define AS_DESIGN_INFO_REG 0x00
-#define AS_DESIGN_INFO_FACTORY(x) (((x) >> 4))
-#define AS_DESIGN_INFO_MODEL(x) ((x) & 0x0f)
-
-/* Read-only Version control register: Reset state: 0000 0000
- * for first engineering samples
- */
-#define AS_VERSION_CONTROL_REG 0x01
-#define AS_VERSION_CONTROL_RFU(x) (((x) >> 4))
-#define AS_VERSION_CONTROL_VERSION(x) ((x) & 0x0f)
-
-/* Read / Write (Indicator and timer register): Reset state: 0000 1111 */
-#define AS_INDICATOR_AND_TIMER_REG 0x02
-#define AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT 0
-#define AS_INDICATOR_AND_TIMER_VREF_SHIFT 4
-#define AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT 6
-
-/* Read / Write (Current set register): Reset state: 0110 1001 */
-#define AS_CURRENT_SET_REG 0x03
-#define AS_CURRENT_ASSIST_LIGHT_SHIFT 0
-#define AS_CURRENT_LED_DET_ON (1 << 3)
-#define AS_CURRENT_FLASH_CURRENT_SHIFT 4
-
-/* Read / Write (Control register): Reset state: 1011 0100 */
-#define AS_CONTROL_REG 0x04
-#define AS_CONTROL_MODE_SETTING_SHIFT 0
-#define AS_CONTROL_STROBE_ON (1 << 2)
-#define AS_CONTROL_OUT_ON (1 << 3)
-#define AS_CONTROL_EXT_TORCH_ON (1 << 4)
-#define AS_CONTROL_STROBE_TYPE_EDGE (0 << 5)
-#define AS_CONTROL_STROBE_TYPE_LEVEL (1 << 5)
-#define AS_CONTROL_COIL_PEAK_SHIFT 6
-
-/* Read only (D3 is read / write) (Fault and info): Reset state: 0000 x000 */
-#define AS_FAULT_INFO_REG 0x05
-#define AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT (1 << 1)
-#define AS_FAULT_INFO_INDICATOR_LED (1 << 2)
-#define AS_FAULT_INFO_LED_AMOUNT (1 << 3)
-#define AS_FAULT_INFO_TIMEOUT (1 << 4)
-#define AS_FAULT_INFO_OVER_TEMPERATURE (1 << 5)
-#define AS_FAULT_INFO_SHORT_CIRCUIT (1 << 6)
-#define AS_FAULT_INFO_OVER_VOLTAGE (1 << 7)
-
-/* Boost register */
-#define AS_BOOST_REG 0x0d
-#define AS_BOOST_CURRENT_DISABLE (0 << 0)
-#define AS_BOOST_CURRENT_ENABLE (1 << 0)
-
-/* Password register is used to unlock boost register writing */
-#define AS_PASSWORD_REG 0x0f
-#define AS_PASSWORD_UNLOCK_VALUE 0x55
-
-enum as_mode {
- AS_MODE_EXT_TORCH = 0 << AS_CONTROL_MODE_SETTING_SHIFT,
- AS_MODE_INDICATOR = 1 << AS_CONTROL_MODE_SETTING_SHIFT,
- AS_MODE_ASSIST = 2 << AS_CONTROL_MODE_SETTING_SHIFT,
- AS_MODE_FLASH = 3 << AS_CONTROL_MODE_SETTING_SHIFT,
-};
-
-/*
- * struct as3645a
- *
- * @subdev: V4L2 subdev
- * @pdata: Flash platform data
- * @power_lock: Protects power_count
- * @power_count: Power reference count
- * @led_mode: V4L2 flash LED mode
- * @timeout: Flash timeout in microseconds
- * @flash_current: Flash current (0=200mA ... 15=500mA). Maximum
- * values are 400mA for two LEDs and 500mA for one LED.
- * @assist_current: Torch/Assist light current (0=20mA, 1=40mA ... 7=160mA)
- * @indicator_current: Indicator LED current (0=0mA, 1=2.5mA ... 4=10mA)
- * @strobe_source: Flash strobe source (software or external)
- */
-struct as3645a {
- struct v4l2_subdev subdev;
- const struct as3645a_platform_data *pdata;
-
- struct mutex power_lock;
- int power_count;
-
- /* Controls */
- struct v4l2_ctrl_handler ctrls;
-
- enum v4l2_flash_led_mode led_mode;
- unsigned int timeout;
- u8 flash_current;
- u8 assist_current;
- u8 indicator_current;
- enum v4l2_flash_strobe_source strobe_source;
-};
-
-#define to_as3645a(sd) container_of(sd, struct as3645a, subdev)
-
-/* Return negative errno else zero on success */
-static int as3645a_write(struct as3645a *flash, u8 addr, u8 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int rval;
-
- rval = i2c_smbus_write_byte_data(client, addr, val);
-
- dev_dbg(&client->dev, "Write Addr:%02X Val:%02X %s\n", addr, val,
- rval < 0 ? "fail" : "ok");
-
- return rval;
-}
-
-/* Return negative errno else a data byte received from the device. */
-static int as3645a_read(struct as3645a *flash, u8 addr)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int rval;
-
- rval = i2c_smbus_read_byte_data(client, addr);
-
- dev_dbg(&client->dev, "Read Addr:%02X Val:%02X %s\n", addr, rval,
- rval < 0 ? "fail" : "ok");
-
- return rval;
-}
-
-/* -----------------------------------------------------------------------------
- * Hardware configuration and trigger
- */
-
-/*
- * as3645a_set_config - Set flash configuration registers
- * @flash: The flash
- *
- * Configure the hardware with flash, assist and indicator currents, as well as
- * flash timeout.
- *
- * Return 0 on success, or a negative error code if an I2C communication error
- * occurred.
- */
-static int as3645a_set_config(struct as3645a *flash)
-{
- int ret;
- u8 val;
-
- val = (flash->flash_current << AS_CURRENT_FLASH_CURRENT_SHIFT)
- | (flash->assist_current << AS_CURRENT_ASSIST_LIGHT_SHIFT)
- | AS_CURRENT_LED_DET_ON;
-
- ret = as3645a_write(flash, AS_CURRENT_SET_REG, val);
- if (ret < 0)
- return ret;
-
- val = AS_TIMER_MS_TO_CODE(flash->timeout / 1000)
- << AS_INDICATOR_AND_TIMER_TIMEOUT_SHIFT;
-
- val |= (flash->pdata->vref << AS_INDICATOR_AND_TIMER_VREF_SHIFT)
- | ((flash->indicator_current ? flash->indicator_current - 1 : 0)
- << AS_INDICATOR_AND_TIMER_INDICATOR_SHIFT);
-
- return as3645a_write(flash, AS_INDICATOR_AND_TIMER_REG, val);
-}
-
-/*
- * as3645a_set_control - Set flash control register
- * @flash: The flash
- * @mode: Desired output mode
- * @on: Desired output state
- *
- * Configure the hardware with output mode and state.
- *
- * Return 0 on success, or a negative error code if an I2C communication error
- * occurred.
- */
-static int
-as3645a_set_control(struct as3645a *flash, enum as_mode mode, bool on)
-{
- u8 reg;
-
- /* Configure output parameters and operation mode. */
- reg = (flash->pdata->peak << AS_CONTROL_COIL_PEAK_SHIFT)
- | (on ? AS_CONTROL_OUT_ON : 0)
- | mode;
-
- if (flash->led_mode == V4L2_FLASH_LED_MODE_FLASH &&
- flash->strobe_source == V4L2_FLASH_STROBE_SOURCE_EXTERNAL) {
- reg |= AS_CONTROL_STROBE_TYPE_LEVEL
- | AS_CONTROL_STROBE_ON;
- }
-
- return as3645a_write(flash, AS_CONTROL_REG, reg);
-}
-
-/*
- * as3645a_set_output - Configure output and operation mode
- * @flash: Flash controller
- * @strobe: Strobe the flash (only valid in flash mode)
- *
- * Turn the LEDs output on/off and set the operation mode based on the current
- * parameters.
- *
- * The AS3645A can't control the indicator LED independently of the flash/torch
- * LED. If the flash controller is in V4L2_FLASH_LED_MODE_NONE mode, set the
- * chip to indicator mode. Otherwise set it to assist light (torch) or flash
- * mode.
- *
- * In indicator and assist modes, turn the output on/off based on the indicator
- * and torch currents. In software strobe flash mode, turn the output on/off
- * based on the strobe parameter.
- */
-static int as3645a_set_output(struct as3645a *flash, bool strobe)
-{
- enum as_mode mode;
- bool on;
-
- switch (flash->led_mode) {
- case V4L2_FLASH_LED_MODE_NONE:
- on = flash->indicator_current != 0;
- mode = AS_MODE_INDICATOR;
- break;
- case V4L2_FLASH_LED_MODE_TORCH:
- on = true;
- mode = AS_MODE_ASSIST;
- break;
- case V4L2_FLASH_LED_MODE_FLASH:
- on = strobe;
- mode = AS_MODE_FLASH;
- break;
- default:
- BUG();
- }
-
- /* Configure output parameters and operation mode. */
- return as3645a_set_control(flash, mode, on);
-}
-
-/* -----------------------------------------------------------------------------
- * V4L2 controls
- */
-
-static int as3645a_is_active(struct as3645a *flash)
-{
- int ret;
-
- ret = as3645a_read(flash, AS_CONTROL_REG);
- return ret < 0 ? ret : !!(ret & AS_CONTROL_OUT_ON);
-}
-
-static int as3645a_read_fault(struct as3645a *flash)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int rval;
-
- /* NOTE: reading register clear fault status */
- rval = as3645a_read(flash, AS_FAULT_INFO_REG);
- if (rval < 0)
- return rval;
-
- if (rval & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT)
- dev_dbg(&client->dev, "Inductor Peak limit fault\n");
-
- if (rval & AS_FAULT_INFO_INDICATOR_LED)
- dev_dbg(&client->dev,
- "Indicator LED fault: Short circuit or open loop\n");
-
- dev_dbg(&client->dev, "%u connected LEDs\n",
- rval & AS_FAULT_INFO_LED_AMOUNT ? 2 : 1);
-
- if (rval & AS_FAULT_INFO_TIMEOUT)
- dev_dbg(&client->dev, "Timeout fault\n");
-
- if (rval & AS_FAULT_INFO_OVER_TEMPERATURE)
- dev_dbg(&client->dev, "Over temperature fault\n");
-
- if (rval & AS_FAULT_INFO_SHORT_CIRCUIT)
- dev_dbg(&client->dev, "Short circuit fault\n");
-
- if (rval & AS_FAULT_INFO_OVER_VOLTAGE)
- dev_dbg(&client->dev,
- "Over voltage fault: Indicates missing capacitor or open connection\n");
-
- return rval;
-}
-
-static int as3645a_get_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct as3645a *flash =
- container_of(ctrl->handler, struct as3645a, ctrls);
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int value;
-
- switch (ctrl->id) {
- case V4L2_CID_FLASH_FAULT:
- value = as3645a_read_fault(flash);
- if (value < 0)
- return value;
-
- ctrl->cur.val = 0;
- if (value & AS_FAULT_INFO_SHORT_CIRCUIT)
- ctrl->cur.val |= V4L2_FLASH_FAULT_SHORT_CIRCUIT;
- if (value & AS_FAULT_INFO_OVER_TEMPERATURE)
- ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_TEMPERATURE;
- if (value & AS_FAULT_INFO_TIMEOUT)
- ctrl->cur.val |= V4L2_FLASH_FAULT_TIMEOUT;
- if (value & AS_FAULT_INFO_OVER_VOLTAGE)
- ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_VOLTAGE;
- if (value & AS_FAULT_INFO_INDUCTOR_PEAK_LIMIT)
- ctrl->cur.val |= V4L2_FLASH_FAULT_OVER_CURRENT;
- if (value & AS_FAULT_INFO_INDICATOR_LED)
- ctrl->cur.val |= V4L2_FLASH_FAULT_INDICATOR;
- break;
-
- case V4L2_CID_FLASH_STROBE_STATUS:
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH) {
- ctrl->cur.val = 0;
- break;
- }
-
- value = as3645a_is_active(flash);
- if (value < 0)
- return value;
-
- ctrl->cur.val = value;
- break;
- }
-
- dev_dbg(&client->dev, "G_CTRL %08x:%d\n", ctrl->id, ctrl->cur.val);
-
- return 0;
-}
-
-static int as3645a_set_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct as3645a *flash =
- container_of(ctrl->handler, struct as3645a, ctrls);
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int ret;
-
- dev_dbg(&client->dev, "S_CTRL %08x:%d\n", ctrl->id, ctrl->val);
-
- /* If a control that doesn't apply to the current mode is modified,
- * we store the value and return immediately. The setting will be
- * applied when the LED mode is changed. Otherwise we apply the setting
- * immediately.
- */
-
- switch (ctrl->id) {
- case V4L2_CID_FLASH_LED_MODE:
- if (flash->indicator_current)
- return -EBUSY;
-
- ret = as3645a_set_config(flash);
- if (ret < 0)
- return ret;
-
- flash->led_mode = ctrl->val;
- return as3645a_set_output(flash, false);
-
- case V4L2_CID_FLASH_STROBE_SOURCE:
- flash->strobe_source = ctrl->val;
-
- /* Applies to flash mode only. */
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
- break;
-
- return as3645a_set_output(flash, false);
-
- case V4L2_CID_FLASH_STROBE:
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
- return -EBUSY;
-
- return as3645a_set_output(flash, true);
-
- case V4L2_CID_FLASH_STROBE_STOP:
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
- return -EBUSY;
-
- return as3645a_set_output(flash, false);
-
- case V4L2_CID_FLASH_TIMEOUT:
- flash->timeout = ctrl->val;
-
- /* Applies to flash mode only. */
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
- break;
-
- return as3645a_set_config(flash);
-
- case V4L2_CID_FLASH_INTENSITY:
- flash->flash_current = (ctrl->val - AS3645A_FLASH_INTENSITY_MIN)
- / AS3645A_FLASH_INTENSITY_STEP;
-
- /* Applies to flash mode only. */
- if (flash->led_mode != V4L2_FLASH_LED_MODE_FLASH)
- break;
-
- return as3645a_set_config(flash);
-
- case V4L2_CID_FLASH_TORCH_INTENSITY:
- flash->assist_current =
- (ctrl->val - AS3645A_TORCH_INTENSITY_MIN)
- / AS3645A_TORCH_INTENSITY_STEP;
-
- /* Applies to torch mode only. */
- if (flash->led_mode != V4L2_FLASH_LED_MODE_TORCH)
- break;
-
- return as3645a_set_config(flash);
-
- case V4L2_CID_FLASH_INDICATOR_INTENSITY:
- if (flash->led_mode != V4L2_FLASH_LED_MODE_NONE)
- return -EBUSY;
-
- flash->indicator_current =
- (ctrl->val - AS3645A_INDICATOR_INTENSITY_MIN)
- / AS3645A_INDICATOR_INTENSITY_STEP;
-
- ret = as3645a_set_config(flash);
- if (ret < 0)
- return ret;
-
- if ((ctrl->val == 0) == (ctrl->cur.val == 0))
- break;
-
- return as3645a_set_output(flash, false);
- }
-
- return 0;
-}
-
-static const struct v4l2_ctrl_ops as3645a_ctrl_ops = {
- .g_volatile_ctrl = as3645a_get_ctrl,
- .s_ctrl = as3645a_set_ctrl,
-};
-
-/* -----------------------------------------------------------------------------
- * V4L2 subdev core operations
- */
-
-/* Put device into know state. */
-static int as3645a_setup(struct as3645a *flash)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&flash->subdev);
- int ret;
-
- /* clear errors */
- ret = as3645a_read(flash, AS_FAULT_INFO_REG);
- if (ret < 0)
- return ret;
-
- dev_dbg(&client->dev, "Fault info: %02x\n", ret);
-
- ret = as3645a_set_config(flash);
- if (ret < 0)
- return ret;
-
- ret = as3645a_set_output(flash, false);
- if (ret < 0)
- return ret;
-
- /* read status */
- ret = as3645a_read_fault(flash);
- if (ret < 0)
- return ret;
-
- dev_dbg(&client->dev, "AS_INDICATOR_AND_TIMER_REG: %02x\n",
- as3645a_read(flash, AS_INDICATOR_AND_TIMER_REG));
- dev_dbg(&client->dev, "AS_CURRENT_SET_REG: %02x\n",
- as3645a_read(flash, AS_CURRENT_SET_REG));
- dev_dbg(&client->dev, "AS_CONTROL_REG: %02x\n",
- as3645a_read(flash, AS_CONTROL_REG));
-
- return ret & ~AS_FAULT_INFO_LED_AMOUNT ? -EIO : 0;
-}
-
-static int __as3645a_set_power(struct as3645a *flash, int on)
-{
- int ret;
-
- if (!on)
- as3645a_set_control(flash, AS_MODE_EXT_TORCH, false);
-
- if (flash->pdata->set_power) {
- ret = flash->pdata->set_power(&flash->subdev, on);
- if (ret < 0)
- return ret;
- }
-
- if (!on)
- return 0;
-
- ret = as3645a_setup(flash);
- if (ret < 0) {
- if (flash->pdata->set_power)
- flash->pdata->set_power(&flash->subdev, 0);
- }
-
- return ret;
-}
-
-static int as3645a_set_power(struct v4l2_subdev *sd, int on)
-{
- struct as3645a *flash = to_as3645a(sd);
- int ret = 0;
-
- mutex_lock(&flash->power_lock);
-
- if (flash->power_count == !on) {
- ret = __as3645a_set_power(flash, !!on);
- if (ret < 0)
- goto done;
- }
-
- flash->power_count += on ? 1 : -1;
- WARN_ON(flash->power_count < 0);
-
-done:
- mutex_unlock(&flash->power_lock);
- return ret;
-}
-
-static int as3645a_registered(struct v4l2_subdev *sd)
-{
- struct as3645a *flash = to_as3645a(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- int rval, man, model, rfu, version;
- const char *vendor;
-
- /* Power up the flash driver and read manufacturer ID, model ID, RFU
- * and version.
- */
- rval = as3645a_set_power(&flash->subdev, 1);
- if (rval < 0)
- return rval;
-
- rval = as3645a_read(flash, AS_DESIGN_INFO_REG);
- if (rval < 0)
- goto power_off;
-
- man = AS_DESIGN_INFO_FACTORY(rval);
- model = AS_DESIGN_INFO_MODEL(rval);
-
- rval = as3645a_read(flash, AS_VERSION_CONTROL_REG);
- if (rval < 0)
- goto power_off;
-
- rfu = AS_VERSION_CONTROL_RFU(rval);
- version = AS_VERSION_CONTROL_VERSION(rval);
-
- /* Verify the chip model and version. */
- if (model != 0x01 || rfu != 0x00) {
- dev_err(&client->dev,
- "AS3645A not detected (model %d rfu %d)\n", model, rfu);
- rval = -ENODEV;
- goto power_off;
- }
-
- switch (man) {
- case 1:
- vendor = "AMS, Austria Micro Systems";
- break;
- case 2:
- vendor = "ADI, Analog Devices Inc.";
- break;
- case 3:
- vendor = "NSC, National Semiconductor";
- break;
- case 4:
- vendor = "NXP";
- break;
- case 5:
- vendor = "TI, Texas Instrument";
- break;
- default:
- vendor = "Unknown";
- }
-
- dev_info(&client->dev, "Chip vendor: %s (%d) Version: %d\n", vendor,
- man, version);
-
- rval = as3645a_write(flash, AS_PASSWORD_REG, AS_PASSWORD_UNLOCK_VALUE);
- if (rval < 0)
- goto power_off;
-
- rval = as3645a_write(flash, AS_BOOST_REG, AS_BOOST_CURRENT_DISABLE);
- if (rval < 0)
- goto power_off;
-
- /* Setup default values. This makes sure that the chip is in a known
- * state, in case the power rail can't be controlled.
- */
- rval = as3645a_setup(flash);
-
-power_off:
- as3645a_set_power(&flash->subdev, 0);
-
- return rval;
-}
-
-static int as3645a_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- return as3645a_set_power(sd, 1);
-}
-
-static int as3645a_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
- return as3645a_set_power(sd, 0);
-}
-
-static const struct v4l2_subdev_core_ops as3645a_core_ops = {
- .s_power = as3645a_set_power,
-};
-
-static const struct v4l2_subdev_ops as3645a_ops = {
- .core = &as3645a_core_ops,
-};
-
-static const struct v4l2_subdev_internal_ops as3645a_internal_ops = {
- .registered = as3645a_registered,
- .open = as3645a_open,
- .close = as3645a_close,
-};
-
-/* -----------------------------------------------------------------------------
- * I2C driver
- */
-#ifdef CONFIG_PM
-
-static int as3645a_suspend(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct as3645a *flash = to_as3645a(subdev);
- int rval;
-
- if (flash->power_count == 0)
- return 0;
-
- rval = __as3645a_set_power(flash, 0);
-
- dev_dbg(&client->dev, "Suspend %s\n", rval < 0 ? "failed" : "ok");
-
- return rval;
-}
-
-static int as3645a_resume(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct as3645a *flash = to_as3645a(subdev);
- int rval;
-
- if (flash->power_count == 0)
- return 0;
-
- rval = __as3645a_set_power(flash, 1);
-
- dev_dbg(&client->dev, "Resume %s\n", rval < 0 ? "fail" : "ok");
-
- return rval;
-}
-
-#else
-
-#define as3645a_suspend NULL
-#define as3645a_resume NULL
-
-#endif /* CONFIG_PM */
-
-/*
- * as3645a_init_controls - Create controls
- * @flash: The flash
- *
- * The number of LEDs reported in platform data is used to compute default
- * limits. Parameters passed through platform data can override those limits.
- */
-static int as3645a_init_controls(struct as3645a *flash)
-{
- const struct as3645a_platform_data *pdata = flash->pdata;
- struct v4l2_ctrl *ctrl;
- int maximum;
-
- v4l2_ctrl_handler_init(&flash->ctrls, 10);
-
- /* V4L2_CID_FLASH_LED_MODE */
- v4l2_ctrl_new_std_menu(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_LED_MODE, 2, ~7,
- V4L2_FLASH_LED_MODE_NONE);
-
- /* V4L2_CID_FLASH_STROBE_SOURCE */
- v4l2_ctrl_new_std_menu(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_STROBE_SOURCE,
- pdata->ext_strobe ? 1 : 0,
- pdata->ext_strobe ? ~3 : ~1,
- V4L2_FLASH_STROBE_SOURCE_SOFTWARE);
-
- flash->strobe_source = V4L2_FLASH_STROBE_SOURCE_SOFTWARE;
-
- /* V4L2_CID_FLASH_STROBE */
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_STROBE, 0, 0, 0, 0);
-
- /* V4L2_CID_FLASH_STROBE_STOP */
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_STROBE_STOP, 0, 0, 0, 0);
-
- /* V4L2_CID_FLASH_STROBE_STATUS */
- ctrl = v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_STROBE_STATUS, 0, 1, 1, 1);
- if (ctrl != NULL)
- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
- /* V4L2_CID_FLASH_TIMEOUT */
- maximum = pdata->timeout_max;
-
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_TIMEOUT, AS3645A_FLASH_TIMEOUT_MIN,
- maximum, AS3645A_FLASH_TIMEOUT_STEP, maximum);
-
- flash->timeout = maximum;
-
- /* V4L2_CID_FLASH_INTENSITY */
- maximum = pdata->flash_max_current;
-
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_INTENSITY, AS3645A_FLASH_INTENSITY_MIN,
- maximum, AS3645A_FLASH_INTENSITY_STEP, maximum);
-
- flash->flash_current = (maximum - AS3645A_FLASH_INTENSITY_MIN)
- / AS3645A_FLASH_INTENSITY_STEP;
-
- /* V4L2_CID_FLASH_TORCH_INTENSITY */
- maximum = pdata->torch_max_current;
-
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_TORCH_INTENSITY,
- AS3645A_TORCH_INTENSITY_MIN, maximum,
- AS3645A_TORCH_INTENSITY_STEP,
- AS3645A_TORCH_INTENSITY_MIN);
-
- flash->assist_current = 0;
-
- /* V4L2_CID_FLASH_INDICATOR_INTENSITY */
- v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_INDICATOR_INTENSITY,
- AS3645A_INDICATOR_INTENSITY_MIN,
- AS3645A_INDICATOR_INTENSITY_MAX,
- AS3645A_INDICATOR_INTENSITY_STEP,
- AS3645A_INDICATOR_INTENSITY_MIN);
-
- flash->indicator_current = 0;
-
- /* V4L2_CID_FLASH_FAULT */
- ctrl = v4l2_ctrl_new_std(&flash->ctrls, &as3645a_ctrl_ops,
- V4L2_CID_FLASH_FAULT, 0,
- V4L2_FLASH_FAULT_OVER_VOLTAGE |
- V4L2_FLASH_FAULT_TIMEOUT |
- V4L2_FLASH_FAULT_OVER_TEMPERATURE |
- V4L2_FLASH_FAULT_SHORT_CIRCUIT, 0, 0);
- if (ctrl != NULL)
- ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
-
- flash->subdev.ctrl_handler = &flash->ctrls;
-
- return flash->ctrls.error;
-}
-
-static int as3645a_probe(struct i2c_client *client,
- const struct i2c_device_id *devid)
-{
- struct as3645a *flash;
- int ret;
-
- if (client->dev.platform_data == NULL)
- return -ENODEV;
-
- flash = devm_kzalloc(&client->dev, sizeof(*flash), GFP_KERNEL);
- if (flash == NULL)
- return -ENOMEM;
-
- flash->pdata = client->dev.platform_data;
-
- v4l2_i2c_subdev_init(&flash->subdev, client, &as3645a_ops);
- flash->subdev.internal_ops = &as3645a_internal_ops;
- flash->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-
- ret = as3645a_init_controls(flash);
- if (ret < 0)
- goto done;
-
- ret = media_entity_pads_init(&flash->subdev.entity, 0, NULL);
- if (ret < 0)
- goto done;
-
- flash->subdev.entity.function = MEDIA_ENT_F_FLASH;
-
- mutex_init(&flash->power_lock);
-
- flash->led_mode = V4L2_FLASH_LED_MODE_NONE;
-
-done:
- if (ret < 0)
- v4l2_ctrl_handler_free(&flash->ctrls);
-
- return ret;
-}
-
-static int as3645a_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *subdev = i2c_get_clientdata(client);
- struct as3645a *flash = to_as3645a(subdev);
-
- v4l2_device_unregister_subdev(subdev);
- v4l2_ctrl_handler_free(&flash->ctrls);
- media_entity_cleanup(&flash->subdev.entity);
- mutex_destroy(&flash->power_lock);
-
- return 0;
-}
-
-static const struct i2c_device_id as3645a_id_table[] = {
- { AS3645A_NAME, 0 },
- { },
-};
-MODULE_DEVICE_TABLE(i2c, as3645a_id_table);
-
-static const struct dev_pm_ops as3645a_pm_ops = {
- .suspend = as3645a_suspend,
- .resume = as3645a_resume,
-};
-
-static struct i2c_driver as3645a_i2c_driver = {
- .driver = {
- .name = AS3645A_NAME,
- .pm = &as3645a_pm_ops,
- },
- .probe = as3645a_probe,
- .remove = as3645a_remove,
- .id_table = as3645a_id_table,
-};
-
-module_i2c_driver(as3645a_i2c_driver);
-
-MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
-MODULE_DESCRIPTION("LED flash driver for AS3645A, LM3555 and their clones");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/i2c/cx25840/Makefile b/drivers/media/i2c/cx25840/Makefile
index 898eb13340ae..ac545812fc6a 100644
--- a/drivers/media/i2c/cx25840/Makefile
+++ b/drivers/media/i2c/cx25840/Makefile
@@ -2,5 +2,3 @@ cx25840-objs := cx25840-core.o cx25840-audio.o cx25840-firmware.o \
cx25840-vbi.o cx25840-ir.o
obj-$(CONFIG_VIDEO_CX25840) += cx25840.o
-
-ccflags-y += -Idrivers/media/i2c
diff --git a/drivers/media/i2c/cx25840/cx25840-core.c b/drivers/media/i2c/cx25840/cx25840-core.c
index f38bf819d805..98be63ae8590 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.c
+++ b/drivers/media/i2c/cx25840/cx25840-core.c
@@ -201,14 +201,14 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
} else {
/* IRQ_N */
if (p[i].flags &
- (V4L2_SUBDEV_IO_PIN_DISABLE |
- V4L2_SUBDEV_IO_PIN_INPUT)) {
+ (BIT(V4L2_SUBDEV_IO_PIN_DISABLE) |
+ BIT(V4L2_SUBDEV_IO_PIN_INPUT))) {
pin_ctrl &= ~(0x1 << 25);
} else {
pin_ctrl |= (0x1 << 25);
}
if (p[i].flags &
- V4L2_SUBDEV_IO_PIN_ACTIVE_LOW) {
+ BIT(V4L2_SUBDEV_IO_PIN_ACTIVE_LOW)) {
pin_ctrl &= ~(0x1 << 24);
} else {
pin_ctrl |= (0x1 << 24);
@@ -224,7 +224,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
} else {
/* GPIO19 */
gpio_oe &= ~(0x1 << 0);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
+ if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {
gpio_data &= ~(0x1 << 0);
gpio_data |= ((p[i].value & 0x1) << 0);
}
@@ -236,7 +236,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
if (p[i].function != CX23885_PAD_GPIO20) {
/* IR_TX */
gpio_oe |= (0x1 << 1);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_DISABLE)
+ if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_DISABLE))
pin_ctrl &= ~(0x1 << 10);
else
pin_ctrl |= (0x1 << 10);
@@ -245,7 +245,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
} else {
/* GPIO20 */
gpio_oe &= ~(0x1 << 1);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
+ if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {
gpio_data &= ~(0x1 << 1);
gpio_data |= ((p[i].value & 0x1) << 1);
}
@@ -263,7 +263,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
} else {
/* GPIO21 */
gpio_oe &= ~(0x1 << 2);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
+ if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {
gpio_data &= ~(0x1 << 2);
gpio_data |= ((p[i].value & 0x1) << 2);
}
@@ -281,7 +281,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
} else {
/* GPIO22 */
gpio_oe &= ~(0x1 << 3);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
+ if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {
gpio_data &= ~(0x1 << 3);
gpio_data |= ((p[i].value & 0x1) << 3);
}
@@ -299,7 +299,7 @@ static int cx23885_s_io_pin_config(struct v4l2_subdev *sd, size_t n,
} else {
/* GPIO23 */
gpio_oe &= ~(0x1 << 4);
- if (p[i].flags & V4L2_SUBDEV_IO_PIN_SET_VALUE) {
+ if (p[i].flags & BIT(V4L2_SUBDEV_IO_PIN_SET_VALUE)) {
gpio_data &= ~(0x1 << 4);
gpio_data |= ((p[i].value & 0x1) << 4);
}
@@ -1263,7 +1263,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp
static int set_v4lstd(struct i2c_client *client)
{
struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- u8 fmt = 0; /* zero is autodetect */
+ u8 fmt = 0; /* zero is autodetect */
u8 pal_m = 0;
/* First tests should be against specific std */
@@ -1395,8 +1395,9 @@ static int cx25840_set_fmt(struct v4l2_subdev *sd,
* height. Without that margin the cx23885 fails in this
* check.
*/
- if ((fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
- (Vlines * 8 < Vsrc) || (Vsrc + 1 < Vlines)) {
+ if ((fmt->width == 0) || (Vlines == 0) ||
+ (fmt->width * 16 < Hsrc) || (Hsrc < fmt->width) ||
+ (Vlines * 8 < Vsrc) || (Vsrc + 1 < Vlines)) {
v4l_err(client, "%dx%d is not a valid size!\n",
fmt->width, fmt->height);
return -ERANGE;
@@ -1759,9 +1760,9 @@ static int cx25840_g_std(struct v4l2_subdev *sd, v4l2_std_id *std)
/* 1001 */ V4L2_STD_UNKNOWN,
/* 1010 */ V4L2_STD_UNKNOWN,
- /* 1001 */ V4L2_STD_UNKNOWN,
- /* 1010 */ V4L2_STD_UNKNOWN,
/* 1011 */ V4L2_STD_UNKNOWN,
+ /* 1100 */ V4L2_STD_SECAM,
+ /* 1101 */ V4L2_STD_UNKNOWN,
/* 1110 */ V4L2_STD_UNKNOWN,
/* 1111 */ V4L2_STD_UNKNOWN
};
@@ -2064,10 +2065,10 @@ static void cx23885_dif_setup(struct i2c_client *client, u32 ifHz)
/* Assuming TV */
/* Calculate the PLL frequency word based on the adjusted ifHz */
- pll_freq = div_u64((u64)ifHz * 268435456, 50000000);
- pll_freq_word = (u32)pll_freq;
+ pll_freq = div_u64((u64)ifHz * 268435456, 50000000);
+ pll_freq_word = (u32)pll_freq;
- cx25840_write4(client, DIF_PLL_FREQ_WORD, pll_freq_word);
+ cx25840_write4(client, DIF_PLL_FREQ_WORD, pll_freq_word);
/* Round down to the nearest 100KHz */
ifHz = (ifHz / 100000) * 100000;
diff --git a/drivers/media/i2c/cx25840/cx25840-core.h b/drivers/media/i2c/cx25840/cx25840-core.h
index 55432ed42714..fb13a624d2e3 100644
--- a/drivers/media/i2c/cx25840/cx25840-core.h
+++ b/drivers/media/i2c/cx25840/cx25840-core.h
@@ -118,7 +118,7 @@ static inline bool is_cx23888(struct cx25840_state *state)
}
/* ----------------------------------------------------------------------- */
-/* cx25850-core.c */
+/* cx25850-core.c */
int cx25840_write(struct i2c_client *client, u16 addr, u8 value);
int cx25840_write4(struct i2c_client *client, u16 addr, u32 value);
u8 cx25840_read(struct i2c_client *client, u16 addr);
diff --git a/drivers/media/i2c/cx25840/cx25840-ir.c b/drivers/media/i2c/cx25840/cx25840-ir.c
index 9b65c7d2fa84..ad7f66c7aac8 100644
--- a/drivers/media/i2c/cx25840/cx25840-ir.c
+++ b/drivers/media/i2c/cx25840/cx25840-ir.c
@@ -28,7 +28,7 @@ static unsigned int ir_debug;
module_param(ir_debug, int, 0644);
MODULE_PARM_DESC(ir_debug, "enable integrated IR debug messages");
-#define CX25840_IR_REG_BASE 0x200
+#define CX25840_IR_REG_BASE 0x200
#define CX25840_IR_CNTRL_REG 0x200
#define CNTRL_WIN_3_3 0x00000000
@@ -131,7 +131,7 @@ static inline struct cx25840_ir_state *to_ir_state(struct v4l2_subdev *sd)
* Rx and Tx Clock Divider register computations
*
* Note the largest clock divider value of 0xffff corresponds to:
- * (0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
+ * (0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
* which fits in 21 bits, so we'll use unsigned int for time arguments.
*/
static inline u16 count_to_clock_divider(unsigned int d)
@@ -187,7 +187,7 @@ static inline unsigned int clock_divider_to_freq(unsigned int divider,
* Low Pass Filter register calculations
*
* Note the largest count value of 0xffff corresponds to:
- * 0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
+ * 0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
* which fits in 21 bits, so we'll use unsigned int for time arguments.
*/
static inline u16 count_to_lpf_count(unsigned int d)
diff --git a/drivers/media/i2c/dw9714.c b/drivers/media/i2c/dw9714.c
index ed01e8bd4331..8dbbf0f917df 100644
--- a/drivers/media/i2c/dw9714.c
+++ b/drivers/media/i2c/dw9714.c
@@ -42,7 +42,6 @@
/* dw9714 device structure */
struct dw9714_device {
- struct i2c_client *client;
struct v4l2_ctrl_handler ctrls_vcm;
struct v4l2_subdev sd;
u16 current_val;
@@ -61,7 +60,7 @@ static inline struct dw9714_device *sd_to_dw9714_vcm(struct v4l2_subdev *subdev)
static int dw9714_i2c_write(struct i2c_client *client, u16 data)
{
int ret;
- u16 val = cpu_to_be16(data);
+ __be16 val = cpu_to_be16(data);
ret = i2c_master_send(client, (const char *)&val, sizeof(val));
if (ret != sizeof(val)) {
@@ -73,7 +72,7 @@ static int dw9714_i2c_write(struct i2c_client *client, u16 data)
static int dw9714_t_focus_vcm(struct dw9714_device *dw9714_dev, u16 val)
{
- struct i2c_client *client = dw9714_dev->client;
+ struct i2c_client *client = v4l2_get_subdevdata(&dw9714_dev->sd);
dw9714_dev->current_val = val;
@@ -96,13 +95,11 @@ static const struct v4l2_ctrl_ops dw9714_vcm_ctrl_ops = {
static int dw9714_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
- struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
- struct device *dev = &dw9714_dev->client->dev;
int rval;
- rval = pm_runtime_get_sync(dev);
+ rval = pm_runtime_get_sync(sd->dev);
if (rval < 0) {
- pm_runtime_put_noidle(dev);
+ pm_runtime_put_noidle(sd->dev);
return rval;
}
@@ -111,10 +108,7 @@ static int dw9714_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
static int dw9714_close(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
- struct dw9714_device *dw9714_dev = sd_to_dw9714_vcm(sd);
- struct device *dev = &dw9714_dev->client->dev;
-
- pm_runtime_put(dev);
+ pm_runtime_put(sd->dev);
return 0;
}
@@ -137,7 +131,6 @@ static int dw9714_init_controls(struct dw9714_device *dev_vcm)
{
struct v4l2_ctrl_handler *hdl = &dev_vcm->ctrls_vcm;
const struct v4l2_ctrl_ops *ops = &dw9714_vcm_ctrl_ops;
- struct i2c_client *client = dev_vcm->client;
v4l2_ctrl_handler_init(hdl, 1);
@@ -145,7 +138,7 @@ static int dw9714_init_controls(struct dw9714_device *dev_vcm)
0, DW9714_MAX_FOCUS_POS, DW9714_FOCUS_STEPS, 0);
if (hdl->error)
- dev_err(&client->dev, "%s fail error: 0x%x\n",
+ dev_err(dev_vcm->sd.dev, "%s fail error: 0x%x\n",
__func__, hdl->error);
dev_vcm->sd.ctrl_handler = hdl;
return hdl->error;
@@ -161,8 +154,6 @@ static int dw9714_probe(struct i2c_client *client)
if (dw9714_dev == NULL)
return -ENOMEM;
- dw9714_dev->client = client;
-
v4l2_i2c_subdev_init(&dw9714_dev->sd, client, &dw9714_ops);
dw9714_dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
dw9714_dev->sd.internal_ops = &dw9714_int_ops;
@@ -183,6 +174,7 @@ static int dw9714_probe(struct i2c_client *client)
pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
+ pm_runtime_idle(&client->dev);
return 0;
diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c
index 2f71af2f90bf..664e8acdf2a0 100644
--- a/drivers/media/i2c/imx274.c
+++ b/drivers/media/i2c/imx274.c
@@ -634,7 +634,7 @@ static int imx274_regmap_util_write_table_8(struct regmap *regmap,
const struct reg_8 table[],
u16 wait_ms_addr, u16 end_addr)
{
- int err;
+ int err = 0;
const struct reg_8 *next;
u8 val;
@@ -655,6 +655,8 @@ static int imx274_regmap_util_write_table_8(struct regmap *regmap,
err = regmap_bulk_write(regmap, range_start,
&range_vals[0],
range_count);
+ else
+ err = 0;
if (err)
return err;
diff --git a/drivers/media/i2c/ir-kbd-i2c.c b/drivers/media/i2c/ir-kbd-i2c.c
index 8b5f7d0435e4..193020d64e51 100644
--- a/drivers/media/i2c/ir-kbd-i2c.c
+++ b/drivers/media/i2c/ir-kbd-i2c.c
@@ -18,6 +18,20 @@
* Brian Rogers <brian_rogers@comcast.net>
* modified for AVerMedia Cardbus by
* Oldrich Jedlicka <oldium.pro@seznam.cz>
+ * Zilog Transmitter portions/ideas were derived from GPLv2+ sources:
+ * - drivers/char/pctv_zilogir.[ch] from Hauppauge Broadway product
+ * Copyright 2011 Hauppauge Computer works
+ * - drivers/staging/media/lirc/lirc_zilog.c
+ * Copyright (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
+ * Michal Kochanowicz <mkochano@pld.org.pl>
+ * Christoph Bartelmus <lirc@bartelmus.de>
+ * Ulrich Mueller <ulrich.mueller42@web.de>
+ * Stefan Jahn <stefan@lkcc.org>
+ * Jerome Brock <jbrock@users.sourceforge.net>
+ * Thomas Reitmayr (treitmayr@yahoo.com)
+ * Mark Weaver <mark@npsl.co.uk>
+ * Jarod Wilson <jarod@redhat.com>
+ * Copyright (C) 2011 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
@@ -46,18 +60,11 @@
#include <media/rc-core.h>
#include <media/i2c/ir-kbd-i2c.h>
-/* ----------------------------------------------------------------------- */
-/* insmod parameters */
-
-static int debug;
-module_param(debug, int, 0644); /* debug level (0,1,2) */
-
+#define FLAG_TX 1
+#define FLAG_HDPVR 2
-#define MODULE_NAME "ir-kbd-i2c"
-#define dprintk(level, fmt, arg...) if (debug >= level) \
- printk(KERN_DEBUG MODULE_NAME ": " fmt , ## arg)
-
-/* ----------------------------------------------------------------------- */
+static bool enable_hdpvr;
+module_param(enable_hdpvr, bool, 0644);
static int get_key_haup_common(struct IR_i2c *ir, enum rc_proto *protocol,
u32 *scancode, u8 *ptoggle, int size)
@@ -96,7 +103,8 @@ static int get_key_haup_common(struct IR_i2c *ir, enum rc_proto *protocol,
if (!range)
code += 64;
- dprintk(1, "ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
+ dev_dbg(&ir->rc->dev,
+ "ir hauppauge (rc5): s%d r%d t%d dev=%d code=%d\n",
start, range, toggle, dev, code);
*protocol = RC_PROTO_RC5;
@@ -113,13 +121,15 @@ static int get_key_haup_common(struct IR_i2c *ir, enum rc_proto *protocol,
*ptoggle = (dev & 0x80) != 0;
*protocol = RC_PROTO_RC6_MCE;
dev &= 0x7f;
- dprintk(1, "ir hauppauge (rc6-mce): t%d vendor=%d dev=%d code=%d\n",
- *ptoggle, vendor, dev, code);
+ dev_dbg(&ir->rc->dev,
+ "ir hauppauge (rc6-mce): t%d vendor=%d dev=%d code=%d\n",
+ *ptoggle, vendor, dev, code);
} else {
*ptoggle = 0;
*protocol = RC_PROTO_RC6_6A_32;
- dprintk(1, "ir hauppauge (rc6-6a-32): vendor=%d dev=%d code=%d\n",
- vendor, dev, code);
+ dev_dbg(&ir->rc->dev,
+ "ir hauppauge (rc6-6a-32): vendor=%d dev=%d code=%d\n",
+ vendor, dev, code);
}
*scancode = RC_SCANCODE_RC6_6A(vendor, dev, code);
@@ -162,7 +172,7 @@ static int get_key_pixelview(struct IR_i2c *ir, enum rc_proto *protocol,
/* poll IR chip */
if (1 != i2c_master_recv(ir->c, &b, 1)) {
- dprintk(1,"read error\n");
+ dev_dbg(&ir->rc->dev, "read error\n");
return -EIO;
}
@@ -179,13 +189,12 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, enum rc_proto *protocol,
/* poll IR chip */
if (4 != i2c_master_recv(ir->c, buf, 4)) {
- dprintk(1,"read error\n");
+ dev_dbg(&ir->rc->dev, "read error\n");
return -EIO;
}
- if(buf[0] !=0 || buf[1] !=0 || buf[2] !=0 || buf[3] != 0)
- dprintk(2, "%s: 0x%2x 0x%2x 0x%2x 0x%2x\n", __func__,
- buf[0], buf[1], buf[2], buf[3]);
+ if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0 || buf[3] != 0)
+ dev_dbg(&ir->rc->dev, "%s: %*ph\n", __func__, 4, buf);
/* no key pressed or signal from other ir remote */
if(buf[0] != 0x1 || buf[1] != 0xfe)
@@ -204,7 +213,7 @@ static int get_key_knc1(struct IR_i2c *ir, enum rc_proto *protocol,
/* poll IR chip */
if (1 != i2c_master_recv(ir->c, &b, 1)) {
- dprintk(1,"read error\n");
+ dev_dbg(&ir->rc->dev, "read error\n");
return -EIO;
}
@@ -212,7 +221,7 @@ static int get_key_knc1(struct IR_i2c *ir, enum rc_proto *protocol,
down, while 0xff indicates that no button is hold
down. 0xfe sequences are sometimes interrupted by 0xFF */
- dprintk(2,"key %02x\n", b);
+ dev_dbg(&ir->rc->dev, "key %02x\n", b);
if (b == 0xff)
return 0;
@@ -237,7 +246,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_proto *protocol,
.buf = &key, .len = 1} };
subaddr = 0x0d;
if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
- dprintk(1, "read error\n");
+ dev_dbg(&ir->rc->dev, "read error\n");
return -EIO;
}
@@ -247,18 +256,17 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir, enum rc_proto *protocol,
subaddr = 0x0b;
msg[1].buf = &keygroup;
if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
- dprintk(1, "read error\n");
+ dev_dbg(&ir->rc->dev, "read error\n");
return -EIO;
}
if (keygroup == 0xff)
return 0;
- dprintk(1, "read key 0x%02x/0x%02x\n", key, keygroup);
+ dev_dbg(&ir->rc->dev, "read key 0x%02x/0x%02x\n", key, keygroup);
if (keygroup < 2 || keygroup > 4) {
- /* Only a warning */
- dprintk(1, "warning: invalid key group 0x%02x for key 0x%02x\n",
- keygroup, key);
+ dev_warn(&ir->rc->dev, "warning: invalid key group 0x%02x for key 0x%02x\n",
+ keygroup, key);
}
key |= (keygroup & 1) << 6;
@@ -279,15 +287,15 @@ static int ir_key_poll(struct IR_i2c *ir)
u8 toggle;
int rc;
- dprintk(3, "%s\n", __func__);
+ dev_dbg(&ir->rc->dev, "%s\n", __func__);
rc = ir->get_key(ir, &protocol, &scancode, &toggle);
if (rc < 0) {
- dprintk(2,"error\n");
+ dev_warn(&ir->rc->dev, "error %d\n", rc);
return rc;
}
if (rc) {
- dprintk(1, "%s: proto = 0x%04x, scancode = 0x%08x\n",
+ dev_dbg(&ir->rc->dev, "%s: proto = 0x%04x, scancode = 0x%08x\n",
__func__, protocol, scancode);
rc_keydown(ir->rc, protocol, scancode, toggle);
}
@@ -299,17 +307,416 @@ static void ir_work(struct work_struct *work)
int rc;
struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work);
- rc = ir_key_poll(ir);
- if (rc == -ENODEV) {
- rc_unregister_device(ir->rc);
- ir->rc = NULL;
- return;
+ /*
+ * If the transmit code is holding the lock, skip polling for
+ * IR, we'll get it to it next time round
+ */
+ if (mutex_trylock(&ir->lock)) {
+ rc = ir_key_poll(ir);
+ mutex_unlock(&ir->lock);
+ if (rc == -ENODEV) {
+ rc_unregister_device(ir->rc);
+ ir->rc = NULL;
+ return;
+ }
}
schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling_interval));
}
-/* ----------------------------------------------------------------------- */
+static int ir_open(struct rc_dev *dev)
+{
+ struct IR_i2c *ir = dev->priv;
+
+ schedule_delayed_work(&ir->work, 0);
+
+ return 0;
+}
+
+static void ir_close(struct rc_dev *dev)
+{
+ struct IR_i2c *ir = dev->priv;
+
+ cancel_delayed_work_sync(&ir->work);
+}
+
+/* Zilog Transmit Interface */
+#define XTAL_FREQ 18432000
+
+#define ZILOG_SEND 0x80
+#define ZILOG_UIR_END 0x40
+#define ZILOG_INIT_END 0x20
+#define ZILOG_LIR_END 0x10
+
+#define ZILOG_STATUS_OK 0x80
+#define ZILOG_STATUS_TX 0x40
+#define ZILOG_STATUS_SET 0x20
+
+/*
+ * As you can see here, very few different lengths of pulse and space
+ * can be encoded. This means that the hardware does not work well with
+ * recorded IR. It's best to work with generated IR, like from ir-ctl or
+ * the in-kernel encoders.
+ */
+struct code_block {
+ u8 length;
+ u16 pulse[7]; /* not aligned */
+ u8 carrier_pulse;
+ u8 carrier_space;
+ u16 space[8]; /* not aligned */
+ u8 codes[61];
+ u8 csum[2];
+} __packed;
+
+static int send_data_block(struct IR_i2c *ir, int cmd,
+ struct code_block *code_block)
+{
+ int i, j, ret;
+ u8 buf[5], *p;
+
+ p = &code_block->length;
+ for (i = 0; p < code_block->csum; i++)
+ code_block->csum[i & 1] ^= *p++;
+
+ p = &code_block->length;
+
+ for (i = 0; i < sizeof(*code_block);) {
+ int tosend = sizeof(*code_block) - i;
+
+ if (tosend > 4)
+ tosend = 4;
+ buf[0] = i + 1;
+ for (j = 0; j < tosend; ++j)
+ buf[1 + j] = p[i + j];
+ dev_dbg(&ir->rc->dev, "%*ph", tosend + 1, buf);
+ ret = i2c_master_send(ir->tx_c, buf, tosend + 1);
+ if (ret != tosend + 1) {
+ dev_dbg(&ir->rc->dev,
+ "i2c_master_send failed with %d\n", ret);
+ return ret < 0 ? ret : -EIO;
+ }
+ i += tosend;
+ }
+
+ buf[0] = 0;
+ buf[1] = cmd;
+ ret = i2c_master_send(ir->tx_c, buf, 2);
+ if (ret != 2) {
+ dev_err(&ir->rc->dev, "i2c_master_send failed with %d\n", ret);
+ return ret < 0 ? ret : -EIO;
+ }
+
+ usleep_range(2000, 5000);
+
+ ret = i2c_master_send(ir->tx_c, buf, 1);
+ if (ret != 1) {
+ dev_err(&ir->rc->dev, "i2c_master_send failed with %d\n", ret);
+ return ret < 0 ? ret : -EIO;
+ }
+
+ return 0;
+}
+
+static int zilog_init(struct IR_i2c *ir)
+{
+ struct code_block code_block = { .length = sizeof(code_block) };
+ u8 buf[4];
+ int ret;
+
+ put_unaligned_be16(0x1000, &code_block.pulse[3]);
+
+ ret = send_data_block(ir, ZILOG_INIT_END, &code_block);
+ if (ret)
+ return ret;
+
+ ret = i2c_master_recv(ir->tx_c, buf, 4);
+ if (ret != 4) {
+ dev_err(&ir->c->dev, "failed to retrieve firmware version: %d\n",
+ ret);
+ return ret < 0 ? ret : -EIO;
+ }
+
+ dev_info(&ir->c->dev, "Zilog/Hauppauge IR blaster firmware version %d.%d.%d\n",
+ buf[1], buf[2], buf[3]);
+
+ return 0;
+}
+
+/*
+ * If the last slot for pulse is the same as the current slot for pulse,
+ * then use slot no 7.
+ */
+static void copy_codes(u8 *dst, u8 *src, unsigned int count)
+{
+ u8 c, last = 0xff;
+
+ while (count--) {
+ c = *src++;
+ if ((c & 0xf0) == last) {
+ *dst++ = 0x70 | (c & 0xf);
+ } else {
+ *dst++ = c;
+ last = c & 0xf0;
+ }
+ }
+}
+
+/*
+ * When looking for repeats, we don't care about the trailing space. This
+ * is set to the shortest possible anyway.
+ */
+static int cmp_no_trail(u8 *a, u8 *b, unsigned int count)
+{
+ while (--count) {
+ if (*a++ != *b++)
+ return 1;
+ }
+
+ return (*a & 0xf0) - (*b & 0xf0);
+}
+
+static int find_slot(u16 *array, unsigned int size, u16 val)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (get_unaligned_be16(&array[i]) == val) {
+ return i;
+ } else if (!array[i]) {
+ put_unaligned_be16(val, &array[i]);
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static int zilog_ir_format(struct rc_dev *rcdev, unsigned int *txbuf,
+ unsigned int count, struct code_block *code_block)
+{
+ struct IR_i2c *ir = rcdev->priv;
+ int rep, i, l, p = 0, s, c = 0;
+ bool repeating;
+ u8 codes[174];
+
+ code_block->carrier_pulse = DIV_ROUND_CLOSEST(
+ ir->duty_cycle * XTAL_FREQ / 1000, ir->carrier);
+ code_block->carrier_space = DIV_ROUND_CLOSEST(
+ (100 - ir->duty_cycle) * XTAL_FREQ / 1000, ir->carrier);
+
+ for (i = 0; i < count; i++) {
+ if (c >= ARRAY_SIZE(codes) - 1) {
+ dev_warn(&rcdev->dev, "IR too long, cannot transmit\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Lengths more than 142220us cannot be encoded; also
+ * this checks for multiply overflow
+ */
+ if (txbuf[i] > 142220)
+ return -EINVAL;
+
+ l = DIV_ROUND_CLOSEST((XTAL_FREQ / 1000) * txbuf[i], 40000);
+
+ if (i & 1) {
+ s = find_slot(code_block->space,
+ ARRAY_SIZE(code_block->space), l);
+ if (s == -1) {
+ dev_warn(&rcdev->dev, "Too many different lengths spaces, cannot transmit");
+ return -EINVAL;
+ }
+
+ /* We have a pulse and space */
+ codes[c++] = (p << 4) | s;
+ } else {
+ p = find_slot(code_block->pulse,
+ ARRAY_SIZE(code_block->pulse), l);
+ if (p == -1) {
+ dev_warn(&rcdev->dev, "Too many different lengths pulses, cannot transmit");
+ return -EINVAL;
+ }
+ }
+ }
+
+ /* We have to encode the trailing pulse. Find the shortest space */
+ s = 0;
+ for (i = 1; i < ARRAY_SIZE(code_block->space); i++) {
+ u16 d = get_unaligned_be16(&code_block->space[i]);
+
+ if (get_unaligned_be16(&code_block->space[s]) > d)
+ s = i;
+ }
+
+ codes[c++] = (p << 4) | s;
+
+ dev_dbg(&rcdev->dev, "generated %d codes\n", c);
+
+ /*
+ * Are the last N codes (so pulse + space) repeating 3 times?
+ * if so we can shorten the codes list and use code 0xc0 to repeat
+ * them.
+ */
+ repeating = false;
+
+ for (rep = c / 3; rep >= 1; rep--) {
+ if (!memcmp(&codes[c - rep * 3], &codes[c - rep * 2], rep) &&
+ !cmp_no_trail(&codes[c - rep], &codes[c - rep * 2], rep)) {
+ repeating = true;
+ break;
+ }
+ }
+
+ if (repeating) {
+ /* first copy any leading non-repeating */
+ int leading = c - rep * 3;
+
+ if (leading + rep >= ARRAY_SIZE(code_block->codes) - 3) {
+ dev_warn(&rcdev->dev, "IR too long, cannot transmit\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(&rcdev->dev, "found trailing %d repeat\n", rep);
+ copy_codes(code_block->codes, codes, leading);
+ code_block->codes[leading] = 0x82;
+ copy_codes(code_block->codes + leading + 1, codes + leading,
+ rep);
+ c = leading + 1 + rep;
+ code_block->codes[c++] = 0xc0;
+ } else {
+ if (c >= ARRAY_SIZE(code_block->codes) - 3) {
+ dev_warn(&rcdev->dev, "IR too long, cannot transmit\n");
+ return -EINVAL;
+ }
+
+ dev_dbg(&rcdev->dev, "found no trailing repeat\n");
+ code_block->codes[0] = 0x82;
+ copy_codes(code_block->codes + 1, codes, c);
+ c++;
+ code_block->codes[c++] = 0xc4;
+ }
+
+ while (c < ARRAY_SIZE(code_block->codes))
+ code_block->codes[c++] = 0x83;
+
+ return 0;
+}
+
+static int zilog_tx(struct rc_dev *rcdev, unsigned int *txbuf,
+ unsigned int count)
+{
+ struct IR_i2c *ir = rcdev->priv;
+ struct code_block code_block = { .length = sizeof(code_block) };
+ u8 buf[2];
+ int ret, i;
+
+ ret = zilog_ir_format(rcdev, txbuf, count, &code_block);
+ if (ret)
+ return ret;
+
+ ret = mutex_lock_interruptible(&ir->lock);
+ if (ret)
+ return ret;
+
+ ret = send_data_block(ir, ZILOG_UIR_END, &code_block);
+ if (ret)
+ goto out_unlock;
+
+ ret = i2c_master_recv(ir->tx_c, buf, 1);
+ if (ret != 1) {
+ dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret);
+ goto out_unlock;
+ }
+
+ dev_dbg(&ir->rc->dev, "code set status: %02x\n", buf[0]);
+
+ if (buf[0] != (ZILOG_STATUS_OK | ZILOG_STATUS_SET)) {
+ dev_err(&ir->rc->dev, "unexpected IR TX response %02x\n",
+ buf[0]);
+ ret = -EIO;
+ goto out_unlock;
+ }
+
+ buf[0] = 0x00;
+ buf[1] = ZILOG_SEND;
+
+ ret = i2c_master_send(ir->tx_c, buf, 2);
+ if (ret != 2) {
+ dev_err(&ir->rc->dev, "i2c_master_send failed with %d\n", ret);
+ if (ret >= 0)
+ ret = -EIO;
+ goto out_unlock;
+ }
+
+ dev_dbg(&ir->rc->dev, "send command sent\n");
+
+ /*
+ * This bit NAKs until the device is ready, so we retry it
+ * sleeping a bit each time. This seems to be what the windows
+ * driver does, approximately.
+ * Try for up to 1s.
+ */
+ for (i = 0; i < 20; ++i) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(msecs_to_jiffies(50));
+ ret = i2c_master_send(ir->tx_c, buf, 1);
+ if (ret == 1)
+ break;
+ dev_dbg(&ir->rc->dev,
+ "NAK expected: i2c_master_send failed with %d (try %d)\n",
+ ret, i + 1);
+ }
+
+ if (ret != 1) {
+ dev_err(&ir->rc->dev,
+ "IR TX chip never got ready: last i2c_master_send failed with %d\n",
+ ret);
+ if (ret >= 0)
+ ret = -EIO;
+ goto out_unlock;
+ }
+
+ i = i2c_master_recv(ir->tx_c, buf, 1);
+ if (i != 1) {
+ dev_err(&ir->rc->dev, "i2c_master_recv failed with %d\n", ret);
+ ret = -EIO;
+ goto out_unlock;
+ } else if (buf[0] != ZILOG_STATUS_OK) {
+ dev_err(&ir->rc->dev, "unexpected IR TX response #2: %02x\n",
+ buf[0]);
+ ret = -EIO;
+ goto out_unlock;
+ }
+ dev_dbg(&ir->rc->dev, "transmit complete\n");
+
+ /* Oh good, it worked */
+ ret = count;
+out_unlock:
+ mutex_unlock(&ir->lock);
+
+ return ret;
+}
+
+static int zilog_tx_carrier(struct rc_dev *dev, u32 carrier)
+{
+ struct IR_i2c *ir = dev->priv;
+
+ if (carrier > 500000 || carrier < 20000)
+ return -EINVAL;
+
+ ir->carrier = carrier;
+
+ return 0;
+}
+
+static int zilog_tx_duty_cycle(struct rc_dev *dev, u32 duty_cycle)
+{
+ struct IR_i2c *ir = dev->priv;
+
+ ir->duty_cycle = duty_cycle;
+
+ return 0;
+}
static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
@@ -322,6 +729,11 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
unsigned short addr = client->addr;
int err;
+ if ((id->driver_data & FLAG_HDPVR) && !enable_hdpvr) {
+ dev_err(&client->dev, "IR for HDPVR is known to cause problems during recording, use enable_hdpvr modparam to enable\n");
+ return -ENODEV;
+ }
+
ir = devm_kzalloc(&client->dev, sizeof(*ir), GFP_KERNEL);
if (!ir)
return -ENOMEM;
@@ -433,18 +845,15 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
/* Make sure we are all setup before going on */
if (!name || !ir->get_key || !rc_proto || !ir_codes) {
- dprintk(1, ": Unsupported device at address 0x%02x\n",
- addr);
+ dev_warn(&client->dev, "Unsupported device at address 0x%02x\n",
+ addr);
err = -ENODEV;
goto err_out_free;
}
- /* Sets name */
- snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
ir->ir_codes = ir_codes;
- snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
- dev_name(&adap->dev),
+ snprintf(ir->phys, sizeof(ir->phys), "%s/%s", dev_name(&adap->dev),
dev_name(&client->dev));
/*
@@ -453,7 +862,11 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
*/
rc->input_id.bustype = BUS_I2C;
rc->input_phys = ir->phys;
- rc->device_name = ir->name;
+ rc->device_name = name;
+ rc->dev.parent = &client->dev;
+ rc->priv = ir;
+ rc->open = ir_open;
+ rc->close = ir_close;
/*
* Initialize the other fields of rc_dev
@@ -461,22 +874,35 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
rc->map_name = ir->ir_codes;
rc->allowed_protocols = rc_proto;
if (!rc->driver_name)
- rc->driver_name = MODULE_NAME;
+ rc->driver_name = KBUILD_MODNAME;
+
+ mutex_init(&ir->lock);
+
+ INIT_DELAYED_WORK(&ir->work, ir_work);
+
+ if (id->driver_data & FLAG_TX) {
+ ir->tx_c = i2c_new_dummy(client->adapter, 0x70);
+ if (!ir->tx_c) {
+ dev_err(&client->dev, "failed to setup tx i2c address");
+ } else if (!zilog_init(ir)) {
+ ir->carrier = 38000;
+ ir->duty_cycle = 40;
+ rc->tx_ir = zilog_tx;
+ rc->s_tx_carrier = zilog_tx_carrier;
+ rc->s_tx_duty_cycle = zilog_tx_duty_cycle;
+ }
+ }
err = rc_register_device(rc);
if (err)
goto err_out_free;
- printk(MODULE_NAME ": %s detected at %s [%s]\n",
- ir->name, ir->phys, adap->name);
-
- /* start polling via eventd */
- INIT_DELAYED_WORK(&ir->work, ir_work);
- schedule_delayed_work(&ir->work, 0);
-
return 0;
err_out_free:
+ if (ir->tx_c)
+ i2c_unregister_device(ir->tx_c);
+
/* Only frees rc if it were allocated internally */
rc_free_device(rc);
return err;
@@ -489,6 +915,9 @@ static int ir_remove(struct i2c_client *client)
/* kill outstanding polls */
cancel_delayed_work_sync(&ir->work);
+ if (ir->tx_c)
+ i2c_unregister_device(ir->tx_c);
+
/* unregister device */
rc_unregister_device(ir->rc);
@@ -500,10 +929,11 @@ static const struct i2c_device_id ir_kbd_id[] = {
/* Generic entry for any IR receiver */
{ "ir_video", 0 },
/* IR device specific entries should be added here */
- { "ir_rx_z8f0811_haup", 0 },
- { "ir_rx_z8f0811_hdpvr", 0 },
+ { "ir_z8f0811_haup", FLAG_TX },
+ { "ir_z8f0811_hdpvr", FLAG_TX | FLAG_HDPVR },
{ }
};
+MODULE_DEVICE_TABLE(i2c, ir_kbd_id);
static struct i2c_driver ir_kbd_driver = {
.driver = {
diff --git a/drivers/media/i2c/ks0127.c b/drivers/media/i2c/ks0127.c
index ab536c4a7115..5905ed6f8397 100644
--- a/drivers/media/i2c/ks0127.c
+++ b/drivers/media/i2c/ks0127.c
@@ -195,7 +195,7 @@ struct adjust {
struct ks0127 {
struct v4l2_subdev sd;
v4l2_std_id norm;
- u8 regs[256];
+ u8 regs[256];
};
static inline struct ks0127 *to_ks0127(struct v4l2_subdev *sd)
diff --git a/drivers/media/i2c/mt9m111.c b/drivers/media/i2c/mt9m111.c
index b1665d97e0fd..efda1aa95ca0 100644
--- a/drivers/media/i2c/mt9m111.c
+++ b/drivers/media/i2c/mt9m111.c
@@ -92,6 +92,7 @@
*/
#define MT9M111_OPER_MODE_CTRL 0x106
#define MT9M111_OUTPUT_FORMAT_CTRL 0x108
+#define MT9M111_TPG_CTRL 0x148
#define MT9M111_REDUCER_XZOOM_B 0x1a0
#define MT9M111_REDUCER_XSIZE_B 0x1a1
#define MT9M111_REDUCER_YZOOM_B 0x1a3
@@ -124,6 +125,7 @@
#define MT9M111_OUTFMT_AVG_CHROMA (1 << 2)
#define MT9M111_OUTFMT_SWAP_YCbCr_C_Y_RGB_EVEN (1 << 1)
#define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr_RGB_R_B (1 << 0)
+#define MT9M111_TPG_SEL_MASK GENMASK(2, 0)
/*
* Camera control register addresses (0x200..0x2ff not implemented)
@@ -215,6 +217,9 @@ struct mt9m111 {
int power_count;
const struct mt9m111_datafmt *fmt;
int lastpage; /* PageMap cache value */
+#ifdef CONFIG_MEDIA_CONTROLLER
+ struct media_pad pad;
+#endif
};
/* Find a data format by a pixel code */
@@ -703,6 +708,25 @@ static int mt9m111_set_autowhitebalance(struct mt9m111 *mt9m111, int on)
return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
}
+static const char * const mt9m111_test_pattern_menu[] = {
+ "Disabled",
+ "Vertical monochrome gradient",
+ "Flat color type 1",
+ "Flat color type 2",
+ "Flat color type 3",
+ "Flat color type 4",
+ "Flat color type 5",
+ "Color bar",
+};
+
+static int mt9m111_set_test_pattern(struct mt9m111 *mt9m111, int val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
+
+ return mt9m111_reg_mask(client, MT9M111_TPG_CTRL, val,
+ MT9M111_TPG_SEL_MASK);
+}
+
static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct mt9m111 *mt9m111 = container_of(ctrl->handler,
@@ -721,6 +745,8 @@ static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl)
return mt9m111_set_autoexposure(mt9m111, ctrl->val);
case V4L2_CID_AUTO_WHITE_BALANCE:
return mt9m111_set_autowhitebalance(mt9m111, ctrl->val);
+ case V4L2_CID_TEST_PATTERN:
+ return mt9m111_set_test_pattern(mt9m111, ctrl->val);
}
return -EINVAL;
@@ -951,6 +977,8 @@ static int mt9m111_probe(struct i2c_client *client,
mt9m111->ctx = &context_b;
v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
+ mt9m111->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
v4l2_ctrl_handler_init(&mt9m111->hdl, 5);
v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
V4L2_CID_VFLIP, 0, 1, 1, 0);
@@ -963,12 +991,24 @@ static int mt9m111_probe(struct i2c_client *client,
v4l2_ctrl_new_std_menu(&mt9m111->hdl,
&mt9m111_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
V4L2_EXPOSURE_AUTO);
+ v4l2_ctrl_new_std_menu_items(&mt9m111->hdl,
+ &mt9m111_ctrl_ops, V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(mt9m111_test_pattern_menu) - 1, 0, 0,
+ mt9m111_test_pattern_menu);
mt9m111->subdev.ctrl_handler = &mt9m111->hdl;
if (mt9m111->hdl.error) {
ret = mt9m111->hdl.error;
goto out_clkput;
}
+#ifdef CONFIG_MEDIA_CONTROLLER
+ mt9m111->pad.flags = MEDIA_PAD_FL_SOURCE;
+ mt9m111->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ ret = media_entity_pads_init(&mt9m111->subdev.entity, 1, &mt9m111->pad);
+ if (ret < 0)
+ goto out_hdlfree;
+#endif
+
/* Second stage probe - when a capture adapter is there */
mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
mt9m111->rect.top = MT9M111_MIN_DARK_ROWS;
@@ -980,16 +1020,20 @@ static int mt9m111_probe(struct i2c_client *client,
ret = mt9m111_video_probe(client);
if (ret < 0)
- goto out_hdlfree;
+ goto out_entityclean;
mt9m111->subdev.dev = &client->dev;
ret = v4l2_async_register_subdev(&mt9m111->subdev);
if (ret < 0)
- goto out_hdlfree;
+ goto out_entityclean;
return 0;
+out_entityclean:
+#ifdef CONFIG_MEDIA_CONTROLLER
+ media_entity_cleanup(&mt9m111->subdev.entity);
out_hdlfree:
+#endif
v4l2_ctrl_handler_free(&mt9m111->hdl);
out_clkput:
v4l2_clk_put(mt9m111->clk);
@@ -1002,6 +1046,7 @@ static int mt9m111_remove(struct i2c_client *client)
struct mt9m111 *mt9m111 = to_mt9m111(client);
v4l2_async_unregister_subdev(&mt9m111->subdev);
+ media_entity_cleanup(&mt9m111->subdev.entity);
v4l2_clk_put(mt9m111->clk);
v4l2_ctrl_handler_free(&mt9m111->hdl);
diff --git a/drivers/media/i2c/mt9v011.c b/drivers/media/i2c/mt9v011.c
index 9ed1b26b6549..5e29064fae91 100644
--- a/drivers/media/i2c/mt9v011.c
+++ b/drivers/media/i2c/mt9v011.c
@@ -1,9 +1,8 @@
-/*
- * mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor
- *
- * Copyright (c) 2009 Mauro Carvalho Chehab
- * This code is placed under the terms of the GNU General Public License v2
- */
+// SPDX-License-Identifier: GPL-2.0
+//
+// mt9v011 -Micron 1/4-Inch VGA Digital Image Sensor
+//
+// Copyright (c) 2009 Mauro Carvalho Chehab <mchehab@kernel.org>
#include <linux/i2c.h>
#include <linux/slab.h>
@@ -17,7 +16,7 @@
MODULE_DESCRIPTION("Micron mt9v011 sensor driver");
MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
static int debug;
module_param(debug, int, 0);
diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c
index 8a430640c85d..4de63b2df334 100644
--- a/drivers/media/i2c/mt9v032.c
+++ b/drivers/media/i2c/mt9v032.c
@@ -294,14 +294,22 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032)
/* Reset the chip and stop data read out */
ret = regmap_write(map, MT9V032_RESET, 1);
if (ret < 0)
- return ret;
+ goto err;
ret = regmap_write(map, MT9V032_RESET, 0);
if (ret < 0)
- return ret;
+ goto err;
+
+ ret = regmap_write(map, MT9V032_CHIP_CONTROL,
+ MT9V032_CHIP_CONTROL_MASTER_MODE);
+ if (ret < 0)
+ goto err;
+
+ return 0;
- return regmap_write(map, MT9V032_CHIP_CONTROL,
- MT9V032_CHIP_CONTROL_MASTER_MODE);
+err:
+ clk_disable_unprepare(mt9v032->clk);
+ return ret;
}
static void mt9v032_power_off(struct mt9v032 *mt9v032)
@@ -876,6 +884,9 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
/* Read and check the sensor version */
ret = regmap_read(mt9v032->regmap, MT9V032_CHIP_VERSION, &version);
+
+ mt9v032_power_off(mt9v032);
+
if (ret < 0) {
dev_err(&client->dev, "Failed reading chip version\n");
return ret;
@@ -894,8 +905,6 @@ static int mt9v032_registered(struct v4l2_subdev *subdev)
return -ENODEV;
}
- mt9v032_power_off(mt9v032);
-
dev_info(&client->dev, "%s detected at address 0x%02x\n",
mt9v032->version->name, client->addr);
diff --git a/drivers/media/i2c/ov2640.c b/drivers/media/i2c/ov2640.c
index 518868388d65..4c3b92763243 100644
--- a/drivers/media/i2c/ov2640.c
+++ b/drivers/media/i2c/ov2640.c
@@ -1147,9 +1147,7 @@ static int ov2640_probe(struct i2c_client *client,
return 0;
err_videoprobe:
-#if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&priv->subdev.entity);
-#endif
err_hdl:
v4l2_ctrl_handler_free(&priv->hdl);
err_clk:
@@ -1163,9 +1161,7 @@ static int ov2640_remove(struct i2c_client *client)
v4l2_async_unregister_subdev(&priv->subdev);
v4l2_ctrl_handler_free(&priv->hdl);
-#if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&priv->subdev.entity);
-#endif
v4l2_device_unregister_subdev(&priv->subdev);
clk_disable_unprepare(priv->clk);
return 0;
diff --git a/drivers/media/i2c/ov2659.c b/drivers/media/i2c/ov2659.c
index 122dd6c5eb38..4715edc8ca33 100644
--- a/drivers/media/i2c/ov2659.c
+++ b/drivers/media/i2c/ov2659.c
@@ -1474,9 +1474,7 @@ static int ov2659_probe(struct i2c_client *client,
error:
v4l2_ctrl_handler_free(&ov2659->ctrls);
-#if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&sd->entity);
-#endif
mutex_destroy(&ov2659->lock);
return ret;
}
@@ -1488,9 +1486,7 @@ static int ov2659_remove(struct i2c_client *client)
v4l2_ctrl_handler_free(&ov2659->ctrls);
v4l2_async_unregister_subdev(sd);
-#if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&sd->entity);
-#endif
mutex_destroy(&ov2659->lock);
return 0;
diff --git a/drivers/media/i2c/ov5640.c b/drivers/media/i2c/ov5640.c
index c89ed6609738..e2dd352224c7 100644
--- a/drivers/media/i2c/ov5640.c
+++ b/drivers/media/i2c/ov5640.c
@@ -34,13 +34,19 @@
#define OV5640_DEFAULT_SLAVE_ID 0x3c
+#define OV5640_REG_SYS_CTRL0 0x3008
#define OV5640_REG_CHIP_ID 0x300a
+#define OV5640_REG_IO_MIPI_CTRL00 0x300e
+#define OV5640_REG_PAD_OUTPUT_ENABLE01 0x3017
+#define OV5640_REG_PAD_OUTPUT_ENABLE02 0x3018
#define OV5640_REG_PAD_OUTPUT00 0x3019
+#define OV5640_REG_SYSTEM_CONTROL1 0x302e
#define OV5640_REG_SC_PLL_CTRL0 0x3034
#define OV5640_REG_SC_PLL_CTRL1 0x3035
#define OV5640_REG_SC_PLL_CTRL2 0x3036
#define OV5640_REG_SC_PLL_CTRL3 0x3037
#define OV5640_REG_SLAVE_ID 0x3100
+#define OV5640_REG_SCCB_SYS_CTRL1 0x3103
#define OV5640_REG_SYS_ROOT_DIVIDER 0x3108
#define OV5640_REG_AWB_R_GAIN 0x3400
#define OV5640_REG_AWB_G_GAIN 0x3402
@@ -70,8 +76,11 @@
#define OV5640_REG_HZ5060_CTRL01 0x3c01
#define OV5640_REG_SIGMADELTA_CTRL0C 0x3c0c
#define OV5640_REG_FRAME_CTRL01 0x4202
+#define OV5640_REG_FORMAT_CONTROL00 0x4300
+#define OV5640_REG_POLARITY_CTRL00 0x4740
#define OV5640_REG_MIPI_CTRL00 0x4800
#define OV5640_REG_DEBUG_MODE 0x4814
+#define OV5640_REG_ISP_FORMAT_MUX_CTRL 0x501f
#define OV5640_REG_PRE_ISP_TEST_SET1 0x503d
#define OV5640_REG_SDE_CTRL0 0x5580
#define OV5640_REG_SDE_CTRL1 0x5581
@@ -99,6 +108,18 @@ enum ov5640_frame_rate {
OV5640_NUM_FRAMERATES,
};
+struct ov5640_pixfmt {
+ u32 code;
+ u32 colorspace;
+};
+
+static const struct ov5640_pixfmt ov5640_formats[] = {
+ { MEDIA_BUS_FMT_UYVY8_2X8, V4L2_COLORSPACE_SRGB, },
+ { MEDIA_BUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_SRGB, },
+ { MEDIA_BUS_FMT_RGB565_2X8_LE, V4L2_COLORSPACE_SRGB, },
+ { MEDIA_BUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_SRGB, },
+};
+
/*
* FIXME: remove this when a subdev API becomes available
* to set the MIPI CSI-2 virtual channel.
@@ -982,7 +1003,111 @@ static int ov5640_get_gain(struct ov5640_dev *sensor)
return gain & 0x3ff;
}
-static int ov5640_set_stream(struct ov5640_dev *sensor, bool on)
+static int ov5640_set_stream_dvp(struct ov5640_dev *sensor, bool on)
+{
+ int ret;
+ unsigned int flags = sensor->ep.bus.parallel.flags;
+ u8 pclk_pol = 0;
+ u8 hsync_pol = 0;
+ u8 vsync_pol = 0;
+
+ /*
+ * Note about parallel port configuration.
+ *
+ * When configured in parallel mode, the OV5640 will
+ * output 10 bits data on DVP data lines [9:0].
+ * If only 8 bits data are wanted, the 8 bits data lines
+ * of the camera interface must be physically connected
+ * on the DVP data lines [9:2].
+ *
+ * Control lines polarity can be configured through
+ * devicetree endpoint control lines properties.
+ * If no endpoint control lines properties are set,
+ * polarity will be as below:
+ * - VSYNC: active high
+ * - HREF: active low
+ * - PCLK: active low
+ */
+
+ if (on) {
+ /*
+ * reset MIPI PCLK/SERCLK divider
+ *
+ * SC PLL CONTRL1 0
+ * - [3..0]: MIPI PCLK/SERCLK divider
+ */
+ ret = ov5640_mod_reg(sensor, OV5640_REG_SC_PLL_CTRL1, 0x0f, 0);
+ if (ret)
+ return ret;
+
+ /*
+ * configure parallel port control lines polarity
+ *
+ * POLARITY CTRL0
+ * - [5]: PCLK polarity (0: active low, 1: active high)
+ * - [1]: HREF polarity (0: active low, 1: active high)
+ * - [0]: VSYNC polarity (mismatch here between
+ * datasheet and hardware, 0 is active high
+ * and 1 is active low...)
+ */
+ if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
+ pclk_pol = 1;
+ if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
+ hsync_pol = 1;
+ if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
+ vsync_pol = 1;
+
+ ret = ov5640_write_reg(sensor,
+ OV5640_REG_POLARITY_CTRL00,
+ (pclk_pol << 5) |
+ (hsync_pol << 1) |
+ vsync_pol);
+
+ if (ret)
+ return ret;
+ }
+
+ /*
+ * powerdown MIPI TX/RX PHY & disable MIPI
+ *
+ * MIPI CONTROL 00
+ * 4: PWDN PHY TX
+ * 3: PWDN PHY RX
+ * 2: MIPI enable
+ */
+ ret = ov5640_write_reg(sensor,
+ OV5640_REG_IO_MIPI_CTRL00, on ? 0x18 : 0);
+ if (ret)
+ return ret;
+
+ /*
+ * enable VSYNC/HREF/PCLK DVP control lines
+ * & D[9:6] DVP data lines
+ *
+ * PAD OUTPUT ENABLE 01
+ * - 6: VSYNC output enable
+ * - 5: HREF output enable
+ * - 4: PCLK output enable
+ * - [3:0]: D[9:6] output enable
+ */
+ ret = ov5640_write_reg(sensor,
+ OV5640_REG_PAD_OUTPUT_ENABLE01,
+ on ? 0x7f : 0);
+ if (ret)
+ return ret;
+
+ /*
+ * enable D[5:0] DVP data lines
+ *
+ * PAD OUTPUT ENABLE 02
+ * - [7:2]: D[5:0] output enable
+ */
+ return ov5640_write_reg(sensor,
+ OV5640_REG_PAD_OUTPUT_ENABLE02,
+ on ? 0xfc : 0);
+}
+
+static int ov5640_set_stream_mipi(struct ov5640_dev *sensor, bool on)
{
int ret;
@@ -1524,7 +1649,7 @@ static int ov5640_restore_mode(struct ov5640_dev *sensor)
static void ov5640_power(struct ov5640_dev *sensor, bool enable)
{
- gpiod_set_value(sensor->pwdn_gpio, enable ? 0 : 1);
+ gpiod_set_value_cansleep(sensor->pwdn_gpio, enable ? 0 : 1);
}
static void ov5640_reset(struct ov5640_dev *sensor)
@@ -1532,7 +1657,7 @@ static void ov5640_reset(struct ov5640_dev *sensor)
if (!sensor->reset_gpio)
return;
- gpiod_set_value(sensor->reset_gpio, 0);
+ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
/* camera power cycle */
ov5640_power(sensor, false);
@@ -1540,56 +1665,89 @@ static void ov5640_reset(struct ov5640_dev *sensor)
ov5640_power(sensor, true);
usleep_range(5000, 10000);
- gpiod_set_value(sensor->reset_gpio, 1);
+ gpiod_set_value_cansleep(sensor->reset_gpio, 1);
usleep_range(1000, 2000);
- gpiod_set_value(sensor->reset_gpio, 0);
+ gpiod_set_value_cansleep(sensor->reset_gpio, 0);
usleep_range(5000, 10000);
}
-static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
+static int ov5640_set_power_on(struct ov5640_dev *sensor)
{
- int ret = 0;
+ struct i2c_client *client = sensor->i2c_client;
+ int ret;
- if (on) {
- clk_prepare_enable(sensor->xclk);
+ ret = clk_prepare_enable(sensor->xclk);
+ if (ret) {
+ dev_err(&client->dev, "%s: failed to enable clock\n",
+ __func__);
+ return ret;
+ }
- ret = regulator_bulk_enable(OV5640_NUM_SUPPLIES,
- sensor->supplies);
- if (ret)
- goto xclk_off;
+ ret = regulator_bulk_enable(OV5640_NUM_SUPPLIES,
+ sensor->supplies);
+ if (ret) {
+ dev_err(&client->dev, "%s: failed to enable regulators\n",
+ __func__);
+ goto xclk_off;
+ }
+
+ ov5640_reset(sensor);
+ ov5640_power(sensor, true);
- ov5640_reset(sensor);
- ov5640_power(sensor, true);
+ ret = ov5640_init_slave_id(sensor);
+ if (ret)
+ goto power_off;
- ret = ov5640_init_slave_id(sensor);
+ return 0;
+
+power_off:
+ ov5640_power(sensor, false);
+ regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
+xclk_off:
+ clk_disable_unprepare(sensor->xclk);
+ return ret;
+}
+
+static void ov5640_set_power_off(struct ov5640_dev *sensor)
+{
+ ov5640_power(sensor, false);
+ regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
+ clk_disable_unprepare(sensor->xclk);
+}
+
+static int ov5640_set_power(struct ov5640_dev *sensor, bool on)
+{
+ int ret = 0;
+
+ if (on) {
+ ret = ov5640_set_power_on(sensor);
if (ret)
- goto power_off;
+ return ret;
ret = ov5640_restore_mode(sensor);
if (ret)
goto power_off;
- /*
- * start streaming briefly followed by stream off in
- * order to coax the clock lane into LP-11 state.
- */
- ret = ov5640_set_stream(sensor, true);
- if (ret)
- goto power_off;
- usleep_range(1000, 2000);
- ret = ov5640_set_stream(sensor, false);
- if (ret)
- goto power_off;
+ if (sensor->ep.bus_type == V4L2_MBUS_CSI2) {
+ /*
+ * start streaming briefly followed by stream off in
+ * order to coax the clock lane into LP-11 state.
+ */
+ ret = ov5640_set_stream_mipi(sensor, true);
+ if (ret)
+ goto power_off;
+ usleep_range(1000, 2000);
+ ret = ov5640_set_stream_mipi(sensor, false);
+ if (ret)
+ goto power_off;
+ }
return 0;
}
power_off:
- ov5640_power(sensor, false);
- regulator_bulk_disable(OV5640_NUM_SUPPLIES, sensor->supplies);
-xclk_off:
- clk_disable_unprepare(sensor->xclk);
+ ov5640_set_power_off(sensor);
return ret;
}
@@ -1693,17 +1851,23 @@ static int ov5640_try_fmt_internal(struct v4l2_subdev *sd,
{
struct ov5640_dev *sensor = to_ov5640_dev(sd);
const struct ov5640_mode_info *mode;
+ int i;
mode = ov5640_find_mode(sensor, fr, fmt->width, fmt->height, true);
if (!mode)
return -EINVAL;
-
fmt->width = mode->width;
fmt->height = mode->height;
- fmt->code = sensor->fmt.code;
if (new_mode)
*new_mode = mode;
+
+ for (i = 0; i < ARRAY_SIZE(ov5640_formats); i++)
+ if (ov5640_formats[i].code == fmt->code)
+ break;
+ if (i >= ARRAY_SIZE(ov5640_formats))
+ fmt->code = ov5640_formats[0].code;
+
return 0;
}
@@ -1746,6 +1910,45 @@ out:
return ret;
}
+static int ov5640_set_framefmt(struct ov5640_dev *sensor,
+ struct v4l2_mbus_framefmt *format)
+{
+ int ret = 0;
+ bool is_rgb = false;
+ u8 val;
+
+ switch (format->code) {
+ case MEDIA_BUS_FMT_UYVY8_2X8:
+ /* YUV422, UYVY */
+ val = 0x3f;
+ break;
+ case MEDIA_BUS_FMT_YUYV8_2X8:
+ /* YUV422, YUYV */
+ val = 0x30;
+ break;
+ case MEDIA_BUS_FMT_RGB565_2X8_LE:
+ /* RGB565 {g[2:0],b[4:0]},{r[4:0],g[5:3]} */
+ val = 0x6F;
+ is_rgb = true;
+ break;
+ case MEDIA_BUS_FMT_RGB565_2X8_BE:
+ /* RGB565 {r[4:0],g[5:3]},{g[2:0],b[4:0]} */
+ val = 0x61;
+ is_rgb = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* FORMAT CONTROL00: YUV and RGB formatting */
+ ret = ov5640_write_reg(sensor, OV5640_REG_FORMAT_CONTROL00, val);
+ if (ret)
+ return ret;
+
+ /* FORMAT MUX CONTROL: ISP YUV or RGB */
+ return ov5640_write_reg(sensor, OV5640_REG_ISP_FORMAT_MUX_CTRL,
+ is_rgb ? 0x01 : 0x00);
+}
/*
* Sensor Controls.
@@ -1854,6 +2057,7 @@ static int ov5640_set_ctrl_exposure(struct ov5640_dev *sensor, int exp)
if (ret < 0)
return ret;
max_exp += ret;
+ ret = 0;
if (ctrls->exposure->val < max_exp)
ret = ov5640_set_exposure(sensor, ctrls->exposure->val);
@@ -2131,15 +2335,12 @@ static int ov5640_enum_mbus_code(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code)
{
- struct ov5640_dev *sensor = to_ov5640_dev(sd);
-
if (code->pad != 0)
return -EINVAL;
- if (code->index != 0)
+ if (code->index >= ARRAY_SIZE(ov5640_formats))
return -EINVAL;
- code->code = sensor->fmt.code;
-
+ code->code = ov5640_formats[code->index].code;
return 0;
}
@@ -2155,9 +2356,17 @@ static int ov5640_s_stream(struct v4l2_subdev *sd, int enable)
ret = ov5640_set_mode(sensor, sensor->current_mode);
if (ret)
goto out;
+
+ ret = ov5640_set_framefmt(sensor, &sensor->fmt);
+ if (ret)
+ goto out;
}
- ret = ov5640_set_stream(sensor, enable);
+ if (sensor->ep.bus_type == V4L2_MBUS_CSI2)
+ ret = ov5640_set_stream_mipi(sensor, enable);
+ else
+ ret = ov5640_set_stream_dvp(sensor, enable);
+
if (!ret)
sensor->streaming = enable;
}
@@ -2202,6 +2411,34 @@ static int ov5640_get_regulators(struct ov5640_dev *sensor)
sensor->supplies);
}
+static int ov5640_check_chip_id(struct ov5640_dev *sensor)
+{
+ struct i2c_client *client = sensor->i2c_client;
+ int ret = 0;
+ u16 chip_id;
+
+ ret = ov5640_set_power_on(sensor);
+ if (ret)
+ return ret;
+
+ ret = ov5640_read_reg16(sensor, OV5640_REG_CHIP_ID, &chip_id);
+ if (ret) {
+ dev_err(&client->dev, "%s: failed to read chip identifier\n",
+ __func__);
+ goto power_off;
+ }
+
+ if (chip_id != 0x5640) {
+ dev_err(&client->dev, "%s: wrong chip identifier, expected 0x5640, got 0x%x\n",
+ __func__, chip_id);
+ ret = -ENXIO;
+ }
+
+power_off:
+ ov5640_set_power_off(sensor);
+ return ret;
+}
+
static int ov5640_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -2242,11 +2479,6 @@ static int ov5640_probe(struct i2c_client *client,
return ret;
}
- if (sensor->ep.bus_type != V4L2_MBUS_CSI2) {
- dev_err(dev, "invalid bus type, must be MIPI CSI2\n");
- return -EINVAL;
- }
-
/* get system clock (xclk) */
sensor->xclk = devm_clk_get(dev, "xclk");
if (IS_ERR(sensor->xclk)) {
@@ -2284,6 +2516,10 @@ static int ov5640_probe(struct i2c_client *client,
mutex_init(&sensor->lock);
+ ret = ov5640_check_chip_id(sensor);
+ if (ret)
+ goto entity_cleanup;
+
ret = ov5640_init_controls(sensor);
if (ret)
goto entity_cleanup;
diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
index 950a0acf85fb..28571de1c2f6 100644
--- a/drivers/media/i2c/ov7670.c
+++ b/drivers/media/i2c/ov7670.c
@@ -163,6 +163,11 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define DBLV_X6 0x10 /* clock x6 */
#define DBLV_X8 0x11 /* clock x8 */
+#define REG_SCALING_XSC 0x70 /* Test pattern and horizontal scale factor */
+#define TEST_PATTTERN_0 0x80
+#define REG_SCALING_YSC 0x71 /* Test pattern and vertical scale factor */
+#define TEST_PATTTERN_1 0x80
+
#define REG_REG76 0x76 /* OV's name */
#define R76_BLKPCOR 0x80 /* Black pixel correction enable */
#define R76_WHTPCOR 0x40 /* White pixel correction enable */
@@ -292,7 +297,8 @@ static struct regval_list ov7670_default_regs[] = {
{ REG_COM3, 0 }, { REG_COM14, 0 },
/* Mystery scaling numbers */
- { 0x70, 0x3a }, { 0x71, 0x35 },
+ { REG_SCALING_XSC, 0x3a },
+ { REG_SCALING_YSC, 0x35 },
{ 0x72, 0x11 }, { 0x73, 0xf0 },
{ 0xa2, 0x02 }, { REG_COM10, 0x0 },
@@ -406,12 +412,12 @@ static struct regval_list ov7670_fmt_yuv422[] = {
{ REG_COM1, 0 }, /* CCIR601 */
{ REG_COM15, COM15_R00FF },
{ REG_COM9, 0x48 }, /* 32x gain ceiling; 0x8 is reserved bit */
- { 0x4f, 0x80 }, /* "matrix coefficient 1" */
- { 0x50, 0x80 }, /* "matrix coefficient 2" */
+ { 0x4f, 0x80 }, /* "matrix coefficient 1" */
+ { 0x50, 0x80 }, /* "matrix coefficient 2" */
{ 0x51, 0 }, /* vb */
- { 0x52, 0x22 }, /* "matrix coefficient 4" */
- { 0x53, 0x5e }, /* "matrix coefficient 5" */
- { 0x54, 0x80 }, /* "matrix coefficient 6" */
+ { 0x52, 0x22 }, /* "matrix coefficient 4" */
+ { 0x53, 0x5e }, /* "matrix coefficient 5" */
+ { 0x54, 0x80 }, /* "matrix coefficient 6" */
{ REG_COM13, COM13_GAMMA|COM13_UVSAT },
{ 0xff, 0xff },
};
@@ -421,13 +427,13 @@ static struct regval_list ov7670_fmt_rgb565[] = {
{ REG_RGB444, 0 }, /* No RGB444 please */
{ REG_COM1, 0x0 }, /* CCIR601 */
{ REG_COM15, COM15_RGB565 },
- { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
- { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
- { 0x50, 0xb3 }, /* "matrix coefficient 2" */
+ { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
+ { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
+ { 0x50, 0xb3 }, /* "matrix coefficient 2" */
{ 0x51, 0 }, /* vb */
- { 0x52, 0x3d }, /* "matrix coefficient 4" */
- { 0x53, 0xa7 }, /* "matrix coefficient 5" */
- { 0x54, 0xe4 }, /* "matrix coefficient 6" */
+ { 0x52, 0x3d }, /* "matrix coefficient 4" */
+ { 0x53, 0xa7 }, /* "matrix coefficient 5" */
+ { 0x54, 0xe4 }, /* "matrix coefficient 6" */
{ REG_COM13, COM13_GAMMA|COM13_UVSAT },
{ 0xff, 0xff },
};
@@ -437,13 +443,13 @@ static struct regval_list ov7670_fmt_rgb444[] = {
{ REG_RGB444, R444_ENABLE }, /* Enable xxxxrrrr ggggbbbb */
{ REG_COM1, 0x0 }, /* CCIR601 */
{ REG_COM15, COM15_R01FE|COM15_RGB565 }, /* Data range needed? */
- { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
- { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
- { 0x50, 0xb3 }, /* "matrix coefficient 2" */
+ { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
+ { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
+ { 0x50, 0xb3 }, /* "matrix coefficient 2" */
{ 0x51, 0 }, /* vb */
- { 0x52, 0x3d }, /* "matrix coefficient 4" */
- { 0x53, 0xa7 }, /* "matrix coefficient 5" */
- { 0x54, 0xe4 }, /* "matrix coefficient 6" */
+ { 0x52, 0x3d }, /* "matrix coefficient 4" */
+ { 0x53, 0xa7 }, /* "matrix coefficient 5" */
+ { 0x54, 0xe4 }, /* "matrix coefficient 6" */
{ REG_COM13, COM13_GAMMA|COM13_UVSAT|0x2 }, /* Magic rsvd bit */
{ 0xff, 0xff },
};
@@ -568,6 +574,19 @@ static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
return ov7670_write_i2c(sd, reg, value);
}
+static int ov7670_update_bits(struct v4l2_subdev *sd, unsigned char reg,
+ unsigned char mask, unsigned char value)
+{
+ unsigned char orig;
+ int ret;
+
+ ret = ov7670_read(sd, reg, &orig);
+ if (ret)
+ return ret;
+
+ return ov7670_write(sd, reg, (orig & ~mask) | (value & mask));
+}
+
/*
* Write a list of register settings; ff/ff stops the process.
*/
@@ -648,7 +667,7 @@ static struct ov7670_format_struct {
{
.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
.colorspace = V4L2_COLORSPACE_SRGB,
- .regs = ov7670_fmt_yuv422,
+ .regs = ov7670_fmt_yuv422,
.cmatrix = { 128, -128, 0, -34, -94, 128 },
},
{
@@ -666,7 +685,7 @@ static struct ov7670_format_struct {
{
.mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
.colorspace = V4L2_COLORSPACE_SRGB,
- .regs = ov7670_fmt_raw,
+ .regs = ov7670_fmt_raw,
.cmatrix = { 0, 0, 0, 0, 0, 0 },
},
};
@@ -1470,6 +1489,25 @@ static int ov7670_s_autoexp(struct v4l2_subdev *sd,
return ret;
}
+static const char * const ov7670_test_pattern_menu[] = {
+ "No test output",
+ "Shifting \"1\"",
+ "8-bar color bar",
+ "Fade to gray color bar",
+};
+
+static int ov7670_s_test_pattern(struct v4l2_subdev *sd, int value)
+{
+ int ret;
+
+ ret = ov7670_update_bits(sd, REG_SCALING_XSC, TEST_PATTTERN_0,
+ value & BIT(0) ? TEST_PATTTERN_0 : 0);
+ if (ret)
+ return ret;
+
+ return ov7670_update_bits(sd, REG_SCALING_YSC, TEST_PATTTERN_1,
+ value & BIT(1) ? TEST_PATTTERN_1 : 0);
+}
static int ov7670_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
{
@@ -1516,6 +1554,8 @@ static int ov7670_s_ctrl(struct v4l2_ctrl *ctrl)
return ov7670_s_exp(sd, info->exposure->val);
}
return ov7670_s_autoexp(sd, ctrl->val);
+ case V4L2_CID_TEST_PATTERN:
+ return ov7670_s_test_pattern(sd, ctrl->val);
}
return -EINVAL;
}
@@ -1770,6 +1810,10 @@ static int ov7670_probe(struct i2c_client *client,
info->auto_exposure = v4l2_ctrl_new_std_menu(&info->hdl, &ov7670_ctrl_ops,
V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0,
V4L2_EXPOSURE_AUTO);
+ v4l2_ctrl_new_std_menu_items(&info->hdl, &ov7670_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(ov7670_test_pattern_menu) - 1, 0, 0,
+ ov7670_test_pattern_menu);
sd->ctrl_handler = &info->hdl;
if (info->hdl.error) {
ret = info->hdl.error;
@@ -1802,9 +1846,7 @@ static int ov7670_probe(struct i2c_client *client,
return 0;
entity_cleanup:
-#if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&info->sd.entity);
-#endif
hdl_free:
v4l2_ctrl_handler_free(&info->hdl);
power_off:
@@ -1820,12 +1862,10 @@ static int ov7670_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct ov7670_info *info = to_state(sd);
- v4l2_device_unregister_subdev(sd);
+ v4l2_async_unregister_subdev(sd);
v4l2_ctrl_handler_free(&info->hdl);
clk_disable_unprepare(info->clk);
-#if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&info->sd.entity);
-#endif
ov7670_s_power(sd, 0);
return 0;
}
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
new file mode 100644
index 000000000000..fc9dbbcae56e
--- /dev/null
+++ b/drivers/media/i2c/ov7740.c
@@ -0,0 +1,1214 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Microchip Corporation.
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-image-sizes.h>
+#include <media/v4l2-subdev.h>
+
+#define REG_OUTSIZE_LSB 0x34
+
+/* OV7740 register tables */
+#define REG_GAIN 0x00 /* Gain lower 8 bits (rest in vref) */
+#define REG_BGAIN 0x01 /* blue gain */
+#define REG_RGAIN 0x02 /* red gain */
+#define REG_GGAIN 0x03 /* green gain */
+#define REG_REG04 0x04 /* analog setting, dont change*/
+#define REG_BAVG 0x05 /* b channel average */
+#define REG_GAVG 0x06 /* g channel average */
+#define REG_RAVG 0x07 /* r channel average */
+
+#define REG_REG0C 0x0C /* filp enable */
+#define REG0C_IMG_FLIP 0x80
+#define REG0C_IMG_MIRROR 0x40
+
+#define REG_REG0E 0x0E /* blc line */
+#define REG_HAEC 0x0F /* auto exposure cntrl */
+#define REG_AEC 0x10 /* auto exposure cntrl */
+
+#define REG_CLK 0x11 /* Clock control */
+#define REG_REG55 0x55 /* Clock PLL DIV/PreDiv */
+
+#define REG_REG12 0x12
+
+#define REG_REG13 0x13 /* auto/manual AGC, AEC, Write Balance*/
+#define REG13_AEC_EN 0x01
+#define REG13_AGC_EN 0x04
+
+#define REG_REG14 0x14
+#define REG_CTRL15 0x15
+#define REG15_GAIN_MSB 0x03
+
+#define REG_REG16 0x16
+
+#define REG_MIDH 0x1C /* manufacture id byte */
+#define REG_MIDL 0x1D /* manufacture id byre */
+#define REG_PIDH 0x0A /* Product ID MSB */
+#define REG_PIDL 0x0B /* Product ID LSB */
+
+#define REG_84 0x84 /* lots of stuff */
+#define REG_REG38 0x38 /* sub-addr */
+
+#define REG_AHSTART 0x17 /* Horiz start high bits */
+#define REG_AHSIZE 0x18
+#define REG_AVSTART 0x19 /* Vert start high bits */
+#define REG_AVSIZE 0x1A
+#define REG_PSHFT 0x1b /* Pixel delay after HREF */
+
+#define REG_HOUTSIZE 0x31
+#define REG_VOUTSIZE 0x32
+#define REG_HVSIZEOFF 0x33
+#define REG_REG34 0x34 /* DSP output size H/V LSB*/
+
+#define REG_ISP_CTRL00 0x80
+#define ISPCTRL00_AWB_EN 0x10
+#define ISPCTRL00_AWB_GAIN_EN 0x04
+
+#define REG_YGAIN 0xE2 /* ygain for contrast control */
+
+#define REG_YBRIGHT 0xE3
+#define REG_SGNSET 0xE4
+#define SGNSET_YBRIGHT_MASK 0x08
+
+#define REG_USAT 0xDD
+#define REG_VSAT 0xDE
+
+
+struct ov7740 {
+ struct v4l2_subdev subdev;
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ struct media_pad pad;
+#endif
+ struct v4l2_mbus_framefmt format;
+ const struct ov7740_pixfmt *fmt; /* Current format */
+ const struct ov7740_framesize *frmsize;
+ struct regmap *regmap;
+ struct clk *xvclk;
+ struct v4l2_ctrl_handler ctrl_handler;
+ struct {
+ /* gain cluster */
+ struct v4l2_ctrl *auto_gain;
+ struct v4l2_ctrl *gain;
+ };
+ struct {
+ struct v4l2_ctrl *auto_wb;
+ struct v4l2_ctrl *blue_balance;
+ struct v4l2_ctrl *red_balance;
+ };
+ struct {
+ struct v4l2_ctrl *hflip;
+ struct v4l2_ctrl *vflip;
+ };
+ struct {
+ /* exposure cluster */
+ struct v4l2_ctrl *auto_exposure;
+ struct v4l2_ctrl *exposure;
+ };
+ struct {
+ /* saturation/hue cluster */
+ struct v4l2_ctrl *saturation;
+ struct v4l2_ctrl *hue;
+ };
+ struct v4l2_ctrl *brightness;
+ struct v4l2_ctrl *contrast;
+
+ struct mutex mutex; /* To serialize asynchronus callbacks */
+ bool streaming; /* Streaming on/off */
+
+ struct gpio_desc *resetb_gpio;
+ struct gpio_desc *pwdn_gpio;
+};
+
+struct ov7740_pixfmt {
+ u32 mbus_code;
+ enum v4l2_colorspace colorspace;
+ const struct reg_sequence *regs;
+ u32 reg_num;
+};
+
+struct ov7740_framesize {
+ u16 width;
+ u16 height;
+ const struct reg_sequence *regs;
+ u32 reg_num;
+};
+
+static const struct reg_sequence ov7740_vga[] = {
+ {0x55, 0x40},
+ {0x11, 0x02},
+
+ {0xd5, 0x10},
+ {0x0c, 0x12},
+ {0x0d, 0x34},
+ {0x17, 0x25},
+ {0x18, 0xa0},
+ {0x19, 0x03},
+ {0x1a, 0xf0},
+ {0x1b, 0x89},
+ {0x22, 0x03},
+ {0x29, 0x18},
+ {0x2b, 0xf8},
+ {0x2c, 0x01},
+ {REG_HOUTSIZE, 0xa0},
+ {REG_VOUTSIZE, 0xf0},
+ {0x33, 0xc4},
+ {REG_OUTSIZE_LSB, 0x0},
+ {0x35, 0x05},
+ {0x04, 0x60},
+ {0x27, 0x80},
+ {0x3d, 0x0f},
+ {0x3e, 0x80},
+ {0x3f, 0x40},
+ {0x40, 0x7f},
+ {0x41, 0x6a},
+ {0x42, 0x29},
+ {0x44, 0x22},
+ {0x45, 0x41},
+ {0x47, 0x02},
+ {0x49, 0x64},
+ {0x4a, 0xa1},
+ {0x4b, 0x40},
+ {0x4c, 0x1a},
+ {0x4d, 0x50},
+ {0x4e, 0x13},
+ {0x64, 0x00},
+ {0x67, 0x88},
+ {0x68, 0x1a},
+
+ {0x14, 0x28},
+ {0x24, 0x3c},
+ {0x25, 0x30},
+ {0x26, 0x72},
+ {0x50, 0x97},
+ {0x51, 0x1f},
+ {0x52, 0x00},
+ {0x53, 0x00},
+ {0x20, 0x00},
+ {0x21, 0xcf},
+ {0x50, 0x4b},
+ {0x38, 0x14},
+ {0xe9, 0x00},
+ {0x56, 0x55},
+ {0x57, 0xff},
+ {0x58, 0xff},
+ {0x59, 0xff},
+ {0x5f, 0x04},
+ {0xec, 0x00},
+ {0x13, 0xff},
+
+ {0x81, 0x3f},
+ {0x82, 0x32},
+ {0x38, 0x11},
+ {0x84, 0x70},
+ {0x85, 0x00},
+ {0x86, 0x03},
+ {0x87, 0x01},
+ {0x88, 0x05},
+ {0x89, 0x30},
+ {0x8d, 0x30},
+ {0x8f, 0x85},
+ {0x93, 0x30},
+ {0x95, 0x85},
+ {0x99, 0x30},
+ {0x9b, 0x85},
+
+ {0x9c, 0x08},
+ {0x9d, 0x12},
+ {0x9e, 0x23},
+ {0x9f, 0x45},
+ {0xa0, 0x55},
+ {0xa1, 0x64},
+ {0xa2, 0x72},
+ {0xa3, 0x7f},
+ {0xa4, 0x8b},
+ {0xa5, 0x95},
+ {0xa6, 0xa7},
+ {0xa7, 0xb5},
+ {0xa8, 0xcb},
+ {0xa9, 0xdd},
+ {0xaa, 0xec},
+ {0xab, 0x1a},
+
+ {0xce, 0x78},
+ {0xcf, 0x6e},
+ {0xd0, 0x0a},
+ {0xd1, 0x0c},
+ {0xd2, 0x84},
+ {0xd3, 0x90},
+ {0xd4, 0x1e},
+
+ {0x5a, 0x24},
+ {0x5b, 0x1f},
+ {0x5c, 0x88},
+ {0x5d, 0x60},
+
+ {0xac, 0x6e},
+ {0xbe, 0xff},
+ {0xbf, 0x00},
+
+ {0x0f, 0x1d},
+ {0x0f, 0x1f},
+};
+
+static const struct ov7740_framesize ov7740_framesizes[] = {
+ {
+ .width = VGA_WIDTH,
+ .height = VGA_HEIGHT,
+ .regs = ov7740_vga,
+ .reg_num = ARRAY_SIZE(ov7740_vga),
+ },
+};
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov7740_get_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+ struct regmap *regmap = ov7740->regmap;
+ unsigned int val = 0;
+ int ret;
+
+ ret = regmap_read(regmap, reg->reg & 0xff, &val);
+ reg->val = val;
+ reg->size = 1;
+
+ return 0;
+}
+
+static int ov7740_set_register(struct v4l2_subdev *sd,
+ const struct v4l2_dbg_register *reg)
+{
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+ struct regmap *regmap = ov7740->regmap;
+
+ regmap_write(regmap, reg->reg & 0xff, reg->val & 0xff);
+
+ return 0;
+}
+#endif
+
+static int ov7740_set_power(struct ov7740 *ov7740, int on)
+{
+ int ret;
+
+ if (on) {
+ ret = clk_prepare_enable(ov7740->xvclk);
+ if (ret)
+ return ret;
+
+ if (ov7740->pwdn_gpio)
+ gpiod_direction_output(ov7740->pwdn_gpio, 0);
+
+ if (ov7740->resetb_gpio) {
+ gpiod_set_value(ov7740->resetb_gpio, 1);
+ usleep_range(500, 1000);
+ gpiod_set_value(ov7740->resetb_gpio, 0);
+ usleep_range(3000, 5000);
+ }
+ } else {
+ clk_disable_unprepare(ov7740->xvclk);
+
+ if (ov7740->pwdn_gpio)
+ gpiod_direction_output(ov7740->pwdn_gpio, 0);
+ }
+
+ return 0;
+}
+
+static struct v4l2_subdev_core_ops ov7740_subdev_core_ops = {
+ .log_status = v4l2_ctrl_subdev_log_status,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ov7740_get_register,
+ .s_register = ov7740_set_register,
+#endif
+ .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static int ov7740_set_white_balance(struct ov7740 *ov7740, int awb)
+{
+ struct regmap *regmap = ov7740->regmap;
+ unsigned int value;
+ int ret;
+
+ ret = regmap_read(regmap, REG_ISP_CTRL00, &value);
+ if (!ret) {
+ if (awb)
+ value |= (ISPCTRL00_AWB_EN | ISPCTRL00_AWB_GAIN_EN);
+ else
+ value &= ~(ISPCTRL00_AWB_EN | ISPCTRL00_AWB_GAIN_EN);
+ ret = regmap_write(regmap, REG_ISP_CTRL00, value);
+ if (ret)
+ return ret;
+ }
+
+ if (!awb) {
+ ret = regmap_write(regmap, REG_BGAIN,
+ ov7740->blue_balance->val);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(regmap, REG_RGAIN, ov7740->red_balance->val);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ov7740_set_saturation(struct regmap *regmap, int value)
+{
+ int ret;
+
+ ret = regmap_write(regmap, REG_USAT, (unsigned char)value);
+ if (ret)
+ return ret;
+
+ return regmap_write(regmap, REG_VSAT, (unsigned char)value);
+}
+
+static int ov7740_set_gain(struct regmap *regmap, int value)
+{
+ int ret;
+
+ ret = regmap_write(regmap, REG_GAIN, value & 0xff);
+ if (ret)
+ return ret;
+
+ ret = regmap_update_bits(regmap, REG_CTRL15,
+ REG15_GAIN_MSB, (value >> 8) & 0x3);
+ if (!ret)
+ ret = regmap_update_bits(regmap, REG_REG13, REG13_AGC_EN, 0);
+
+ return ret;
+}
+
+static int ov7740_set_autogain(struct regmap *regmap, int value)
+{
+ unsigned int reg;
+ int ret;
+
+ ret = regmap_read(regmap, REG_REG13, &reg);
+ if (ret)
+ return ret;
+ if (value)
+ reg |= REG13_AGC_EN;
+ else
+ reg &= ~REG13_AGC_EN;
+ return regmap_write(regmap, REG_REG13, reg);
+}
+
+static int ov7740_set_brightness(struct regmap *regmap, int value)
+{
+ /* Turn off AEC/AGC */
+ regmap_update_bits(regmap, REG_REG13, REG13_AEC_EN, 0);
+ regmap_update_bits(regmap, REG_REG13, REG13_AGC_EN, 0);
+
+ if (value >= 0) {
+ regmap_write(regmap, REG_YBRIGHT, (unsigned char)value);
+ regmap_update_bits(regmap, REG_SGNSET, SGNSET_YBRIGHT_MASK, 0);
+ } else{
+ regmap_write(regmap, REG_YBRIGHT, (unsigned char)(-value));
+ regmap_update_bits(regmap, REG_SGNSET, SGNSET_YBRIGHT_MASK, 1);
+ }
+
+ return 0;
+}
+
+static int ov7740_set_contrast(struct regmap *regmap, int value)
+{
+ return regmap_write(regmap, REG_YGAIN, (unsigned char)value);
+}
+
+static int ov7740_get_gain(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl)
+{
+ struct regmap *regmap = ov7740->regmap;
+ unsigned int value0, value1;
+ int ret;
+
+ if (!ctrl->val)
+ return 0;
+
+ ret = regmap_read(regmap, REG_GAIN, &value0);
+ if (ret)
+ return ret;
+ ret = regmap_read(regmap, REG_CTRL15, &value1);
+ if (ret)
+ return ret;
+
+ ov7740->gain->val = (value1 << 8) | (value0 & 0xff);
+
+ return 0;
+}
+
+static int ov7740_set_exp(struct regmap *regmap, int value)
+{
+ int ret;
+
+ /* Turn off AEC/AGC */
+ ret = regmap_update_bits(regmap, REG_REG13,
+ REG13_AEC_EN | REG13_AGC_EN, 0);
+ if (ret)
+ return ret;
+
+ ret = regmap_write(regmap, REG_AEC, (unsigned char)value);
+ if (ret)
+ return ret;
+
+ return regmap_write(regmap, REG_HAEC, (unsigned char)(value >> 8));
+}
+
+static int ov7740_set_autoexp(struct regmap *regmap,
+ enum v4l2_exposure_auto_type value)
+{
+ unsigned int reg;
+ int ret;
+
+ ret = regmap_read(regmap, REG_REG13, &reg);
+ if (!ret) {
+ if (value == V4L2_EXPOSURE_AUTO)
+ reg |= (REG13_AEC_EN | REG13_AGC_EN);
+ else
+ reg &= ~(REG13_AEC_EN | REG13_AGC_EN);
+ ret = regmap_write(regmap, REG_REG13, reg);
+ }
+
+ return ret;
+}
+
+
+static int ov7740_get_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct ov7740 *ov7740 = container_of(ctrl->handler,
+ struct ov7740, ctrl_handler);
+ int ret;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUTOGAIN:
+ ret = ov7740_get_gain(ov7740, ctrl);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int ov7740_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct ov7740 *ov7740 = container_of(ctrl->handler,
+ struct ov7740, ctrl_handler);
+ struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
+ struct regmap *regmap = ov7740->regmap;
+ int ret;
+ u8 val = 0;
+
+ if (pm_runtime_get_if_in_use(&client->dev) <= 0)
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ ret = ov7740_set_white_balance(ov7740, ctrl->val);
+ break;
+ case V4L2_CID_SATURATION:
+ ret = ov7740_set_saturation(regmap, ctrl->val);
+ break;
+ case V4L2_CID_BRIGHTNESS:
+ ret = ov7740_set_brightness(regmap, ctrl->val);
+ break;
+ case V4L2_CID_CONTRAST:
+ ret = ov7740_set_contrast(regmap, ctrl->val);
+ break;
+ case V4L2_CID_VFLIP:
+ ret = regmap_update_bits(regmap, REG_REG0C,
+ REG0C_IMG_FLIP, val);
+ break;
+ case V4L2_CID_HFLIP:
+ val = ctrl->val ? REG0C_IMG_MIRROR : 0x00;
+ ret = regmap_update_bits(regmap, REG_REG0C,
+ REG0C_IMG_MIRROR, val);
+ break;
+ case V4L2_CID_AUTOGAIN:
+ if (!ctrl->val)
+ return ov7740_set_gain(regmap, ov7740->gain->val);
+
+ ret = ov7740_set_autogain(regmap, ctrl->val);
+ break;
+
+ case V4L2_CID_EXPOSURE_AUTO:
+ if (ctrl->val == V4L2_EXPOSURE_MANUAL)
+ return ov7740_set_exp(regmap, ov7740->exposure->val);
+
+ ret = ov7740_set_autoexp(regmap, ctrl->val);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ pm_runtime_put(&client->dev);
+
+ return ret;
+}
+
+static const struct v4l2_ctrl_ops ov7740_ctrl_ops = {
+ .g_volatile_ctrl = ov7740_get_volatile_ctrl,
+ .s_ctrl = ov7740_set_ctrl,
+};
+
+static int ov7740_start_streaming(struct ov7740 *ov7740)
+{
+ int ret;
+
+ if (ov7740->fmt) {
+ ret = regmap_multi_reg_write(ov7740->regmap,
+ ov7740->fmt->regs,
+ ov7740->fmt->reg_num);
+ if (ret)
+ return ret;
+ }
+
+ if (ov7740->frmsize) {
+ ret = regmap_multi_reg_write(ov7740->regmap,
+ ov7740->frmsize->regs,
+ ov7740->frmsize->reg_num);
+ if (ret)
+ return ret;
+ }
+
+ return __v4l2_ctrl_handler_setup(ov7740->subdev.ctrl_handler);
+}
+
+static int ov7740_set_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret = 0;
+
+ mutex_lock(&ov7740->mutex);
+ if (ov7740->streaming == enable) {
+ mutex_unlock(&ov7740->mutex);
+ return 0;
+ }
+
+ if (enable) {
+ ret = pm_runtime_get_sync(&client->dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(&client->dev);
+ goto err_unlock;
+ }
+
+ ret = ov7740_start_streaming(ov7740);
+ if (ret)
+ goto err_rpm_put;
+ } else {
+ pm_runtime_put(&client->dev);
+ }
+
+ ov7740->streaming = enable;
+
+ mutex_unlock(&ov7740->mutex);
+ return ret;
+
+err_rpm_put:
+ pm_runtime_put(&client->dev);
+err_unlock:
+ mutex_unlock(&ov7740->mutex);
+ return ret;
+}
+
+static int ov7740_get_parm(struct v4l2_subdev *sd,
+ struct v4l2_streamparm *parms)
+{
+ struct v4l2_captureparm *cp = &parms->parm.capture;
+ struct v4l2_fract *tpf = &cp->timeperframe;
+
+ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ memset(cp, 0, sizeof(struct v4l2_captureparm));
+ cp->capability = V4L2_CAP_TIMEPERFRAME;
+
+ tpf->numerator = 1;
+ tpf->denominator = 60;
+
+ return 0;
+}
+
+static int ov7740_set_parm(struct v4l2_subdev *sd,
+ struct v4l2_streamparm *parms)
+{
+ struct v4l2_captureparm *cp = &parms->parm.capture;
+ struct v4l2_fract *tpf = &cp->timeperframe;
+
+ if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (cp->extendedmode != 0)
+ return -EINVAL;
+
+ cp->capability = V4L2_CAP_TIMEPERFRAME;
+
+ tpf->numerator = 1;
+ tpf->denominator = 60;
+
+ return 0;
+}
+
+static struct v4l2_subdev_video_ops ov7740_subdev_video_ops = {
+ .s_stream = ov7740_set_stream,
+ .s_parm = ov7740_set_parm,
+ .g_parm = ov7740_get_parm,
+};
+
+static const struct reg_sequence ov7740_format_yuyv[] = {
+ {0x12, 0x00},
+ {0x36, 0x3f},
+ {0x80, 0x7f},
+ {0x83, 0x01},
+};
+
+static const struct reg_sequence ov7740_format_bggr8[] = {
+ {0x36, 0x2f},
+ {0x80, 0x01},
+ {0x83, 0x04},
+};
+
+static const struct ov7740_pixfmt ov7740_formats[] = {
+ {
+ .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .regs = ov7740_format_yuyv,
+ .reg_num = ARRAY_SIZE(ov7740_format_yuyv),
+ },
+ {
+ .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .regs = ov7740_format_bggr8,
+ .reg_num = ARRAY_SIZE(ov7740_format_bggr8),
+ }
+};
+#define N_OV7740_FMTS ARRAY_SIZE(ov7740_formats)
+
+static int ov7740_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad || code->index >= N_OV7740_FMTS)
+ return -EINVAL;
+
+ code->code = ov7740_formats[code->index].mbus_code;
+
+ return 0;
+}
+
+static int ov7740_enum_frame_interval(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_interval_enum *fie)
+{
+ if (fie->pad)
+ return -EINVAL;
+
+ if (fie->index >= 1)
+ return -EINVAL;
+
+ if ((fie->width != VGA_WIDTH) || (fie->height != VGA_HEIGHT))
+ return -EINVAL;
+
+ fie->interval.numerator = 1;
+ fie->interval.denominator = 60;
+
+ return 0;
+}
+
+static int ov7740_enum_frame_size(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->pad)
+ return -EINVAL;
+
+ if (fse->index > 0)
+ return -EINVAL;
+
+ fse->min_width = fse->max_width = VGA_WIDTH;
+ fse->min_height = fse->max_height = VGA_HEIGHT;
+
+ return 0;
+}
+
+static int ov7740_try_fmt_internal(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *fmt,
+ const struct ov7740_pixfmt **ret_fmt,
+ const struct ov7740_framesize **ret_frmsize)
+{
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+ const struct ov7740_framesize *fsize = &ov7740_framesizes[0];
+ int index, i;
+
+ for (index = 0; index < N_OV7740_FMTS; index++) {
+ if (ov7740_formats[index].mbus_code == fmt->code)
+ break;
+ }
+ if (index >= N_OV7740_FMTS) {
+ /* default to first format */
+ index = 0;
+ fmt->code = ov7740_formats[0].mbus_code;
+ }
+ if (ret_fmt != NULL)
+ *ret_fmt = ov7740_formats + index;
+
+ for (i = 0; i < ARRAY_SIZE(ov7740_framesizes); i++) {
+ if ((fsize->width >= fmt->width) &&
+ (fsize->height >= fmt->height)) {
+ fmt->width = fsize->width;
+ fmt->height = fsize->height;
+ break;
+ }
+
+ fsize++;
+ }
+
+ if (ret_frmsize != NULL)
+ *ret_frmsize = fsize;
+
+ fmt->field = V4L2_FIELD_NONE;
+ fmt->colorspace = ov7740_formats[index].colorspace;
+
+ ov7740->format = *fmt;
+
+ return 0;
+}
+
+static int ov7740_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+ const struct ov7740_pixfmt *ovfmt;
+ const struct ov7740_framesize *fsize;
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ struct v4l2_mbus_framefmt *mbus_fmt;
+#endif
+ int ret;
+
+ mutex_lock(&ov7740->mutex);
+ if (format->pad) {
+ ret = -EINVAL;
+ goto error;
+ }
+
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+ ret = ov7740_try_fmt_internal(sd, &format->format, NULL, NULL);
+ if (ret)
+ goto error;
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, format->pad);
+ *mbus_fmt = format->format;
+
+ mutex_unlock(&ov7740->mutex);
+ return 0;
+#else
+ ret = -ENOTTY;
+ goto error;
+#endif
+ }
+
+ ret = ov7740_try_fmt_internal(sd, &format->format, &ovfmt, &fsize);
+ if (ret)
+ goto error;
+
+ ov7740->fmt = ovfmt;
+ ov7740->frmsize = fsize;
+
+ mutex_unlock(&ov7740->mutex);
+ return 0;
+
+error:
+ mutex_unlock(&ov7740->mutex);
+ return ret;
+}
+
+static int ov7740_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *format)
+{
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ struct v4l2_mbus_framefmt *mbus_fmt;
+#endif
+ int ret = 0;
+
+ mutex_lock(&ov7740->mutex);
+ if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ mbus_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
+ format->format = *mbus_fmt;
+ ret = 0;
+#else
+ ret = -ENOTTY;
+#endif
+ } else {
+ format->format = ov7740->format;
+ }
+ mutex_unlock(&ov7740->mutex);
+
+ return ret;
+}
+
+static const struct v4l2_subdev_pad_ops ov7740_subdev_pad_ops = {
+ .enum_frame_interval = ov7740_enum_frame_interval,
+ .enum_frame_size = ov7740_enum_frame_size,
+ .enum_mbus_code = ov7740_enum_mbus_code,
+ .get_fmt = ov7740_get_fmt,
+ .set_fmt = ov7740_set_fmt,
+};
+
+static const struct v4l2_subdev_ops ov7740_subdev_ops = {
+ .core = &ov7740_subdev_core_ops,
+ .video = &ov7740_subdev_video_ops,
+ .pad = &ov7740_subdev_pad_ops,
+};
+
+static void ov7740_get_default_format(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *format)
+{
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+ format->width = ov7740->frmsize->width;
+ format->height = ov7740->frmsize->height;
+ format->colorspace = ov7740->fmt->colorspace;
+ format->code = ov7740->fmt->mbus_code;
+ format->field = V4L2_FIELD_NONE;
+}
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+static int ov7740_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+ struct v4l2_mbus_framefmt *format =
+ v4l2_subdev_get_try_format(sd, fh->pad, 0);
+
+ mutex_lock(&ov7740->mutex);
+ ov7740_get_default_format(sd, format);
+ mutex_unlock(&ov7740->mutex);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_internal_ops ov7740_subdev_internal_ops = {
+ .open = ov7740_open,
+};
+#endif
+
+static int ov7740_probe_dt(struct i2c_client *client,
+ struct ov7740 *ov7740)
+{
+ ov7740->resetb_gpio = devm_gpiod_get_optional(&client->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(ov7740->resetb_gpio)) {
+ dev_info(&client->dev, "can't get %s GPIO\n", "reset");
+ return PTR_ERR(ov7740->resetb_gpio);
+ }
+
+ ov7740->pwdn_gpio = devm_gpiod_get_optional(&client->dev, "powerdown",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(ov7740->pwdn_gpio)) {
+ dev_info(&client->dev, "can't get %s GPIO\n", "powerdown");
+ return PTR_ERR(ov7740->pwdn_gpio);
+ }
+
+ return 0;
+}
+
+static int ov7740_detect(struct ov7740 *ov7740)
+{
+ struct regmap *regmap = ov7740->regmap;
+ unsigned int midh, midl, pidh, pidl;
+ int ret;
+
+ ret = regmap_read(regmap, REG_MIDH, &midh);
+ if (ret)
+ return ret;
+ if (midh != 0x7f)
+ return -ENODEV;
+
+ ret = regmap_read(regmap, REG_MIDL, &midl);
+ if (ret)
+ return ret;
+ if (midl != 0xa2)
+ return -ENODEV;
+
+ ret = regmap_read(regmap, REG_PIDH, &pidh);
+ if (ret)
+ return ret;
+ if (pidh != 0x77)
+ return -ENODEV;
+
+ ret = regmap_read(regmap, REG_PIDL, &pidl);
+ if (ret)
+ return ret;
+ if ((pidl != 0x40) && (pidl != 0x41) && (pidl != 0x42))
+ return -ENODEV;
+
+ return 0;
+}
+
+static int ov7740_init_controls(struct ov7740 *ov7740)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov7740->subdev);
+ struct v4l2_ctrl_handler *ctrl_hdlr = &ov7740->ctrl_handler;
+ int ret;
+
+ ret = v4l2_ctrl_handler_init(ctrl_hdlr, 2);
+ if (ret < 0)
+ return ret;
+
+ ctrl_hdlr->lock = &ov7740->mutex;
+ ov7740->auto_wb = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_AUTO_WHITE_BALANCE,
+ 0, 1, 1, 1);
+ ov7740->blue_balance = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_BLUE_BALANCE,
+ 0, 0xff, 1, 0x80);
+ ov7740->red_balance = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_RED_BALANCE,
+ 0, 0xff, 1, 0x80);
+
+ ov7740->brightness = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_BRIGHTNESS,
+ -255, 255, 1, 0);
+ ov7740->contrast = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_CONTRAST,
+ 0, 127, 1, 0x20);
+ ov7740->saturation = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_SATURATION, 0, 256, 1, 0x80);
+ ov7740->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 0);
+ ov7740->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+ ov7740->gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_GAIN, 0, 1023, 1, 500);
+ ov7740->auto_gain = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
+ ov7740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
+ V4L2_CID_EXPOSURE, 0, 65535, 1, 500);
+ ov7740->auto_exposure = v4l2_ctrl_new_std_menu(ctrl_hdlr,
+ &ov7740_ctrl_ops,
+ V4L2_CID_EXPOSURE_AUTO,
+ V4L2_EXPOSURE_MANUAL, 0,
+ V4L2_EXPOSURE_AUTO);
+
+ ov7740->gain->flags |= V4L2_CTRL_FLAG_VOLATILE;
+ ov7740->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+ v4l2_ctrl_auto_cluster(3, &ov7740->auto_wb, 0, false);
+ v4l2_ctrl_auto_cluster(2, &ov7740->auto_gain, 0, true);
+ v4l2_ctrl_auto_cluster(2, &ov7740->auto_exposure,
+ V4L2_EXPOSURE_MANUAL, false);
+ v4l2_ctrl_cluster(2, &ov7740->hflip);
+
+ ret = v4l2_ctrl_handler_setup(ctrl_hdlr);
+ if (ret) {
+ dev_err(&client->dev, "%s control init failed (%d)\n",
+ __func__, ret);
+ goto error;
+ }
+
+ ov7740->subdev.ctrl_handler = ctrl_hdlr;
+ return 0;
+
+error:
+ v4l2_ctrl_handler_free(ctrl_hdlr);
+ mutex_destroy(&ov7740->mutex);
+ return ret;
+}
+
+static void ov7740_free_controls(struct ov7740 *ov7740)
+{
+ v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
+ mutex_destroy(&ov7740->mutex);
+}
+
+#define OV7740_MAX_REGISTER 0xff
+static const struct regmap_config ov7740_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = OV7740_MAX_REGISTER,
+};
+
+static int ov7740_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ov7740 *ov7740;
+ struct v4l2_subdev *sd;
+ int ret;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA)) {
+ dev_err(&client->dev,
+ "OV7740: I2C-Adapter doesn't support SMBUS\n");
+ return -EIO;
+ }
+
+ ov7740 = devm_kzalloc(&client->dev, sizeof(*ov7740), GFP_KERNEL);
+ if (!ov7740)
+ return -ENOMEM;
+
+ ov7740->xvclk = devm_clk_get(&client->dev, "xvclk");
+ if (IS_ERR(ov7740->xvclk)) {
+ ret = PTR_ERR(ov7740->xvclk);
+ dev_err(&client->dev,
+ "OV7740: fail to get xvclk: %d\n", ret);
+ return ret;
+ }
+
+ ret = ov7740_probe_dt(client, ov7740);
+ if (ret)
+ return ret;
+
+ ov7740->regmap = devm_regmap_init_i2c(client, &ov7740_regmap_config);
+ if (IS_ERR(ov7740->regmap)) {
+ ret = PTR_ERR(ov7740->regmap);
+ dev_err(&client->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ sd = &ov7740->subdev;
+ client->flags |= I2C_CLIENT_SCCB;
+ v4l2_i2c_subdev_init(sd, client, &ov7740_subdev_ops);
+
+#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
+ sd->internal_ops = &ov7740_subdev_internal_ops;
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+#endif
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ ov7740->pad.flags = MEDIA_PAD_FL_SOURCE;
+ sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ ret = media_entity_pads_init(&sd->entity, 1, &ov7740->pad);
+ if (ret)
+ return ret;
+#endif
+
+ ret = ov7740_set_power(ov7740, 1);
+ if (ret)
+ return ret;
+
+ ret = ov7740_detect(ov7740);
+ if (ret)
+ goto error_detect;
+
+ mutex_init(&ov7740->mutex);
+
+ ret = ov7740_init_controls(ov7740);
+ if (ret)
+ goto error_init_controls;
+
+ v4l_info(client, "chip found @ 0x%02x (%s)\n",
+ client->addr << 1, client->adapter->name);
+
+ ov7740->fmt = &ov7740_formats[0];
+ ov7740->frmsize = &ov7740_framesizes[0];
+
+ ov7740_get_default_format(sd, &ov7740->format);
+
+ ret = v4l2_async_register_subdev(sd);
+ if (ret)
+ goto error_async_register;
+
+ pm_runtime_set_active(&client->dev);
+ pm_runtime_enable(&client->dev);
+ pm_runtime_idle(&client->dev);
+
+ return 0;
+
+error_async_register:
+ v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
+error_init_controls:
+ ov7740_free_controls(ov7740);
+error_detect:
+ ov7740_set_power(ov7740, 0);
+ media_entity_cleanup(&ov7740->subdev.entity);
+
+ return ret;
+}
+
+static int ov7740_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+ mutex_destroy(&ov7740->mutex);
+ v4l2_ctrl_handler_free(ov7740->subdev.ctrl_handler);
+ media_entity_cleanup(&ov7740->subdev.entity);
+ v4l2_async_unregister_subdev(sd);
+ ov7740_free_controls(ov7740);
+
+ pm_runtime_get_sync(&client->dev);
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
+
+ ov7740_set_power(ov7740, 0);
+ return 0;
+}
+
+static int __maybe_unused ov7740_runtime_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+ ov7740_set_power(ov7740, 0);
+
+ return 0;
+}
+
+static int __maybe_unused ov7740_runtime_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov7740 *ov7740 = container_of(sd, struct ov7740, subdev);
+
+ return ov7740_set_power(ov7740, 1);
+}
+
+static const struct i2c_device_id ov7740_id[] = {
+ { "ov7740", 0 },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, ov7740_id);
+
+static const struct dev_pm_ops ov7740_pm_ops = {
+ SET_RUNTIME_PM_OPS(ov7740_runtime_suspend, ov7740_runtime_resume, NULL)
+};
+
+static const struct of_device_id ov7740_of_match[] = {
+ {.compatible = "ovti,ov7740", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ov7740_of_match);
+
+static struct i2c_driver ov7740_i2c_driver = {
+ .driver = {
+ .name = "ov7740",
+ .pm = &ov7740_pm_ops,
+ .of_match_table = of_match_ptr(ov7740_of_match),
+ },
+ .probe = ov7740_probe,
+ .remove = ov7740_remove,
+ .id_table = ov7740_id,
+};
+module_i2c_driver(ov7740_i2c_driver);
+
+MODULE_DESCRIPTION("The V4L2 driver for Omnivision 7740 sensor");
+MODULE_AUTHOR("Songjun Wu <songjun.wu@atmel.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/i2c/ov9650.c b/drivers/media/i2c/ov9650.c
index 69433e1e2533..e519f278d5f9 100644
--- a/drivers/media/i2c/ov9650.c
+++ b/drivers/media/i2c/ov9650.c
@@ -886,10 +886,12 @@ static int __g_volatile_ctrl(struct ov965x *ov965x, struct v4l2_ctrl *ctrl)
if (ctrl->val == V4L2_EXPOSURE_MANUAL)
return 0;
ret = ov965x_read(client, REG_COM1, &reg0);
- if (!ret)
- ret = ov965x_read(client, REG_AECH, &reg1);
- if (!ret)
- ret = ov965x_read(client, REG_AECHM, &reg2);
+ if (ret < 0)
+ return ret;
+ ret = ov965x_read(client, REG_AECH, &reg1);
+ if (ret < 0)
+ return ret;
+ ret = ov965x_read(client, REG_AECHM, &reg2);
if (ret < 0)
return ret;
exposure = ((reg2 & 0x3f) << 10) | (reg1 << 2) |
diff --git a/drivers/media/i2c/saa6752hs.c b/drivers/media/i2c/saa6752hs.c
index 7202d3a3219a..170cc65c4f23 100644
--- a/drivers/media/i2c/saa6752hs.c
+++ b/drivers/media/i2c/saa6752hs.c
@@ -72,8 +72,8 @@ struct saa6752hs_mpeg_params {
/* video */
enum v4l2_mpeg_video_aspect vi_aspect;
enum v4l2_mpeg_video_bitrate_mode vi_bitrate_mode;
- __u32 vi_bitrate;
- __u32 vi_bitrate_peak;
+ __u32 vi_bitrate;
+ __u32 vi_bitrate_peak;
};
static const struct v4l2_format v4l2_format_table[] =
@@ -98,8 +98,8 @@ struct saa6752hs_state {
struct v4l2_ctrl *video_bitrate;
struct v4l2_ctrl *video_bitrate_peak;
};
- u32 revision;
- int has_ac3;
+ u32 revision;
+ int has_ac3;
struct saa6752hs_mpeg_params params;
enum saa6752hs_videoformat video_format;
v4l2_std_id standard;
diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
index d863b04aa2a8..e216cd768409 100644
--- a/drivers/media/i2c/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -1,37 +1,27 @@
-/* saa711x - Philips SAA711x video decoder driver
- * This driver can work with saa7111, saa7111a, saa7113, saa7114,
- * saa7115 and saa7118.
- *
- * Based on saa7114 driver by Maxim Yevtyushkin, which is based on
- * the saa7111 driver by Dave Perks.
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr <scherr@net4you.net>
- *
- * Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
- * by Ronald Bultje <rbultje@ronald.bitfreak.net>
- *
- * Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
- * (2/17/2003)
- *
- * VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
- *
- * Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- * SAA7111, SAA7113 and SAA7118 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// saa711x - Philips SAA711x video decoder driver
+// This driver can work with saa7111, saa7111a, saa7113, saa7114,
+// saa7115 and saa7118.
+//
+// Based on saa7114 driver by Maxim Yevtyushkin, which is based on
+// the saa7111 driver by Dave Perks.
+//
+// Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+// Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
+//
+// Slight changes for video timing and attachment output by
+// Wolfgang Scherr <scherr@net4you.net>
+//
+// Moved over to the linux >= 2.4.x i2c protocol (1/1/2003)
+// by Ronald Bultje <rbultje@ronald.bitfreak.net>
+//
+// Added saa7115 support by Kevin Thayer <nufan_wfk at yahoo.com>
+// (2/17/2003)
+//
+// VBI support (2004) and cleanups (2005) by Hans Verkuil <hverkuil@xs4all.nl>
+//
+// Copyright (c) 2005-2006 Mauro Carvalho Chehab <mchehab@infradead.org>
+// SAA7111, SAA7113 and SAA7118 support
#include "saa711x_regs.h"
@@ -758,7 +748,7 @@ static int saa711x_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
u32 acni;
u32 hz;
u64 f;
- u8 acc = 0; /* reg 0x3a, audio clock control */
+ u8 acc = 0; /* reg 0x3a, audio clock control */
/* Checks for chips that don't have audio clock (saa7111, saa7113) */
if (!saa711x_has_reg(state->ident, R_30_AUD_MAST_CLK_CYCLES_PER_FIELD))
diff --git a/drivers/media/i2c/saa711x_regs.h b/drivers/media/i2c/saa711x_regs.h
index 730ca90b30ac..a50d480e101a 100644
--- a/drivers/media/i2c/saa711x_regs.h
+++ b/drivers/media/i2c/saa711x_regs.h
@@ -1,16 +1,8 @@
-/* saa711x - Philips SAA711x video decoder register specifications
+/*
+ * SPDX-License-Identifier: GPL-2.0+
+ * saa711x - Philips SAA711x video decoder register specifications
*
* Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.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.
*/
#define R_00_CHIP_VERSION 0x00
diff --git a/drivers/media/i2c/saa7127.c b/drivers/media/i2c/saa7127.c
index 01784d441ae6..e58a150cec5c 100644
--- a/drivers/media/i2c/saa7127.c
+++ b/drivers/media/i2c/saa7127.c
@@ -132,109 +132,109 @@ struct i2c_reg_value {
};
static const struct i2c_reg_value saa7129_init_config_extra[] = {
- { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 },
- { SAA7127_REG_VTRIG, 0xfa },
+ { SAA7127_REG_OUTPUT_PORT_CONTROL, 0x38 },
+ { SAA7127_REG_VTRIG, 0xfa },
{ 0, 0 }
};
static const struct i2c_reg_value saa7127_init_config_common[] = {
- { SAA7127_REG_WIDESCREEN_CONFIG, 0x0d },
- { SAA7127_REG_WIDESCREEN_ENABLE, 0x00 },
- { SAA7127_REG_COPYGEN_0, 0x77 },
- { SAA7127_REG_COPYGEN_1, 0x41 },
- { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */
- { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf },
- { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 },
- { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 },
- { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */
- { SAA7127_REG_LINE_21_ODD_0, 0x77 },
- { SAA7127_REG_LINE_21_ODD_1, 0x41 },
- { SAA7127_REG_LINE_21_EVEN_0, 0x88 },
- { SAA7127_REG_LINE_21_EVEN_1, 0x41 },
- { SAA7127_REG_RCV_PORT_CONTROL, 0x12 },
- { SAA7127_REG_VTRIG, 0xf9 },
- { SAA7127_REG_HTRIG_HI, 0x00 },
- { SAA7127_REG_RCV2_OUTPUT_START, 0x41 },
- { SAA7127_REG_RCV2_OUTPUT_END, 0xc3 },
- { SAA7127_REG_RCV2_OUTPUT_MSBS, 0x00 },
- { SAA7127_REG_TTX_REQUEST_H_START, 0x3e },
- { SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH, 0xb8 },
- { SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT, 0x03 },
- { SAA7127_REG_TTX_ODD_REQ_VERT_START, 0x15 },
- { SAA7127_REG_TTX_ODD_REQ_VERT_END, 0x16 },
- { SAA7127_REG_TTX_EVEN_REQ_VERT_START, 0x15 },
- { SAA7127_REG_TTX_EVEN_REQ_VERT_END, 0x16 },
- { SAA7127_REG_FIRST_ACTIVE, 0x1a },
- { SAA7127_REG_LAST_ACTIVE, 0x01 },
- { SAA7127_REG_MSB_VERTICAL, 0xc0 },
- { SAA7127_REG_DISABLE_TTX_LINE_LO_0, 0x00 },
- { SAA7127_REG_DISABLE_TTX_LINE_LO_1, 0x00 },
+ { SAA7127_REG_WIDESCREEN_CONFIG, 0x0d },
+ { SAA7127_REG_WIDESCREEN_ENABLE, 0x00 },
+ { SAA7127_REG_COPYGEN_0, 0x77 },
+ { SAA7127_REG_COPYGEN_1, 0x41 },
+ { SAA7127_REG_COPYGEN_2, 0x00 }, /* Macrovision enable/disable */
+ { SAA7127_REG_OUTPUT_PORT_CONTROL, 0xbf },
+ { SAA7127_REG_GAIN_LUMINANCE_RGB, 0x00 },
+ { SAA7127_REG_GAIN_COLORDIFF_RGB, 0x00 },
+ { SAA7127_REG_INPUT_PORT_CONTROL_1, 0x80 }, /* for color bars */
+ { SAA7127_REG_LINE_21_ODD_0, 0x77 },
+ { SAA7127_REG_LINE_21_ODD_1, 0x41 },
+ { SAA7127_REG_LINE_21_EVEN_0, 0x88 },
+ { SAA7127_REG_LINE_21_EVEN_1, 0x41 },
+ { SAA7127_REG_RCV_PORT_CONTROL, 0x12 },
+ { SAA7127_REG_VTRIG, 0xf9 },
+ { SAA7127_REG_HTRIG_HI, 0x00 },
+ { SAA7127_REG_RCV2_OUTPUT_START, 0x41 },
+ { SAA7127_REG_RCV2_OUTPUT_END, 0xc3 },
+ { SAA7127_REG_RCV2_OUTPUT_MSBS, 0x00 },
+ { SAA7127_REG_TTX_REQUEST_H_START, 0x3e },
+ { SAA7127_REG_TTX_REQUEST_H_DELAY_LENGTH, 0xb8 },
+ { SAA7127_REG_CSYNC_ADVANCE_VSYNC_SHIFT, 0x03 },
+ { SAA7127_REG_TTX_ODD_REQ_VERT_START, 0x15 },
+ { SAA7127_REG_TTX_ODD_REQ_VERT_END, 0x16 },
+ { SAA7127_REG_TTX_EVEN_REQ_VERT_START, 0x15 },
+ { SAA7127_REG_TTX_EVEN_REQ_VERT_END, 0x16 },
+ { SAA7127_REG_FIRST_ACTIVE, 0x1a },
+ { SAA7127_REG_LAST_ACTIVE, 0x01 },
+ { SAA7127_REG_MSB_VERTICAL, 0xc0 },
+ { SAA7127_REG_DISABLE_TTX_LINE_LO_0, 0x00 },
+ { SAA7127_REG_DISABLE_TTX_LINE_LO_1, 0x00 },
{ 0, 0 }
};
#define SAA7127_60HZ_DAC_CONTROL 0x15
static const struct i2c_reg_value saa7127_init_config_60hz[] = {
- { SAA7127_REG_BURST_START, 0x19 },
+ { SAA7127_REG_BURST_START, 0x19 },
/* BURST_END is also used as a chip ID in saa7127_probe */
- { SAA7127_REG_BURST_END, 0x1d },
- { SAA7127_REG_CHROMA_PHASE, 0xa3 },
- { SAA7127_REG_GAINU, 0x98 },
- { SAA7127_REG_GAINV, 0xd3 },
- { SAA7127_REG_BLACK_LEVEL, 0x39 },
- { SAA7127_REG_BLANKING_LEVEL, 0x2e },
- { SAA7127_REG_VBI_BLANKING, 0x2e },
- { SAA7127_REG_DAC_CONTROL, 0x15 },
- { SAA7127_REG_BURST_AMP, 0x4d },
- { SAA7127_REG_SUBC3, 0x1f },
- { SAA7127_REG_SUBC2, 0x7c },
- { SAA7127_REG_SUBC1, 0xf0 },
- { SAA7127_REG_SUBC0, 0x21 },
- { SAA7127_REG_MULTI, 0x90 },
- { SAA7127_REG_CLOSED_CAPTION, 0x11 },
+ { SAA7127_REG_BURST_END, 0x1d },
+ { SAA7127_REG_CHROMA_PHASE, 0xa3 },
+ { SAA7127_REG_GAINU, 0x98 },
+ { SAA7127_REG_GAINV, 0xd3 },
+ { SAA7127_REG_BLACK_LEVEL, 0x39 },
+ { SAA7127_REG_BLANKING_LEVEL, 0x2e },
+ { SAA7127_REG_VBI_BLANKING, 0x2e },
+ { SAA7127_REG_DAC_CONTROL, 0x15 },
+ { SAA7127_REG_BURST_AMP, 0x4d },
+ { SAA7127_REG_SUBC3, 0x1f },
+ { SAA7127_REG_SUBC2, 0x7c },
+ { SAA7127_REG_SUBC1, 0xf0 },
+ { SAA7127_REG_SUBC0, 0x21 },
+ { SAA7127_REG_MULTI, 0x90 },
+ { SAA7127_REG_CLOSED_CAPTION, 0x11 },
{ 0, 0 }
};
#define SAA7127_50HZ_PAL_DAC_CONTROL 0x02
static struct i2c_reg_value saa7127_init_config_50hz_pal[] = {
- { SAA7127_REG_BURST_START, 0x21 },
+ { SAA7127_REG_BURST_START, 0x21 },
/* BURST_END is also used as a chip ID in saa7127_probe */
- { SAA7127_REG_BURST_END, 0x1d },
- { SAA7127_REG_CHROMA_PHASE, 0x3f },
- { SAA7127_REG_GAINU, 0x7d },
- { SAA7127_REG_GAINV, 0xaf },
- { SAA7127_REG_BLACK_LEVEL, 0x33 },
- { SAA7127_REG_BLANKING_LEVEL, 0x35 },
- { SAA7127_REG_VBI_BLANKING, 0x35 },
- { SAA7127_REG_DAC_CONTROL, 0x02 },
- { SAA7127_REG_BURST_AMP, 0x2f },
- { SAA7127_REG_SUBC3, 0xcb },
- { SAA7127_REG_SUBC2, 0x8a },
- { SAA7127_REG_SUBC1, 0x09 },
- { SAA7127_REG_SUBC0, 0x2a },
- { SAA7127_REG_MULTI, 0xa0 },
- { SAA7127_REG_CLOSED_CAPTION, 0x00 },
+ { SAA7127_REG_BURST_END, 0x1d },
+ { SAA7127_REG_CHROMA_PHASE, 0x3f },
+ { SAA7127_REG_GAINU, 0x7d },
+ { SAA7127_REG_GAINV, 0xaf },
+ { SAA7127_REG_BLACK_LEVEL, 0x33 },
+ { SAA7127_REG_BLANKING_LEVEL, 0x35 },
+ { SAA7127_REG_VBI_BLANKING, 0x35 },
+ { SAA7127_REG_DAC_CONTROL, 0x02 },
+ { SAA7127_REG_BURST_AMP, 0x2f },
+ { SAA7127_REG_SUBC3, 0xcb },
+ { SAA7127_REG_SUBC2, 0x8a },
+ { SAA7127_REG_SUBC1, 0x09 },
+ { SAA7127_REG_SUBC0, 0x2a },
+ { SAA7127_REG_MULTI, 0xa0 },
+ { SAA7127_REG_CLOSED_CAPTION, 0x00 },
{ 0, 0 }
};
#define SAA7127_50HZ_SECAM_DAC_CONTROL 0x08
static struct i2c_reg_value saa7127_init_config_50hz_secam[] = {
- { SAA7127_REG_BURST_START, 0x21 },
+ { SAA7127_REG_BURST_START, 0x21 },
/* BURST_END is also used as a chip ID in saa7127_probe */
- { SAA7127_REG_BURST_END, 0x1d },
- { SAA7127_REG_CHROMA_PHASE, 0x3f },
- { SAA7127_REG_GAINU, 0x6a },
- { SAA7127_REG_GAINV, 0x81 },
- { SAA7127_REG_BLACK_LEVEL, 0x33 },
- { SAA7127_REG_BLANKING_LEVEL, 0x35 },
- { SAA7127_REG_VBI_BLANKING, 0x35 },
- { SAA7127_REG_DAC_CONTROL, 0x08 },
- { SAA7127_REG_BURST_AMP, 0x2f },
- { SAA7127_REG_SUBC3, 0xb2 },
- { SAA7127_REG_SUBC2, 0x3b },
- { SAA7127_REG_SUBC1, 0xa3 },
- { SAA7127_REG_SUBC0, 0x28 },
- { SAA7127_REG_MULTI, 0x90 },
- { SAA7127_REG_CLOSED_CAPTION, 0x00 },
+ { SAA7127_REG_BURST_END, 0x1d },
+ { SAA7127_REG_CHROMA_PHASE, 0x3f },
+ { SAA7127_REG_GAINU, 0x6a },
+ { SAA7127_REG_GAINV, 0x81 },
+ { SAA7127_REG_BLACK_LEVEL, 0x33 },
+ { SAA7127_REG_BLANKING_LEVEL, 0x35 },
+ { SAA7127_REG_VBI_BLANKING, 0x35 },
+ { SAA7127_REG_DAC_CONTROL, 0x08 },
+ { SAA7127_REG_BURST_AMP, 0x2f },
+ { SAA7127_REG_SUBC3, 0xb2 },
+ { SAA7127_REG_SUBC2, 0x3b },
+ { SAA7127_REG_SUBC1, 0xa3 },
+ { SAA7127_REG_SUBC0, 0x28 },
+ { SAA7127_REG_MULTI, 0x90 },
+ { SAA7127_REG_CLOSED_CAPTION, 0x00 },
{ 0, 0 }
};
diff --git a/drivers/media/i2c/saa717x.c b/drivers/media/i2c/saa717x.c
index 102467e00fb3..668c39cc29e8 100644
--- a/drivers/media/i2c/saa717x.c
+++ b/drivers/media/i2c/saa717x.c
@@ -82,13 +82,13 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
/* ----------------------------------------------------------------------- */
/* for audio mode */
-#define TUNER_AUDIO_MONO 0 /* LL */
-#define TUNER_AUDIO_STEREO 1 /* LR */
-#define TUNER_AUDIO_LANG1 2 /* LL */
-#define TUNER_AUDIO_LANG2 3 /* RR */
+#define TUNER_AUDIO_MONO 0 /* LL */
+#define TUNER_AUDIO_STEREO 1 /* LR */
+#define TUNER_AUDIO_LANG1 2 /* LL */
+#define TUNER_AUDIO_LANG2 3 /* RR */
-#define SAA717X_NTSC_WIDTH (704)
-#define SAA717X_NTSC_HEIGHT (480)
+#define SAA717X_NTSC_WIDTH (704)
+#define SAA717X_NTSC_HEIGHT (480)
/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index e6b717b83b18..3b7ace395ee6 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -1791,7 +1791,7 @@ static int smiapp_set_format_source(struct v4l2_subdev *subdev,
if (csi_format->compressed == old_csi_format->compressed)
return 0;
- valid_link_freqs =
+ valid_link_freqs =
&sensor->valid_link_freqs[sensor->csi_format->compressed
- sensor->compressed_min_bpp];
diff --git a/drivers/media/i2c/tda7432.c b/drivers/media/i2c/tda7432.c
index d87168adee45..1c5c61d829d6 100644
--- a/drivers/media/i2c/tda7432.c
+++ b/drivers/media/i2c/tda7432.c
@@ -36,7 +36,6 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
-#include <media/i2c-addr.h>
#ifndef VIDEO_AUDIO_BALANCE
# define VIDEO_AUDIO_BALANCE 32
diff --git a/drivers/media/i2c/ths7303.c b/drivers/media/i2c/ths7303.c
index 71a31352135c..8206bf7a5a8f 100644
--- a/drivers/media/i2c/ths7303.c
+++ b/drivers/media/i2c/ths7303.c
@@ -319,7 +319,7 @@ static const struct v4l2_subdev_core_ops ths7303_core_ops = {
static const struct v4l2_subdev_ops ths7303_ops = {
.core = &ths7303_core_ops,
- .video = &ths7303_video_ops,
+ .video = &ths7303_video_ops,
};
static int ths7303_probe(struct i2c_client *client,
diff --git a/drivers/media/i2c/tvaudio.c b/drivers/media/i2c/tvaudio.c
index 16a1e08ce06c..772164b848ef 100644
--- a/drivers/media/i2c/tvaudio.c
+++ b/drivers/media/i2c/tvaudio.c
@@ -40,8 +40,6 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ctrls.h>
-#include <media/i2c-addr.h>
-
/* ---------------------------------------------------------------------- */
/* insmod args */
@@ -136,7 +134,7 @@ struct CHIPSTATE {
/* thread */
struct task_struct *thread;
struct timer_list wt;
- int audmode;
+ int audmode;
};
static inline struct CHIPSTATE *to_state(struct v4l2_subdev *sd)
diff --git a/drivers/media/i2c/tvp514x.c b/drivers/media/i2c/tvp514x.c
index d575b3e7e835..8b0aa9297bde 100644
--- a/drivers/media/i2c/tvp514x.c
+++ b/drivers/media/i2c/tvp514x.c
@@ -1131,9 +1131,7 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
done:
if (ret < 0) {
v4l2_ctrl_handler_free(&decoder->hdl);
-#if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&decoder->sd.entity);
-#endif
}
return ret;
}
@@ -1151,9 +1149,7 @@ static int tvp514x_remove(struct i2c_client *client)
struct tvp514x_decoder *decoder = to_decoder(sd);
v4l2_async_unregister_subdev(&decoder->sd);
-#if defined(CONFIG_MEDIA_CONTROLLER)
media_entity_cleanup(&decoder->sd.entity);
-#endif
v4l2_ctrl_handler_free(&decoder->hdl);
return 0;
}
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index 7b79a7498751..3c1851984b90 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -1,9 +1,8 @@
-/*
- * tvp5150 - Texas Instruments TVP5150A/AM1 and TVP5151 video decoder driver
- *
- * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
- */
+// SPDX-License-Identifier: GPL-2.0
+//
+// tvp5150 - Texas Instruments TVP5150A/AM1 and TVP5151 video decoder driver
+//
+// Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@infradead.org>
#include <dt-bindings/media/tvp5150.h>
#include <linux/i2c.h>
@@ -30,7 +29,7 @@
MODULE_DESCRIPTION("Texas Instruments TVP5150A/TVP5150AM1/TVP5151 video decoder driver");
MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
static int debug;
diff --git a/drivers/media/i2c/tvp5150_reg.h b/drivers/media/i2c/tvp5150_reg.h
index 30a48c28d05a..c43b7b844021 100644
--- a/drivers/media/i2c/tvp5150_reg.h
+++ b/drivers/media/i2c/tvp5150_reg.h
@@ -1,8 +1,9 @@
/*
+ * SPDX-License-Identifier: GPL-2.0
+ *
* tvp5150 - Texas Instruments TVP5150A/AM1 video decoder registers
*
- * Copyright (c) 2005,2006 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
+ * Copyright (c) 2005,2006 Mauro Carvalho Chehab <mchehab@infradead.org>
*/
#define TVP5150_VD_IN_SRC_SEL_1 0x00 /* Video input source selection #1 */
@@ -66,10 +67,10 @@
#define VIDEO_STD_NTSC_MJ_BIT_AS 0x01
#define VIDEO_STD_PAL_BDGHIN_BIT_AS 0x03
-#define VIDEO_STD_PAL_M_BIT_AS 0x05
+#define VIDEO_STD_PAL_M_BIT_AS 0x05
#define VIDEO_STD_PAL_COMBINATION_N_BIT_AS 0x07
#define VIDEO_STD_NTSC_4_43_BIT_AS 0x09
-#define VIDEO_STD_SECAM_BIT_AS 0x0b
+#define VIDEO_STD_SECAM_BIT_AS 0x0b
/* Reserved 29h-2bh */
diff --git a/drivers/media/i2c/tvp7002_reg.h b/drivers/media/i2c/tvp7002_reg.h
index 933673561fa2..3c8c8b0a6a4c 100644
--- a/drivers/media/i2c/tvp7002_reg.h
+++ b/drivers/media/i2c/tvp7002_reg.h
@@ -109,15 +109,15 @@
#define TVP7002_L_FRAME_STAT_LSBS 0x37
#define TVP7002_L_FRAME_STAT_MSBS 0x38
#define TVP7002_CLK_L_STAT_LSBS 0x39
-#define TVP7002_CLK_L_STAT_MSBS 0x3a
+#define TVP7002_CLK_L_STAT_MSBS 0x3a
#define TVP7002_HSYNC_W 0x3b
#define TVP7002_VSYNC_W 0x3c
-#define TVP7002_L_LENGTH_TOL 0x3d
+#define TVP7002_L_LENGTH_TOL 0x3d
/* Reserved 0x3e */
#define TVP7002_VIDEO_BWTH_CTL 0x3f
#define TVP7002_AVID_START_PIXEL_LSBS 0x40
#define TVP7002_AVID_START_PIXEL_MSBS 0x41
-#define TVP7002_AVID_STOP_PIXEL_LSBS 0x42
+#define TVP7002_AVID_STOP_PIXEL_LSBS 0x42
#define TVP7002_AVID_STOP_PIXEL_MSBS 0x43
#define TVP7002_VBLK_F_0_START_L_OFF 0x44
#define TVP7002_VBLK_F_1_START_L_OFF 0x45
diff --git a/drivers/media/i2c/vpx3220.c b/drivers/media/i2c/vpx3220.c
index 67de79b2d550..c3549fa55b62 100644
--- a/drivers/media/i2c/vpx3220.c
+++ b/drivers/media/i2c/vpx3220.c
@@ -201,7 +201,7 @@ static const unsigned short init_pal[] = {
* skipped by the VFE) */
0x8b, 16, /* Horizontal begin */
0x8c, 768, /* Horizontal length */
- 0x8d, 784, /* Number of pixels
+ 0x8d, 784, /* Number of pixels
* Must be >= Horizontal begin + Horizontal length */
0x8f, 0xc00, /* Disable window 2 */
0xf0, 0x77, /* 13.5 MHz transport, Forced
diff --git a/drivers/media/mmc/siano/Makefile b/drivers/media/mmc/siano/Makefile
index 0e01f973db6b..5fc345645a80 100644
--- a/drivers/media/mmc/siano/Makefile
+++ b/drivers/media/mmc/siano/Makefile
@@ -1,6 +1,4 @@
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/pci/Kconfig b/drivers/media/pci/Kconfig
index da28e68c87d8..5932e225f9c0 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -54,5 +54,7 @@ source "drivers/media/pci/smipcie/Kconfig"
source "drivers/media/pci/netup_unidvb/Kconfig"
endif
+source "drivers/media/pci/intel/ipu3/Kconfig"
+
endif #MEDIA_PCI_SUPPORT
endif #PCI
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index 1ab759e9b1bb..1c5ab07a8cff 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -14,7 +14,8 @@ obj-y += ttpci/ \
ddbridge/ \
saa7146/ \
smipcie/ \
- netup_unidvb/
+ netup_unidvb/ \
+ intel/
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
obj-$(CONFIG_VIDEO_ZORAN) += zoran/
diff --git a/drivers/media/pci/b2c2/Makefile b/drivers/media/pci/b2c2/Makefile
index 35d6835ae43e..b43b9167db5a 100644
--- a/drivers/media/pci/b2c2/Makefile
+++ b/drivers/media/pci/b2c2/Makefile
@@ -6,5 +6,4 @@ 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/pci/bt8xx/Makefile b/drivers/media/pci/bt8xx/Makefile
index 009f1dc1521f..7f1c3beb1bbc 100644
--- a/drivers/media/pci/bt8xx/Makefile
+++ b/drivers/media/pci/bt8xx/Makefile
@@ -6,8 +6,6 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.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/common
ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/bt8xx/bt878.c b/drivers/media/pci/bt8xx/bt878.c
index a5f52137d306..f5f87e03f94b 100644
--- a/drivers/media/pci/bt8xx/bt878.c
+++ b/drivers/media/pci/bt8xx/bt878.c
@@ -40,8 +40,8 @@
#include <linux/vmalloc.h>
#include <linux/init.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
#include "bt878.h"
#include "dst_priv.h"
@@ -422,8 +422,7 @@ static int bt878_probe(struct pci_dev *dev, const struct pci_device_id *pci_id)
bt878_num);
if (bt878_num >= BT878_MAX) {
printk(KERN_ERR "bt878: Too many devices inserted\n");
- result = -ENOMEM;
- goto fail0;
+ return -ENOMEM;
}
if (pci_enable_device(dev))
return -EIO;
diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c
index 5cc42b426715..1902732f90e1 100644
--- a/drivers/media/pci/bt8xx/bttv-cards.c
+++ b/drivers/media/pci/bt8xx/bttv-cards.c
@@ -141,6 +141,13 @@ MODULE_PARM_DESC(audiodev, "specify audio device:\n"
MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition.");
MODULE_PARM_DESC(no_overlay, "allow override overlay default (0 disables, 1 enables) [some VIA/SIS chipsets are known to have problem with overlay]");
+
+/* I2C addresses list */
+#define I2C_ADDR_TDA7432 0x8a
+#define I2C_ADDR_MSP3400 0x80
+#define I2C_ADDR_MSP3400_ALT 0x88
+
+
/* ----------------------------------------------------------------------- */
/* list of card IDs for bt878+ cards */
@@ -366,8 +373,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 15,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 2, 0, 0, 0 },
- .gpiomute = 10,
+ .gpiomux = { 2, 0, 0, 0 },
+ .gpiomute = 10,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
},
@@ -378,8 +385,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 7,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
+ .gpiomux = { 0, 1, 2, 3 },
+ .gpiomute = 4,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
},
@@ -390,8 +397,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 7,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 4, 0, 2, 3 },
- .gpiomute = 1,
+ .gpiomux = { 4, 0, 2, 3 },
+ .gpiomute = 1,
.no_msp34xx = 1,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
@@ -407,7 +414,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0 },
+ .gpiomux = { 0 },
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
},
@@ -418,8 +425,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 3,
.muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 0, 1, 0, 1 },
- .gpiomute = 3,
+ .gpiomux = { 0, 1, 0, 1 },
+ .gpiomute = 3,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
},
@@ -430,7 +437,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 3,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomask = 0x0f,
- .gpiomux = { 0x0c, 0x04, 0x08, 0x04 },
+ .gpiomux = { 0x0c, 0x04, 0x08, 0x04 },
/* 0x04 for some cards ?? */
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -444,7 +451,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 3,
.gpiomask = 0,
.muxsel = MUXSEL(2, 3, 1, 0, 0),
- .gpiomux = { 0 },
+ .gpiomux = { 0 },
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
},
@@ -457,8 +464,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0xc00,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0xc00, 0x800, 0x400 },
- .gpiomute = 0xc00,
+ .gpiomux = { 0, 0xc00, 0x800, 0x400 },
+ .gpiomute = 0xc00,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -470,7 +477,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 3,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 1, 2, 3 },
+ .gpiomux = { 1, 1, 2, 3 },
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
@@ -482,8 +489,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x0f, /* old: 7 */
.muxsel = MUXSEL(2, 0, 1, 1),
- .gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
+ .gpiomux = { 0, 1, 2, 3 },
+ .gpiomute = 4,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -495,8 +502,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x3014f,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x20001,0x10001, 0, 0 },
- .gpiomute = 10,
+ .gpiomux = { 0x20001,0x10001, 0, 0 },
+ .gpiomute = 10,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
},
@@ -509,7 +516,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 15,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 13, 14, 11, 7 },
+ .gpiomux = { 13, 14, 11, 7 },
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
},
@@ -520,7 +527,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 15,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 13, 14, 11, 7 },
+ .gpiomux = { 13, 14, 11, 7 },
.msp34xx_alt = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
@@ -535,8 +542,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 7,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */
- .gpiomute = 4,
+ .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */
+ .gpiomute = 4,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -548,8 +555,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 15,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0, 1, 0 },
- .gpiomute = 10,
+ .gpiomux = { 0, 0, 1, 0 },
+ .gpiomute = 10,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
},
@@ -564,7 +571,7 @@ struct tvcard bttv_tvcards[] = {
.muxsel = MUXSEL(2, 3, 1, 1),
/* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
.gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
- .gpiomute = 0x002000,
+ .gpiomute = 0x002000,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -576,8 +583,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x8300f8,
.muxsel = MUXSEL(2, 3, 1, 1, 0),
- .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 },
- .gpiomute = 0xcfa007,
+ .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 },
+ .gpiomute = 0xcfa007,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
.volume_gpio = winview_volume,
@@ -590,7 +597,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 0, 0, 0 },
+ .gpiomux = { 1, 0, 0, 0 },
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
},
@@ -601,7 +608,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = NO_SVHS,
.gpiomask = 0x8dff00,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0 },
+ .gpiomux = { 0 },
.no_msp34xx = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
@@ -624,8 +631,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x1800,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
+ .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
+ .gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
@@ -637,8 +644,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0xc00,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 1, 0x800, 0x400 },
- .gpiomute = 0xc00,
+ .gpiomux = { 0, 1, 0x800, 0x400 },
+ .gpiomute = 0xc00,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -652,7 +659,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 7,
.muxsel = MUXSEL(2, 3, 0), /* input 2 is digital */
/* .digital_mode= DIGITAL_MODE_CAMERA, */
- .gpiomux = { 0, 0, 0, 0 },
+ .gpiomux = { 0, 0, 0, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ALPS_TSBB5_PAL_I,
@@ -667,8 +674,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0xe00,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = {0x400, 0x400, 0x400, 0x400 },
- .gpiomute = 0xc00,
+ .gpiomux = {0x400, 0x400, 0x400, 0x400 },
+ .gpiomute = 0xc00,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -683,7 +690,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x1f0fff,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
- .gpiomute = 0x40000,
+ .gpiomute = 0x40000,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
.audio_mode_gpio= terratv_audio,
@@ -695,8 +702,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 3,
.gpiomask = 7,
.muxsel = MUXSEL(2, 0, 1, 1),
- .gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
+ .gpiomux = { 0, 1, 2, 3 },
+ .gpiomute = 4,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
},
@@ -707,8 +714,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x1800,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
+ .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
+ .gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_SECAM,
.tuner_addr = ADDR_UNSET,
@@ -722,8 +729,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x1f0fff,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 },
- .gpiomute = 0x40000,
+ .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 },
+ .gpiomute = 0x40000,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
.audio_mode_gpio= terratv_audio,
@@ -767,7 +774,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 1, /* was: 4 */
.gpiomask = 0,
.muxsel = MUXSEL(2, 3, 1, 0, 0),
- .gpiomux = { 0 },
+ .gpiomux = { 0 },
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
.muxsel_hook = PXC200_muxsel,
@@ -780,8 +787,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x1800, /* 0x8dfe00 */
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x0800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
+ .gpiomux = { 0, 0x0800, 0x1000, 0x1000 },
+ .gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -793,7 +800,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 3,
.gpiomask = 1,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 0, 0, 0 },
+ .gpiomux = { 1, 0, 0, 0 },
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
@@ -807,7 +814,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0 },
+ .gpiomux = { 0 },
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
},
@@ -818,8 +825,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0xffff00,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x500, 0, 0x300, 0x900 },
- .gpiomute = 0x900,
+ .gpiomux = { 0x500, 0, 0x300, 0x900 },
+ .gpiomute = 0x900,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
@@ -833,8 +840,8 @@ struct tvcard bttv_tvcards[] = {
.muxsel = MUXSEL(2, 3, 1, 1, 0),
/* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
.gpiomask = 0xb33000,
- .gpiomux = { 0x122000,0x1000,0x0000,0x620000 },
- .gpiomute = 0x800000,
+ .gpiomux = { 0x122000,0x1000,0x0000,0x620000 },
+ .gpiomute = 0x800000,
/* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
gpio23 -- hef4052:nEnable (0x800000)
gpio12 -- hef4052:A1
@@ -860,8 +867,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x1800,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
+ .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
+ .gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -875,8 +882,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x1800,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
+ .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
+ .gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -889,8 +896,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0xff,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x21, 0x20, 0x24, 0x2c },
- .gpiomute = 0x29,
+ .gpiomux = { 0x21, 0x20, 0x24, 0x2c },
+ .gpiomute = 0x29,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = UNSET,
@@ -903,8 +910,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x551e00,
.muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 0x551400, 0x551200, 0, 0 },
- .gpiomute = 0x551c00,
+ .gpiomux = { 0x551400, 0x551200, 0, 0 },
+ .gpiomute = 0x551c00,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
@@ -917,8 +924,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x03000F,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 2, 0xd0001, 0, 0 },
- .gpiomute = 1,
+ .gpiomux = { 2, 0xd0001, 0, 0 },
+ .gpiomute = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -932,8 +939,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 7,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 4, 0, 2, 3 },
- .gpiomute = 1,
+ .gpiomux = { 4, 0, 2, 3 },
+ .gpiomute = 1,
.no_msp34xx = 1,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
@@ -947,7 +954,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 15,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 13, 4, 11, 7 },
+ .gpiomux = { 13, 4, 11, 7 },
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -961,7 +968,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0, 0, 0},
+ .gpiomux = { 0, 0, 0, 0},
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
@@ -974,8 +981,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0xe00b,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 },
- .gpiomute = 0xff3ffc,
+ .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 },
+ .gpiomute = 0xff3ffc,
.no_msp34xx = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -989,8 +996,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = NO_SVHS,
.gpiomask = 3,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 1, 0, 2 },
- .gpiomute = 3,
+ .gpiomux = { 1, 1, 0, 2 },
+ .gpiomute = 3,
.no_msp34xx = 1,
.pll = PLL_NONE,
.tuner_type = UNSET,
@@ -1003,7 +1010,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 3,
.gpiomask = 0,
.muxsel = MUXSEL(2, 3, 1, 0, 0),
- .gpiomux = { 0 },
+ .gpiomux = { 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ABSENT,
@@ -1016,8 +1023,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0xbcf03f,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 },
- .gpiomute = 0xbcb03f,
+ .gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 },
+ .gpiomute = 0xbcb03f,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4039FR5_NTSC,
@@ -1030,8 +1037,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x70000,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
- .gpiomute = 0x40000,
+ .gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
+ .gpiomute = 0x40000,
.no_msp34xx = 1,
.pll = PLL_35,
.tuner_type = TUNER_PHILIPS_PAL_I,
@@ -1047,8 +1054,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 15,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = {2,0,0,0 },
- .gpiomute = 1,
+ .gpiomux = {2,0,0,0 },
+ .gpiomute = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
@@ -1060,7 +1067,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x010f00,
.muxsel = MUXSEL(2, 3, 0, 0),
- .gpiomux = {0x10000, 0, 0x10000, 0 },
+ .gpiomux = {0x10000, 0, 0x10000, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ALPS_TSHC6_NTSC,
@@ -1076,8 +1083,8 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0xAA0000,
.muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
/* .digital_mode= DIGITAL_MODE_CAMERA, */
- .gpiomux = { 0x20000, 0, 0x80000, 0x80000 },
- .gpiomute = 0xa8000,
+ .gpiomux = { 0x20000, 0, 0x80000, 0x80000 },
+ .gpiomute = 0xa8000,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
@@ -1101,7 +1108,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 7,
.muxsel = MUXSEL(2, 0, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
+ .gpiomute = 4,
.pll = PLL_28,
.tuner_type = UNSET /* TUNER_ALPS_TMDH2_NTSC */,
.tuner_addr = ADDR_UNSET,
@@ -1116,8 +1123,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 3,
.gpiomask = 0x03000F,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 1, 0xd0001, 0, 0 },
- .gpiomute = 10,
+ .gpiomux = { 1, 0xd0001, 0, 0 },
+ .gpiomute = 10,
/* sound path (5 sources):
MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
0= ext. Audio IN
@@ -1140,8 +1147,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x1c,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0, 0, 0x10, 8 },
- .gpiomute = 4,
+ .gpiomux = { 0, 0, 0x10, 8 },
+ .gpiomute = 4,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
@@ -1159,8 +1166,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x18e0,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
- .gpiomute = 0x18e0,
+ .gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
+ .gpiomute = 0x18e0,
/* For cards with tda9820/tda9821:
0x0000: Tuner normal stereo
0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
@@ -1179,7 +1186,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0xF,
.muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 2, 0, 0, 0 },
- .gpiomute = 10,
+ .gpiomute = 10,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
@@ -1195,7 +1202,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x1800,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
- .gpiomute = 0x1800,
+ .gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
@@ -1225,7 +1232,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0xe00,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x400, 0x400, 0x400, 0x400 },
- .gpiomute = 0x800,
+ .gpiomute = 0x800,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4036FY5_NTSC,
.tuner_addr = ADDR_UNSET,
@@ -1239,7 +1246,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x03000F,
.muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 2, 0, 0, 0 },
- .gpiomute = 1,
+ .gpiomute = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
@@ -1256,7 +1263,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 11,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 1 },
- .gpiomute = 8,
+ .gpiomute = 8,
.pll = PLL_35,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
@@ -1286,7 +1293,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0xFF,
.muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 1, 0, 4, 4 },
- .gpiomute = 9,
+ .gpiomute = 9,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
@@ -1299,8 +1306,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0xf03f,
.muxsel = MUXSEL(2, 3, 1, 0),
- .gpiomux = { 0xbffe, 0, 0xbfff, 0 },
- .gpiomute = 0xbffe,
+ .gpiomux = { 0xbffe, 0, 0xbfff, 0 },
+ .gpiomute = 0xbffe,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
.tuner_addr = ADDR_UNSET,
@@ -1315,7 +1322,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = NO_SVHS,
.gpiomask = 1,
.muxsel = MUXSEL(2, 3, 0, 1),
- .gpiomux = { 0, 0, 1, 0 },
+ .gpiomux = { 0, 0, 1, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
@@ -1332,8 +1339,8 @@ struct tvcard bttv_tvcards[] = {
/* Radio changed from 1e80 to 0x800 to make
FlyVideo2000S in .hu happy (gm)*/
/* -dk-???: set mute=0x1800 for tda9874h daughterboard */
- .gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
- .gpiomute = 0x1800,
+ .gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
+ .gpiomute = 0x1800,
.audio_mode_gpio= fv2000s_audio,
.no_msp34xx = 1,
.pll = PLL_28,
@@ -1347,8 +1354,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0xffff00,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x500, 0x500, 0x300, 0x900 },
- .gpiomute = 0x900,
+ .gpiomux = { 0x500, 0x500, 0x300, 0x900 },
+ .gpiomute = 0x900,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
@@ -1382,7 +1389,7 @@ struct tvcard bttv_tvcards[] = {
/* 0x100000: 1=MSP enabled (0=disable again)
* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
.gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff },
- .gpiomute = 0x947fff,
+ .gpiomute = 0x947fff,
/* tvtuner, radio, external,internal, mute, stereo
* tuner, Composit, SVid, Composit-on-Svid-adapter */
.muxsel = MUXSEL(2, 3, 0, 1),
@@ -1402,7 +1409,7 @@ struct tvcard bttv_tvcards[] = {
/* 0x100000: 1=MSP enabled (0=disable again)
* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
.gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff },
- .gpiomute = 0x947fff,
+ .gpiomute = 0x947fff,
/* tvtuner, radio, external,internal, mute, stereo
* tuner, Composit, SVid, Composit-on-Svid-adapter */
.muxsel = MUXSEL(2, 3, 0, 1),
@@ -1431,7 +1438,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 15,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */
- .gpiomute = 13,
+ .gpiomute = 13,
.pll = PLL_28,
.tuner_type = TUNER_LG_PAL_I_FM,
.tuner_addr = ADDR_UNSET,
@@ -1466,8 +1473,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x3f,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 0x01, 0x00, 0x03, 0x03 },
- .gpiomute = 0x09,
+ .gpiomux = { 0x01, 0x00, 0x03, 0x03 },
+ .gpiomute = 0x09,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
@@ -1518,7 +1525,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
.muxsel = MUXSEL(2, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
- .gpiomute = 4,
+ .gpiomute = 4,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
.pll = PLL_28,
@@ -1535,7 +1542,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x140007,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
+ .gpiomute = 4,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
.audio_mode_gpio= windvr_audio,
@@ -1568,7 +1575,7 @@ struct tvcard bttv_tvcards[] = {
* gpiomux =1: lower volume, 2+3: mute
* btwincap uses 0x80000/0x80003
*/
- .gpiomute = 4,
+ .gpiomute = 4,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
@@ -1619,7 +1626,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x0f0f80,
.muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = {0x030000, 0x010000, 0, 0 },
- .gpiomute = 0x020000,
+ .gpiomute = 0x020000,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
@@ -1822,7 +1829,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 7,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3},
- .gpiomute = 4,
+ .gpiomute = 4,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
.pll = PLL_28,
@@ -1865,7 +1872,7 @@ struct tvcard bttv_tvcards[] = {
.muxsel = MUXSEL(2, 3, 1, 0),
/* Tuner, Radio, external, internal, off, on */
.gpiomux = { 0x08, 0x0f, 0x0a, 0x08 },
- .gpiomute = 0x0f,
+ .gpiomute = 0x0f,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC,
@@ -2132,7 +2139,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x008007,
.muxsel = MUXSEL(2, 3, 0, 0),
.gpiomux = { 0, 0, 0, 0 },
- .gpiomute = 0x000003,
+ .gpiomute = 0x000003,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
@@ -2175,7 +2182,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x008007,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
- .gpiomute = 3,
+ .gpiomute = 3,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
@@ -2290,7 +2297,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0xFF,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
- .gpiomute = 10,
+ .gpiomute = 10,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
@@ -2319,7 +2326,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x3f,
.muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = {0x31, 0x31, 0x31, 0x31 },
- .gpiomute = 0x31,
+ .gpiomute = 0x31,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
@@ -2433,7 +2440,7 @@ struct tvcard bttv_tvcards[] = {
.muxsel = MUXSEL(2, 3, 1),
.gpiomask = 0x00e00007,
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
- .gpiomute = 0x00c00007,
+ .gpiomute = 0x00c00007,
.no_msp34xx = 1,
.no_tda7432 = 1,
.has_dvb = 1,
@@ -2448,7 +2455,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x01fe00,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
- .gpiomute = 0x002000,
+ .gpiomute = 0x002000,
.pll = PLL_28,
.tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
.tuner_addr = 0xc1 >>1,
@@ -2463,7 +2470,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x001c0007,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
- .gpiomute = 3,
+ .gpiomute = 3,
.pll = PLL_28,
.tuner_type = TUNER_TENA_9533_DI,
.tuner_addr = ADDR_UNSET,
@@ -2498,7 +2505,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x3f,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x21, 0x20, 0x24, 0x2c },
- .gpiomute = 0x29,
+ .gpiomute = 0x29,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_YMEC_TVF_5533MF,
@@ -2542,8 +2549,8 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 15,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 2, 0, 0, 0 },
- .gpiomute = 1,
+ .gpiomux = { 2, 0, 0, 0 },
+ .gpiomute = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
@@ -2556,7 +2563,7 @@ struct tvcard bttv_tvcards[] = {
.svhs = 2,
.gpiomask = 0x108007,
.muxsel = MUXSEL(2, 3, 1, 1),
- .gpiomux = { 100000, 100002, 100002, 100000 },
+ .gpiomux = { 100000, 100002, 100002, 100000 },
.no_msp34xx = 1,
.no_tda7432 = 1,
.pll = PLL_28,
@@ -2592,7 +2599,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 7,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
- .gpiomute = 4,
+ .gpiomute = 4,
.tuner_type = TUNER_TEMIC_4009FR5_PAL,
.tuner_addr = ADDR_UNSET,
.pll = PLL_28,
@@ -2628,7 +2635,7 @@ struct tvcard bttv_tvcards[] = {
.muxsel = MUXSEL(2, 3, 1),
.gpiomask = 0x00e00007,
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
- .gpiomute = 0x00c00007,
+ .gpiomute = 0x00c00007,
.no_msp34xx = 1,
.no_tda7432 = 1,
},
@@ -2672,7 +2679,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x008007,
.muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */
- .gpiomute = 3, /* CONTVFMi */
+ .gpiomute = 3, /* CONTVFMi */
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */
.tuner_addr = ADDR_UNSET,
.pll = PLL_28,
@@ -2695,7 +2702,7 @@ struct tvcard bttv_tvcards[] = {
.gpiomask = 0x060040,
.muxsel = MUXSEL(2, 3, 3),
.gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 },
- .gpiomute = 0,
+ .gpiomute = 0,
.tuner_type = TUNER_TCL_MF02GIP_5N,
.tuner_addr = ADDR_UNSET,
.pll = PLL_28,
@@ -2745,8 +2752,8 @@ struct tvcard bttv_tvcards[] = {
/* Bruno Christo <bchristo@inf.ufsm.br>
*
* GeoVision GV-800(S) has 4 Conexant Fusion 878A:
- * 1 audio input per BT878A = 4 audio inputs
- * 4 video inputs per BT878A = 16 video inputs
+ * 1 audio input per BT878A = 4 audio inputs
+ * 4 video inputs per BT878A = 16 video inputs
* This is the first BT878A chip of the GV-800(S). It's the
* "master" chip and it controls the video inputs through an
* analog multiplexer (a CD22M3494) via some GPIO pins. The
@@ -2772,8 +2779,8 @@ struct tvcard bttv_tvcards[] = {
/* Bruno Christo <bchristo@inf.ufsm.br>
*
* GeoVision GV-800(S) has 4 Conexant Fusion 878A:
- * 1 audio input per BT878A = 4 audio inputs
- * 4 video inputs per BT878A = 16 video inputs
+ * 1 audio input per BT878A = 4 audio inputs
+ * 4 video inputs per BT878A = 16 video inputs
* The 3 other BT878A chips are "slave" chips of the GV-800(S)
* and should use this card type.
* The audio input is not working yet.
@@ -4777,9 +4784,9 @@ static void gv800s_write(struct bttv *btv,
* GPIO bits 0-9 are used for the analog switch:
* 00 - 03: camera selector
* 04 - 06: 878A (controller) selector
- * 16: cselect
+ * 16: cselect
* 17: strobe
- * 18: data (1->on, 0->off)
+ * 18: data (1->on, 0->off)
* 19: reset
*/
const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4);
@@ -4875,7 +4882,7 @@ void __init bttv_check_chipset(void)
int pcipci_fail = 0;
struct pci_dev *dev = NULL;
- if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) /* should check if target is AGP */
+ if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) /* should check if target is AGP */
pcipci_fail = 1;
if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF))
triton1 = 1;
diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c
index ac7674700685..da49c5567db5 100644
--- a/drivers/media/pci/bt8xx/bttv-input.c
+++ b/drivers/media/pci/bt8xx/bttv-input.c
@@ -349,12 +349,12 @@ static int get_key_pv951(struct IR_i2c *ir, enum rc_proto *protocol,
* NOTE:
* lirc_i2c maps the pv951 code as:
* addr = 0x61D6
- * cmd = bit_reverse (b)
+ * cmd = bit_reverse (b)
* So, it seems that this device uses NEC extended
* I decided to not fix the table, due to two reasons:
- * 1) Without the actual device, this is only a guess;
- * 2) As the addr is not reported via I2C, nor can be changed,
- * the device is bound to the vendor-provided RC.
+ * 1) Without the actual device, this is only a guess;
+ * 2) As the addr is not reported via I2C, nor can be changed,
+ * the device is bound to the vendor-provided RC.
*/
*protocol = RC_PROTO_UNKNOWN;
diff --git a/drivers/media/pci/bt8xx/bttv.h b/drivers/media/pci/bt8xx/bttv.h
index eb67e362acf7..a27384adadd2 100644
--- a/drivers/media/pci/bt8xx/bttv.h
+++ b/drivers/media/pci/bt8xx/bttv.h
@@ -18,7 +18,6 @@
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/i2c-addr.h>
#include <media/tuner.h>
/* ---------------------------------------------------------- */
@@ -166,7 +165,7 @@
#define BTTV_BOARD_PV_M4900 0x8b
#define BTTV_BOARD_OSPREY440 0x8c
#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
-#define BTTV_BOARD_SABRENT_TVFM 0x8e
+#define BTTV_BOARD_SABRENT_TVFM 0x8e
#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
#define BTTV_BOARD_MACHTV_MAGICTV 0x90
#define BTTV_BOARD_SSAI_SECURITY 0x91
@@ -266,7 +265,7 @@ extern struct tvcard bttv_tvcards[];
* that they are changed to octal. One should not use hex number, macros, or
* anything else with this macro. Just use plain integers from 0 to 3.
*/
-#define _MUXSELf(a) 0##a << 30
+#define _MUXSELf(a) 0##a << 30
#define _MUXSELe(a, b...) 0##a << 28 | _MUXSELf(b)
#define _MUXSELd(a, b...) 0##a << 26 | _MUXSELe(b)
#define _MUXSELc(a, b...) 0##a << 24 | _MUXSELd(b)
diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h
index cb1b5e611130..7a86e7295166 100644
--- a/drivers/media/pci/bt8xx/bttvp.h
+++ b/drivers/media/pci/bt8xx/bttvp.h
@@ -141,7 +141,7 @@ struct bttv_ir {
bool rc5_gpio; /* Is RC5 legacy GPIO enabled? */
u32 last_bit; /* last raw bit seen */
u32 code; /* raw code under construction */
- ktime_t base_time; /* time of last seen code */
+ ktime_t base_time; /* time of last seen code */
bool active; /* building raw code */
};
@@ -400,8 +400,8 @@ struct bttv {
int i2c_state, i2c_rc;
int i2c_done;
wait_queue_head_t i2c_queue;
- struct v4l2_subdev *sd_msp34xx;
- struct v4l2_subdev *sd_tvaudio;
+ struct v4l2_subdev *sd_msp34xx;
+ struct v4l2_subdev *sd_tvaudio;
struct v4l2_subdev *sd_tda7432;
/* video4linux (1) */
diff --git a/drivers/media/pci/bt8xx/dst.c b/drivers/media/pci/bt8xx/dst.c
index 7166d2279465..4f0bba9e4c48 100644
--- a/drivers/media/pci/bt8xx/dst.c
+++ b/drivers/media/pci/bt8xx/dst.c
@@ -28,7 +28,7 @@
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "dst_priv.h"
#include "dst_common.h"
diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c
index 530b3e9764ce..0a7623c0fc8e 100644
--- a/drivers/media/pci/bt8xx/dst_ca.c
+++ b/drivers/media/pci/bt8xx/dst_ca.c
@@ -25,8 +25,8 @@
#include <linux/mutex.h>
#include <linux/string.h>
#include <linux/dvb/ca.h>
-#include "dvbdev.h"
-#include "dvb_frontend.h"
+#include <media/dvbdev.h>
+#include <media/dvb_frontend.h>
#include "dst_ca.h"
#include "dst_common.h"
diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c
index ad617871ce9b..f60d69ac515b 100644
--- a/drivers/media/pci/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c
@@ -26,10 +26,10 @@
#include <linux/slab.h>
#include <linux/i2c.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
#include "dvb-bt8xx.h"
#include "bt878.h"
diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.h b/drivers/media/pci/bt8xx/dvb-bt8xx.h
index 0ec538e23b4e..3184b3f3a85e 100644
--- a/drivers/media/pci/bt8xx/dvb-bt8xx.h
+++ b/drivers/media/pci/bt8xx/dvb-bt8xx.h
@@ -23,8 +23,8 @@
#include <linux/i2c.h>
#include <linux/mutex.h>
-#include "dvbdev.h"
-#include "dvb_net.h"
+#include <media/dvbdev.h>
+#include <media/dvb_net.h>
#include "bttv.h"
#include "mt352.h"
#include "sp887x.h"
diff --git a/drivers/media/pci/cobalt/Kconfig b/drivers/media/pci/cobalt/Kconfig
index 70343829a125..aa35cbc0a904 100644
--- a/drivers/media/pci/cobalt/Kconfig
+++ b/drivers/media/pci/cobalt/Kconfig
@@ -6,6 +6,7 @@ config VIDEO_COBALT
depends on SND
depends on MTD
select I2C_ALGOBIT
+ select SND_PCM
select VIDEO_ADV7604
select VIDEO_ADV7511
select VIDEO_ADV7842
diff --git a/drivers/media/pci/cx18/Makefile b/drivers/media/pci/cx18/Makefile
index 98914a40f6ac..9c82c2df05e1 100644
--- a/drivers/media/pci/cx18/Makefile
+++ b/drivers/media/pci/cx18/Makefile
@@ -9,6 +9,5 @@ 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-core
ccflags-y += -Idrivers/media/dvb-frontends
ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/cx18/cx18-alsa-pcm.c b/drivers/media/pci/cx18/cx18-alsa-pcm.c
index aadd76466aec..4f31042a442a 100644
--- a/drivers/media/pci/cx18/cx18-alsa-pcm.c
+++ b/drivers/media/pci/cx18/cx18-alsa-pcm.c
@@ -41,7 +41,7 @@ MODULE_PARM_DESC(pcm_debug, "enable debug messages for pcm");
#define dprintk(fmt, arg...) do { \
if (pcm_debug) \
printk(KERN_INFO "cx18-alsa-pcm %s: " fmt, \
- __func__, ##arg); \
+ __func__, ##arg); \
} while (0)
static const struct snd_pcm_hardware snd_cx18_hw_capture = {
diff --git a/drivers/media/pci/cx18/cx18-av-audio.c b/drivers/media/pci/cx18/cx18-av-audio.c
index 8b95e9aae576..3abc54cbe4a1 100644
--- a/drivers/media/pci/cx18/cx18-av-audio.c
+++ b/drivers/media/pci/cx18/cx18-av-audio.c
@@ -31,7 +31,7 @@ static int set_audclk_freq(struct cx18 *cx, u32 freq)
* would ideally be:
*
* NTSC Color subcarrier freq * 8 =
- * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
+ * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
*
* The accidents of history and rationale that explain from where this
* combination of magic numbers originate can be found in:
diff --git a/drivers/media/pci/cx18/cx18-av-core.c b/drivers/media/pci/cx18/cx18-av-core.c
index cf8817e9c8b9..eda343322ee0 100644
--- a/drivers/media/pci/cx18/cx18-av-core.c
+++ b/drivers/media/pci/cx18/cx18-av-core.c
@@ -236,10 +236,10 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
*/
cx18_av_and_or4(cx, CXADEC_AFE_CTRL, 0xFF000000, 0x00005D00);
-/* if(dwEnable && dw3DCombAvailable) { */
-/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
+/* if(dwEnable && dw3DCombAvailable) { */
+/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */
/* } else { */
-/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
+/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
/* } */
cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
default_volume = cx18_av_read(cx, 0x8d4);
@@ -319,13 +319,13 @@ void cx18_av_std_setup(struct cx18 *cx)
* vblank656: half lines after line 625/mid-313 of blanked video
* vblank: half lines, after line 5/317, of blanked video
* vactive: half lines of active video +
- * 5 half lines after the end of active video
+ * 5 half lines after the end of active video
*
* As far as I can tell:
* vblank656 starts counting from the falling edge of the first
- * vsync pulse (start of line 1 or mid-313)
+ * vsync pulse (start of line 1 or mid-313)
* vblank starts counting from the after the 5 vsync pulses and
- * 5 or 4 equalization pulses (start of line 6 or 318)
+ * 5 or 4 equalization pulses (start of line 6 or 318)
*
* For 625 line systems the driver will extract VBI information
* from lines 6-23 and lines 318-335 (but the slicer can only
@@ -395,9 +395,9 @@ void cx18_av_std_setup(struct cx18 *cx)
*
* As far as I can tell:
* vblank656 starts counting from the falling edge of the first
- * vsync pulse (start of line 4 or mid-266)
+ * vsync pulse (start of line 4 or mid-266)
* vblank starts counting from the after the 6 vsync pulses and
- * 6 or 5 equalization pulses (start of line 10 or 272)
+ * 6 or 5 equalization pulses (start of line 10 or 272)
*
* For 525 line systems the driver will extract VBI information
* from lines 10-21 and lines 273-284.
@@ -851,7 +851,7 @@ static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
struct cx18_av_state *state = to_cx18_av_state(sd);
struct cx18 *cx = v4l2_get_subdevdata(sd);
- u8 fmt = 0; /* zero is autodetect */
+ u8 fmt = 0; /* zero is autodetect */
u8 pal_m = 0;
if (state->radio == 0 && state->std == norm)
diff --git a/drivers/media/pci/cx18/cx18-av-core.h b/drivers/media/pci/cx18/cx18-av-core.h
index c976ce6e7a78..1a37f269d2e4 100644
--- a/drivers/media/pci/cx18/cx18-av-core.h
+++ b/drivers/media/pci/cx18/cx18-av-core.h
@@ -349,7 +349,7 @@ static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
}
/* ----------------------------------------------------------------------- */
-/* cx18_av-core.c */
+/* cx18_av-core.c */
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value);
int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value);
diff --git a/drivers/media/pci/cx18/cx18-cards.c b/drivers/media/pci/cx18/cx18-cards.c
index 11e898e66ce9..c2cf965d639e 100644
--- a/drivers/media/pci/cx18/cx18-cards.c
+++ b/drivers/media/pci/cx18/cx18-cards.c
@@ -388,7 +388,7 @@ static const struct cx18_card cx18_card_cnxt_raptor_pal = {
{ CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
},
.audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
+ { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
{ CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
{ CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
},
@@ -439,7 +439,7 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
{ CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
},
.audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
+ { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
{ CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
},
.tuners = {
@@ -485,7 +485,7 @@ static const struct cx18_card cx18_card_leadtek_pvr2100 = {
{ CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
},
.audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
+ { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
{ CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
},
.tuners = {
@@ -538,7 +538,7 @@ static const struct cx18_card cx18_card_leadtek_dvr3100h = {
{ CX18_CARD_INPUT_COMPONENT1, 1, CX18_AV_COMPONENT1 },
},
.audio_inputs = {
- { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
+ { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
{ CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
},
.tuners = {
diff --git a/drivers/media/pci/cx18/cx18-cards.h b/drivers/media/pci/cx18/cx18-cards.h
index 667e2d7b1d03..02d0fb703a41 100644
--- a/drivers/media/pci/cx18/cx18-cards.h
+++ b/drivers/media/pci/cx18/cx18-cards.h
@@ -25,30 +25,24 @@
#define CX18_HW_418_AV (1 << 4)
#define CX18_HW_GPIO_MUX (1 << 5)
#define CX18_HW_GPIO_RESET_CTRL (1 << 6)
-#define CX18_HW_Z8F0811_IR_TX_HAUP (1 << 7)
-#define CX18_HW_Z8F0811_IR_RX_HAUP (1 << 8)
-#define CX18_HW_Z8F0811_IR_HAUP (CX18_HW_Z8F0811_IR_RX_HAUP | \
- CX18_HW_Z8F0811_IR_TX_HAUP)
-
-#define CX18_HW_IR_ANY (CX18_HW_Z8F0811_IR_RX_HAUP | \
- CX18_HW_Z8F0811_IR_TX_HAUP)
+#define CX18_HW_Z8F0811_IR_HAUP (1 << 7)
/* video inputs */
#define CX18_CARD_INPUT_VID_TUNER 1
-#define CX18_CARD_INPUT_SVIDEO1 2
-#define CX18_CARD_INPUT_SVIDEO2 3
-#define CX18_CARD_INPUT_COMPOSITE1 4
-#define CX18_CARD_INPUT_COMPOSITE2 5
-#define CX18_CARD_INPUT_COMPONENT1 6
+#define CX18_CARD_INPUT_SVIDEO1 2
+#define CX18_CARD_INPUT_SVIDEO2 3
+#define CX18_CARD_INPUT_COMPOSITE1 4
+#define CX18_CARD_INPUT_COMPOSITE2 5
+#define CX18_CARD_INPUT_COMPONENT1 6
/* audio inputs */
#define CX18_CARD_INPUT_AUD_TUNER 1
-#define CX18_CARD_INPUT_LINE_IN1 2
-#define CX18_CARD_INPUT_LINE_IN2 3
+#define CX18_CARD_INPUT_LINE_IN1 2
+#define CX18_CARD_INPUT_LINE_IN2 3
#define CX18_CARD_MAX_VIDEO_INPUTS 6
#define CX18_CARD_MAX_AUDIO_INPUTS 3
-#define CX18_CARD_MAX_TUNERS 2
+#define CX18_CARD_MAX_TUNERS 2
/* V4L2 capability aliases */
#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
@@ -57,7 +51,7 @@
V4L2_CAP_SLICED_VBI_CAPTURE)
struct cx18_card_video_input {
- u8 video_type; /* video input type */
+ u8 video_type; /* video input type */
u8 audio_index; /* index in cx18_card_audio_input array */
u32 video_input; /* hardware video input */
};
@@ -80,7 +74,7 @@ struct cx18_card_pci_info {
/* The mask is the set of bits used by the operation */
struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
- u32 direction; /* DIR setting. Leave to 0 if no init is needed */
+ u32 direction; /* DIR setting. Leave to 0 if no init is needed */
u32 initial_value;
};
@@ -92,16 +86,16 @@ struct cx18_gpio_i2c_slave_reset {
u32 ir_reset_mask; /* GPIO to reset the Zilog Z8F0811 IR contoller */
};
-struct cx18_gpio_audio_input { /* select tuner/line in input */
- u32 mask; /* leave to 0 if not supported */
+struct cx18_gpio_audio_input { /* select tuner/line in input */
+ u32 mask; /* leave to 0 if not supported */
u32 tuner;
u32 linein;
u32 radio;
};
struct cx18_card_tuner {
- v4l2_std_id std; /* standard for which the tuner is suitable */
- int tuner; /* tuner ID (from tuner.h) */
+ v4l2_std_id std; /* standard for which the tuner is suitable */
+ int tuner; /* tuner ID (from tuner.h) */
};
struct cx18_card_tuner_i2c {
@@ -134,8 +128,8 @@ struct cx18_card {
struct cx18_card_audio_input radio_input;
/* GPIO card-specific settings */
- u8 xceive_pin; /* XCeive tuner GPIO reset pin */
- struct cx18_gpio_init gpio_init;
+ u8 xceive_pin; /* XCeive tuner GPIO reset pin */
+ struct cx18_gpio_init gpio_init;
struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset;
struct cx18_gpio_audio_input gpio_audio_input;
diff --git a/drivers/media/pci/cx18/cx18-driver.h b/drivers/media/pci/cx18/cx18-driver.h
index 7be2088c45fe..0b707faca543 100644
--- a/drivers/media/pci/cx18/cx18-driver.h
+++ b/drivers/media/pci/cx18/cx18-driver.h
@@ -50,12 +50,12 @@
#include "cx23418.h"
/* DVB */
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
/* Videobuf / YUV support */
#include <media/videobuf-core.h>
@@ -75,8 +75,8 @@
/* Supported cards */
#define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */
#define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */
-#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
-#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
+#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */
+#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
@@ -99,9 +99,9 @@
#define PCI_DEVICE_ID_CX23418 0x5b7a
/* subsystem vendor ID */
-#define CX18_PCI_ID_HAUPPAUGE 0x0070
-#define CX18_PCI_ID_COMPRO 0x185b
-#define CX18_PCI_ID_YUAN 0x12ab
+#define CX18_PCI_ID_HAUPPAUGE 0x0070
+#define CX18_PCI_ID_COMPRO 0x185b
+#define CX18_PCI_ID_YUAN 0x12ab
#define CX18_PCI_ID_CONEXANT 0x14f1
#define CX18_PCI_ID_TOSHIBA 0x1179
#define CX18_PCI_ID_LEADTEK 0x107D
@@ -260,7 +260,7 @@ struct cx18_options {
#define CX18_F_M_NEED_SWAP 0 /* mdl buffer data must be endianness swapped */
/* per-stream, s_flags */
-#define CX18_F_S_CLAIMED 3 /* this stream is claimed */
+#define CX18_F_S_CLAIMED 3 /* this stream is claimed */
#define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */
@@ -268,12 +268,12 @@ struct cx18_options {
#define CX18_F_S_STOPPING 9 /* telling the fw to stop capturing */
/* per-cx18, i_flags */
-#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */
-#define CX18_F_I_EOS 4 /* End of encoder stream */
-#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */
-#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */
-#define CX18_F_I_INITED 21 /* set after first open */
-#define CX18_F_I_FAILED 22 /* set if first open failed */
+#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */
+#define CX18_F_I_EOS 4 /* End of encoder stream */
+#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */
+#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */
+#define CX18_F_I_INITED 21 /* set after first open */
+#define CX18_F_I_FAILED 22 /* set if first open failed */
/* These are the VBI types as they appear in the embedded VBI private packets. */
#define CX18_SLICED_TYPE_TELETEXT_B (1)
@@ -370,7 +370,7 @@ struct cx18_stream {
is not actually created. */
struct video_device video_dev; /* v4l2_dev is NULL when stream not created */
struct cx18_dvb *dvb; /* DVB / Digital Transport */
- struct cx18 *cx; /* for ease of use */
+ struct cx18 *cx; /* for ease of use */
const char *name; /* name of the stream */
int type; /* stream type */
u32 handle; /* task handle */
@@ -525,14 +525,14 @@ struct vbi_info {
* into the MPEG PS stream.
*
* In each sliced_mpeg_data[] buffer is:
- * 16 byte MPEG-2 PS Program Pack Header
- * 16 byte MPEG-2 Private Stream 1 PES Header
- * 4 byte magic number: "itv0" or "ITV0"
- * 4 byte first field line mask, if "itv0"
- * 4 byte second field line mask, if "itv0"
- * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
+ * 16 byte MPEG-2 PS Program Pack Header
+ * 16 byte MPEG-2 Private Stream 1 PES Header
+ * 4 byte magic number: "itv0" or "ITV0"
+ * 4 byte first field line mask, if "itv0"
+ * 4 byte second field line mask, if "itv0"
+ * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
*
- * Each line in the payload is
+ * Each line in the payload is
* 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
* 42 bytes of line data
*
@@ -583,7 +583,7 @@ struct cx18 {
u8 nof_inputs; /* number of video inputs */
u8 nof_audio_inputs; /* number of audio inputs */
u32 v4l2_cap; /* V4L2 capabilities of card */
- u32 hw_flags; /* Hardware description of the board */
+ u32 hw_flags; /* Hardware description of the board */
unsigned int free_mdl_idx;
struct cx18_scb __iomem *scb; /* pointer to SCB */
struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/
@@ -602,10 +602,10 @@ struct cx18 {
u32 dualwatch_stereo_mode;
struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
- struct cx18_options options; /* User options */
+ struct cx18_options options; /* User options */
int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */
int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */
- struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
+ struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */
struct snd_cx18_card *alsa; /* ALSA interface for PCM capture stream */
void (*pcm_announce_callback)(struct snd_cx18_card *card, u8 *pcm_data,
size_t num_bytes);
diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c
index 2b0abd5bbf64..a8dbb922ba4b 100644
--- a/drivers/media/pci/cx18/cx18-fileops.c
+++ b/drivers/media/pci/cx18/cx18-fileops.c
@@ -633,7 +633,7 @@ __poll_t cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
if (v4l2_event_pending(&id->fh))
res |= POLLPRI;
- if (eof && videobuf_poll == POLLERR)
+ if (eof && videobuf_poll == POLLERR)
return res | POLLHUP;
return res | videobuf_poll;
}
diff --git a/drivers/media/pci/cx18/cx18-firmware.c b/drivers/media/pci/cx18/cx18-firmware.c
index 1b34ea1c3730..498a1854b3b0 100644
--- a/drivers/media/pci/cx18/cx18-firmware.c
+++ b/drivers/media/pci/cx18/cx18-firmware.c
@@ -23,65 +23,65 @@
#include "cx18-cards.h"
#include <linux/firmware.h>
-#define CX18_PROC_SOFT_RESET 0xc70010
-#define CX18_DDR_SOFT_RESET 0xc70014
-#define CX18_CLOCK_SELECT1 0xc71000
-#define CX18_CLOCK_SELECT2 0xc71004
-#define CX18_HALF_CLOCK_SELECT1 0xc71008
-#define CX18_HALF_CLOCK_SELECT2 0xc7100C
-#define CX18_CLOCK_POLARITY1 0xc71010
-#define CX18_CLOCK_POLARITY2 0xc71014
-#define CX18_ADD_DELAY_ENABLE1 0xc71018
-#define CX18_ADD_DELAY_ENABLE2 0xc7101C
-#define CX18_CLOCK_ENABLE1 0xc71020
-#define CX18_CLOCK_ENABLE2 0xc71024
-
-#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
-
-#define CX18_FAST_CLOCK_PLL_INT 0xc78000
-#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004
-#define CX18_FAST_CLOCK_PLL_POST 0xc78008
-#define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C
+#define CX18_PROC_SOFT_RESET 0xc70010
+#define CX18_DDR_SOFT_RESET 0xc70014
+#define CX18_CLOCK_SELECT1 0xc71000
+#define CX18_CLOCK_SELECT2 0xc71004
+#define CX18_HALF_CLOCK_SELECT1 0xc71008
+#define CX18_HALF_CLOCK_SELECT2 0xc7100C
+#define CX18_CLOCK_POLARITY1 0xc71010
+#define CX18_CLOCK_POLARITY2 0xc71014
+#define CX18_ADD_DELAY_ENABLE1 0xc71018
+#define CX18_ADD_DELAY_ENABLE2 0xc7101C
+#define CX18_CLOCK_ENABLE1 0xc71020
+#define CX18_CLOCK_ENABLE2 0xc71024
+
+#define CX18_REG_BUS_TIMEOUT_EN 0xc72024
+
+#define CX18_FAST_CLOCK_PLL_INT 0xc78000
+#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004
+#define CX18_FAST_CLOCK_PLL_POST 0xc78008
+#define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C
#define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010
-#define CX18_SLOW_CLOCK_PLL_INT 0xc78014
-#define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018
-#define CX18_SLOW_CLOCK_PLL_POST 0xc7801C
+#define CX18_SLOW_CLOCK_PLL_INT 0xc78014
+#define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018
+#define CX18_SLOW_CLOCK_PLL_POST 0xc7801C
#define CX18_MPEG_CLOCK_PLL_INT 0xc78040
#define CX18_MPEG_CLOCK_PLL_FRAC 0xc78044
#define CX18_MPEG_CLOCK_PLL_POST 0xc78048
-#define CX18_PLL_POWER_DOWN 0xc78088
+#define CX18_PLL_POWER_DOWN 0xc78088
#define CX18_SW1_INT_STATUS 0xc73104
#define CX18_SW1_INT_ENABLE_PCI 0xc7311C
#define CX18_SW2_INT_SET 0xc73140
#define CX18_SW2_INT_STATUS 0xc73144
-#define CX18_ADEC_CONTROL 0xc78120
+#define CX18_ADEC_CONTROL 0xc78120
-#define CX18_DDR_REQUEST_ENABLE 0xc80000
-#define CX18_DDR_CHIP_CONFIG 0xc80004
-#define CX18_DDR_REFRESH 0xc80008
-#define CX18_DDR_TIMING1 0xc8000C
-#define CX18_DDR_TIMING2 0xc80010
+#define CX18_DDR_REQUEST_ENABLE 0xc80000
+#define CX18_DDR_CHIP_CONFIG 0xc80004
+#define CX18_DDR_REFRESH 0xc80008
+#define CX18_DDR_TIMING1 0xc8000C
+#define CX18_DDR_TIMING2 0xc80010
#define CX18_DDR_POWER_REG 0xc8001C
-#define CX18_DDR_TUNE_LANE 0xc80048
-#define CX18_DDR_INITIAL_EMRS 0xc80054
-#define CX18_DDR_MB_PER_ROW_7 0xc8009C
-#define CX18_DDR_BASE_63_ADDR 0xc804FC
-
-#define CX18_WMB_CLIENT02 0xc90108
-#define CX18_WMB_CLIENT05 0xc90114
-#define CX18_WMB_CLIENT06 0xc90118
-#define CX18_WMB_CLIENT07 0xc9011C
-#define CX18_WMB_CLIENT08 0xc90120
-#define CX18_WMB_CLIENT09 0xc90124
-#define CX18_WMB_CLIENT10 0xc90128
-#define CX18_WMB_CLIENT11 0xc9012C
-#define CX18_WMB_CLIENT12 0xc90130
-#define CX18_WMB_CLIENT13 0xc90134
-#define CX18_WMB_CLIENT14 0xc90138
-
-#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
+#define CX18_DDR_TUNE_LANE 0xc80048
+#define CX18_DDR_INITIAL_EMRS 0xc80054
+#define CX18_DDR_MB_PER_ROW_7 0xc8009C
+#define CX18_DDR_BASE_63_ADDR 0xc804FC
+
+#define CX18_WMB_CLIENT02 0xc90108
+#define CX18_WMB_CLIENT05 0xc90114
+#define CX18_WMB_CLIENT06 0xc90118
+#define CX18_WMB_CLIENT07 0xc9011C
+#define CX18_WMB_CLIENT08 0xc90120
+#define CX18_WMB_CLIENT09 0xc90124
+#define CX18_WMB_CLIENT10 0xc90128
+#define CX18_WMB_CLIENT11 0xc9012C
+#define CX18_WMB_CLIENT12 0xc90130
+#define CX18_WMB_CLIENT13 0xc90134
+#define CX18_WMB_CLIENT14 0xc90138
+
+#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
#define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */
#define APU_ROM_SYNC2 0x72646548 /* "rdeH" */
@@ -229,7 +229,7 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
* would ideally be:
*
* NTSC Color subcarrier freq * 8 =
- * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
+ * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz
*
* The accidents of history and rationale that explain from where this
* combination of magic numbers originate can be found in:
diff --git a/drivers/media/pci/cx18/cx18-i2c.c b/drivers/media/pci/cx18/cx18-i2c.c
index 7f588eeac60f..f0eb181f2b94 100644
--- a/drivers/media/pci/cx18/cx18-i2c.c
+++ b/drivers/media/pci/cx18/cx18-i2c.c
@@ -47,8 +47,7 @@ static const u8 hw_addrs[] = {
0, /* CX18_HW_418_AV */
0, /* CX18_HW_GPIO_MUX */
0, /* CX18_HW_GPIO_RESET_CTRL */
- CX18_Z8F0811_IR_TX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_TX_HAUP */
- CX18_Z8F0811_IR_RX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_RX_HAUP */
+ CX18_Z8F0811_IR_RX_I2C_ADDR, /* CX18_HW_Z8F0811_IR_HAUP */
};
/* This array should match the CX18_HW_ defines */
@@ -61,8 +60,7 @@ static const u8 hw_bus[] = {
0, /* CX18_HW_418_AV */
0, /* CX18_HW_GPIO_MUX */
0, /* CX18_HW_GPIO_RESET_CTRL */
- 0, /* CX18_HW_Z8F0811_IR_TX_HAUP */
- 0, /* CX18_HW_Z8F0811_IR_RX_HAUP */
+ 0, /* CX18_HW_Z8F0811_IR_HAUP */
};
/* This array should match the CX18_HW_ defines */
@@ -74,8 +72,7 @@ static const char * const hw_devicenames[] = {
"cx23418_AV",
"gpio_mux",
"gpio_reset_ctrl",
- "ir_tx_z8f0811_haup",
- "ir_rx_z8f0811_haup",
+ "ir_z8f0811_haup",
};
static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
@@ -90,7 +87,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
/* Our default information for ir-kbd-i2c.c to use */
switch (hw) {
- case CX18_HW_Z8F0811_IR_RX_HAUP:
+ case CX18_HW_Z8F0811_IR_HAUP:
init_data->ir_codes = RC_MAP_HAUPPAUGE;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE |
@@ -129,7 +126,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
return sd != NULL ? 0 : -1;
}
- if (hw & CX18_HW_IR_ANY)
+ if (hw == CX18_HW_Z8F0811_IR_HAUP)
return cx18_i2c_new_ir(cx, adap, hw, type, hw_addrs[idx]);
/* Is it not an I2C device or one we do not wish to register? */
diff --git a/drivers/media/pci/cx18/cx18-mailbox.c b/drivers/media/pci/cx18/cx18-mailbox.c
index 763f960fc918..f66dd63e1994 100644
--- a/drivers/media/pci/cx18/cx18-mailbox.c
+++ b/drivers/media/pci/cx18/cx18-mailbox.c
@@ -35,7 +35,7 @@ struct cx18_api_info {
u32 cmd;
u8 flags; /* Flags, see above */
u8 rpu; /* Processing unit */
- const char *name; /* The name of the command */
+ const char *name; /* The name of the command */
};
#define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x }
@@ -43,9 +43,9 @@ struct cx18_api_info {
static const struct cx18_api_info api_info[] = {
/* MPEG encoder API */
API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0),
- API_ENTRY(CPU, CX18_EPU_DEBUG, 0),
- API_ENTRY(CPU, CX18_CREATE_TASK, 0),
- API_ENTRY(CPU, CX18_DESTROY_TASK, 0),
+ API_ENTRY(CPU, CX18_EPU_DEBUG, 0),
+ API_ENTRY(CPU, CX18_CREATE_TASK, 0),
+ API_ENTRY(CPU, CX18_DESTROY_TASK, 0),
API_ENTRY(CPU, CX18_CPU_CAPTURE_START, API_SLOW),
API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP, API_SLOW),
API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE, 0),
diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c
index f35f78d66985..a594cfdeca20 100644
--- a/drivers/media/pci/cx18/cx18-streams.c
+++ b/drivers/media/pci/cx18/cx18-streams.c
@@ -29,7 +29,7 @@
#include "cx18-scb.h"
#include "cx18-dvb.h"
-#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
+#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
static const struct v4l2_file_operations cx18_v4l2_enc_fops = {
.owner = THIS_MODULE,
@@ -116,7 +116,7 @@ static int cx18_prepare_buffer(struct videobuf_queue *q,
unsigned int width, unsigned int height,
enum v4l2_field field)
{
- struct cx18 *cx = s->cx;
+ struct cx18 *cx = s->cx;
int rc = 0;
/* check settings */
diff --git a/drivers/media/pci/cx18/cx18-vbi.c b/drivers/media/pci/cx18/cx18-vbi.c
index 72c74d60c6fb..81f1e27436fd 100644
--- a/drivers/media/pci/cx18/cx18-vbi.c
+++ b/drivers/media/pci/cx18/cx18-vbi.c
@@ -47,7 +47,7 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */
0x00, 0x1a, /* length */
0x84, 0x80, 0x07, /* flags, hdr data len */
- 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */
+ 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */
0xff, 0xff /* stuffing */
};
const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
diff --git a/drivers/media/pci/cx18/cx23418.h b/drivers/media/pci/cx18/cx23418.h
index 901ed7fac10f..15205b662952 100644
--- a/drivers/media/pci/cx18/cx23418.h
+++ b/drivers/media/pci/cx18/cx23418.h
@@ -19,10 +19,10 @@
#include <media/drv-intf/cx2341x.h>
-#define MGR_CMD_MASK 0x40000000
+#define MGR_CMD_MASK 0x40000000
/* The MSB of the command code indicates that this is the completion of a
command */
-#define MGR_CMD_MASK_ACK (MGR_CMD_MASK | 0x80000000)
+#define MGR_CMD_MASK_ACK (MGR_CMD_MASK | 0x80000000)
/* Description: This command creates a new instance of a certain task
IN[0] - Task ID. This is one of the XPU_CMD_MASK_YYY where XPU is
@@ -30,26 +30,26 @@
OUT[0] - Task handle. This handle is passed along with commands to
dispatch to the right instance of the task
ReturnCode - One of the ERR_SYS_... */
-#define CX18_CREATE_TASK (MGR_CMD_MASK | 0x0001)
+#define CX18_CREATE_TASK (MGR_CMD_MASK | 0x0001)
/* Description: This command destroys an instance of a task
IN[0] - Task handle. Hanlde of the task to destroy
ReturnCode - One of the ERR_SYS_... */
-#define CX18_DESTROY_TASK (MGR_CMD_MASK | 0x0002)
+#define CX18_DESTROY_TASK (MGR_CMD_MASK | 0x0002)
/* All commands for CPU have the following mask set */
-#define CPU_CMD_MASK 0x20000000
-#define CPU_CMD_MASK_DEBUG (CPU_CMD_MASK | 0x00000000)
-#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000)
-#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000)
-#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000)
+#define CPU_CMD_MASK 0x20000000
+#define CPU_CMD_MASK_DEBUG (CPU_CMD_MASK | 0x00000000)
+#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000)
+#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000)
+#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000)
-#define EPU_CMD_MASK 0x02000000
-#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000)
-#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000)
+#define EPU_CMD_MASK 0x02000000
+#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000)
+#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000)
-#define APU_CMD_MASK 0x10000000
-#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000)
+#define APU_CMD_MASK 0x10000000
+#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000)
#define CX18_APU_ENCODING_METHOD_MPEG (0 << 28)
#define CX18_APU_ENCODING_METHOD_AC3 (1 << 28)
@@ -67,7 +67,7 @@
/* Description: Command APU to reset the AI
ReturnCode - ??? */
-#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05)
+#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05)
/* Description: This command indicates that a Memory Descriptor List has been
filled with the requested channel type
@@ -75,13 +75,13 @@
IN[1] - Offset of the MDL_ACK from the beginning of the local DDR.
IN[2] - Number of CNXT_MDL_ACK structures in the array pointed to by IN[1]
ReturnCode - One of the ERR_DE_... */
-#define CX18_EPU_DMA_DONE (EPU_CMD_MASK_DE | 0x0001)
+#define CX18_EPU_DMA_DONE (EPU_CMD_MASK_DE | 0x0001)
/* Something interesting happened
IN[0] - A value to log
IN[1] - An offset of a string in the MiniMe memory;
0/zero/NULL means "I have nothing to say" */
-#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003)
+#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003)
/* Reads memory/registers (32-bit)
IN[0] - Address
@@ -91,40 +91,40 @@
/* Description: This command starts streaming with the set channel type
IN[0] - Task handle. Handle of the task to start
ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_START (CPU_CMD_MASK_CAPTURE | 0x0002)
+#define CX18_CPU_CAPTURE_START (CPU_CMD_MASK_CAPTURE | 0x0002)
/* Description: This command stops streaming with the set channel type
IN[0] - Task handle. Handle of the task to stop
IN[1] - 0 = stop at end of GOP, 1 = stop at end of frame (MPEG only)
ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_STOP (CPU_CMD_MASK_CAPTURE | 0x0003)
+#define CX18_CPU_CAPTURE_STOP (CPU_CMD_MASK_CAPTURE | 0x0003)
/* Description: This command pauses streaming with the set channel type
IN[0] - Task handle. Handle of the task to pause
ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_PAUSE (CPU_CMD_MASK_CAPTURE | 0x0007)
+#define CX18_CPU_CAPTURE_PAUSE (CPU_CMD_MASK_CAPTURE | 0x0007)
/* Description: This command resumes streaming with the set channel type
IN[0] - Task handle. Handle of the task to resume
ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_CAPTURE_RESUME (CPU_CMD_MASK_CAPTURE | 0x0008)
-
-#define CAPTURE_CHANNEL_TYPE_NONE 0
-#define CAPTURE_CHANNEL_TYPE_MPEG 1
-#define CAPTURE_CHANNEL_TYPE_INDEX 2
-#define CAPTURE_CHANNEL_TYPE_YUV 3
-#define CAPTURE_CHANNEL_TYPE_PCM 4
-#define CAPTURE_CHANNEL_TYPE_VBI 5
+#define CX18_CPU_CAPTURE_RESUME (CPU_CMD_MASK_CAPTURE | 0x0008)
+
+#define CAPTURE_CHANNEL_TYPE_NONE 0
+#define CAPTURE_CHANNEL_TYPE_MPEG 1
+#define CAPTURE_CHANNEL_TYPE_INDEX 2
+#define CAPTURE_CHANNEL_TYPE_YUV 3
+#define CAPTURE_CHANNEL_TYPE_PCM 4
+#define CAPTURE_CHANNEL_TYPE_VBI 5
#define CAPTURE_CHANNEL_TYPE_SLICED_VBI 6
#define CAPTURE_CHANNEL_TYPE_TS 7
-#define CAPTURE_CHANNEL_TYPE_MAX 15
+#define CAPTURE_CHANNEL_TYPE_MAX 15
/* Description: This command sets the channel type. This can only be done
when stopped.
IN[0] - Task handle. Handle of the task to start
IN[1] - Channel Type. See Below.
ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_CHANNEL_TYPE (CPU_CMD_MASK_CAPTURE + 1)
+#define CX18_CPU_SET_CHANNEL_TYPE (CPU_CMD_MASK_CAPTURE + 1)
/* Description: Set stream output type
IN[0] - task handle. Handle of the task to start
@@ -140,7 +140,7 @@
IN[4] - reserved
IN[5] - frame rate, 0 - 29.97f/s, 1 - 25f/s
ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_IN (CPU_CMD_MASK_CAPTURE | 0x0004)
+#define CX18_CPU_SET_VIDEO_IN (CPU_CMD_MASK_CAPTURE | 0x0004)
/* Description: Set video frame rate
IN[0] - task handle. Handle of the task to start
@@ -149,7 +149,7 @@
IN[3] - video peak rate
IN[4] - system mux rate
ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_VIDEO_RATE (CPU_CMD_MASK_CAPTURE | 0x0005)
+#define CX18_CPU_SET_VIDEO_RATE (CPU_CMD_MASK_CAPTURE | 0x0005)
/* Description: Set video output resolution
IN[0] - task handle
@@ -166,7 +166,7 @@
3 = horizontal/vertical, 4 = diagonal
IN[3] - strength, temporal 0 - 31, spatial 0 - 15
ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_FILTER_PARAM (CPU_CMD_MASK_CAPTURE | 0x0009)
+#define CX18_CPU_SET_FILTER_PARAM (CPU_CMD_MASK_CAPTURE | 0x0009)
/* Description: This command set spatial filter type
IN[0] - Task handle.
@@ -174,7 +174,7 @@
3 = 2D H/V separable, 4 = 2D symmetric non-separable
IN[2] - chroma type: 0 - disable, 1 = 1D horizontal
ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C)
+#define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C)
/* Description: This command set coring levels for median filter
IN[0] - Task handle.
@@ -183,16 +183,16 @@
IN[3] - chroma_high
IN[4] - chroma_low
ReturnCode - One of the ERR_CAPTURE_... */
-#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E)
+#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E)
/* Description: This command set the picture type mask for index file
IN[0] - Task handle (ignored by firmware)
- IN[1] - 0 = disable index file output
+ IN[1] - 0 = disable index file output
1 = output I picture
2 = P picture
4 = B picture
other = illegal */
-#define CX18_CPU_SET_INDEXTABLE (CPU_CMD_MASK_CAPTURE | 0x0010)
+#define CX18_CPU_SET_INDEXTABLE (CPU_CMD_MASK_CAPTURE | 0x0010)
/* Description: Set audio parameters
IN[0] - task handle. Handle of the task to start
@@ -218,7 +218,7 @@
/* Description: Set stream output type
IN[0] - task handle. Handle of the task to start
IN[1] - subType
- SET_INITIAL_SCR 1
+ SET_INITIAL_SCR 1
SET_QUALITY_MODE 2
SET_VIM_PROTECT_MODE 3
SET_PTS_CORRECTION 4
@@ -311,7 +311,7 @@
bit 0: output user data, 1 - enable
bit 1: output private stream, 1 - enable
bit 2: mux option, 0 - in GOP, 1 - in picture
- bit[7:0] private stream ID
+ bit[7:0] private stream ID
IN[5] - insertion period while mux option is in picture
ReturnCode - VBI data offset */
#define CX18_CPU_SET_SLICED_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0020)
@@ -344,13 +344,13 @@
#define CX18_CPU_SET_VFC_PARAM (CPU_CMD_MASK_CAPTURE | 0x0023)
/* Below is the list of commands related to the data exchange */
-#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000)
+#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000)
/* Description: This command provides the physical base address of the local
DDR as viewed by EPU
IN[0] - Physical offset where EPU has the local DDR mapped
ReturnCode - One of the ERR_DE_... */
-#define CPU_CMD_DE_SetBase (CPU_CMD_MASK_DE | 0x0001)
+#define CPU_CMD_DE_SetBase (CPU_CMD_MASK_DE | 0x0001)
/* Description: This command provides the offsets in the device memory where
the 2 cx18_mdl_ack blocks reside
@@ -360,7 +360,7 @@
IN[2] - Offset of the second cx18_mdl_ack from the beginning of the
local DDR.
ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_SET_MDL_ACK (CPU_CMD_MASK_DE | 0x0002)
+#define CX18_CPU_DE_SET_MDL_ACK (CPU_CMD_MASK_DE | 0x0002)
/* Description: This command provides the offset to a Memory Descriptor List
IN[0] - Task handle. Handle of the task to start
@@ -369,13 +369,13 @@
IN[3] - Buffer ID
IN[4] - Total buffer length
ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_SET_MDL (CPU_CMD_MASK_DE | 0x0005)
+#define CX18_CPU_DE_SET_MDL (CPU_CMD_MASK_DE | 0x0005)
/* Description: This command requests return of all current Memory
Descriptor Lists to the driver
IN[0] - Task handle. Handle of the task to start
ReturnCode - One of the ERR_DE_... */
-#define CX18_CPU_DE_RELEASE_MDL (CPU_CMD_MASK_DE | 0x0006)
+#define CX18_CPU_DE_RELEASE_MDL (CPU_CMD_MASK_DE | 0x0006)
/* Description: This command signals the cpu that the dat buffer has been
consumed and ready for re-use.
diff --git a/drivers/media/pci/cx23885/Makefile b/drivers/media/pci/cx23885/Makefile
index b8bf7806124b..130f0aa29ac6 100644
--- a/drivers/media/pci/cx23885/Makefile
+++ b/drivers/media/pci/cx23885/Makefile
@@ -8,9 +8,7 @@ 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/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/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c
index 5c94e312cba3..70aec9bb7e95 100644
--- a/drivers/media/pci/cx23885/altera-ci.c
+++ b/drivers/media/pci/cx23885/altera-ci.c
@@ -51,10 +51,10 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <dvb_demux.h>
-#include <dvb_frontend.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
#include "altera-ci.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
/* FPGA regs */
#define NETUP_CI_INT_CTRL 0x00
diff --git a/drivers/media/pci/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c
index 5e8e134d81c2..19c005f4a57d 100644
--- a/drivers/media/pci/cx23885/cimax2.c
+++ b/drivers/media/pci/cx23885/cimax2.c
@@ -21,7 +21,7 @@
#include "cx23885.h"
#include "cimax2.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE 64
@@ -54,7 +54,7 @@
#define NETUP_CI_CTL 0x04
#define NETUP_CI_RD 1
-#define NETUP_IRQ_DETAM 0x1
+#define NETUP_IRQ_DETAM 0x1
#define NETUP_IRQ_IRQAM 0x4
static unsigned int ci_dbg;
diff --git a/drivers/media/pci/cx23885/cimax2.h b/drivers/media/pci/cx23885/cimax2.h
index 565e958f6f8d..167ffe205b5d 100644
--- a/drivers/media/pci/cx23885/cimax2.h
+++ b/drivers/media/pci/cx23885/cimax2.h
@@ -21,7 +21,7 @@
#ifndef CIMAX2_H
#define CIMAX2_H
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
extern int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
int slot, int addr);
diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c
index 28eab9c518c5..3622521431f5 100644
--- a/drivers/media/pci/cx23885/cx23885-cards.c
+++ b/drivers/media/pci/cx23885/cx23885-cards.c
@@ -1816,13 +1816,13 @@ int cx23885_ir_init(struct cx23885_dev *dev)
{
static struct v4l2_subdev_io_pin_config ir_rxtx_pin_cfg[] = {
{
- .flags = V4L2_SUBDEV_IO_PIN_INPUT,
+ .flags = BIT(V4L2_SUBDEV_IO_PIN_INPUT),
.pin = CX23885_PIN_IR_RX_GPIO19,
.function = CX23885_PAD_IR_RX,
.value = 0,
.strength = CX25840_PIN_DRIVE_MEDIUM,
}, {
- .flags = V4L2_SUBDEV_IO_PIN_OUTPUT,
+ .flags = BIT(V4L2_SUBDEV_IO_PIN_OUTPUT),
.pin = CX23885_PIN_IR_TX_GPIO20,
.function = CX23885_PAD_IR_TX,
.value = 0,
@@ -1833,7 +1833,7 @@ int cx23885_ir_init(struct cx23885_dev *dev)
static struct v4l2_subdev_io_pin_config ir_rx_pin_cfg[] = {
{
- .flags = V4L2_SUBDEV_IO_PIN_INPUT,
+ .flags = BIT(V4L2_SUBDEV_IO_PIN_INPUT),
.pin = CX23885_PIN_IR_RX_GPIO19,
.function = CX23885_PAD_IR_RX,
.value = 0,
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index e795ddeb7fe2..700422b538c0 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -27,7 +27,7 @@
#include <media/v4l2-common.h>
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
#include "s5h1409.h"
#include "s5h1411.h"
#include "mt2131.h"
@@ -1852,8 +1852,8 @@ static int dvb_register(struct cx23885_tsport *port)
/* attach frontend */
memset(&si2165_pdata, 0, sizeof(si2165_pdata));
si2165_pdata.fe = &fe0->dvb.frontend;
- si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL,
- si2165_pdata.ref_freq_Hz = 16000000,
+ si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL;
+ si2165_pdata.ref_freq_hz = 16000000;
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "si2165", I2C_NAME_SIZE);
info.addr = 0x64;
diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c
index 944b70831f12..0f4e54294bb7 100644
--- a/drivers/media/pci/cx23885/cx23885-input.c
+++ b/drivers/media/pci/cx23885/cx23885-input.c
@@ -340,14 +340,23 @@ int cx23885_input_init(struct cx23885_dev *dev)
kernel_ir->cx = dev;
kernel_ir->name = kasprintf(GFP_KERNEL, "cx23885 IR (%s)",
cx23885_boards[dev->board].name);
+ if (!kernel_ir->name) {
+ ret = -ENOMEM;
+ goto err_out_free;
+ }
+
kernel_ir->phys = kasprintf(GFP_KERNEL, "pci-%s/ir0",
pci_name(dev->pci));
+ if (!kernel_ir->phys) {
+ ret = -ENOMEM;
+ goto err_out_free_name;
+ }
/* input device */
rc = rc_allocate_device(RC_DRIVER_IR_RAW);
if (!rc) {
ret = -ENOMEM;
- goto err_out_free;
+ goto err_out_free_phys;
}
kernel_ir->rc = rc;
@@ -382,9 +391,11 @@ err_out_stop:
cx23885_input_ir_stop(dev);
dev->kernel_ir = NULL;
rc_free_device(rc);
-err_out_free:
+err_out_free_phys:
kfree(kernel_ir->phys);
+err_out_free_name:
kfree(kernel_ir->name);
+err_out_free:
kfree(kernel_ir);
return ret;
}
diff --git a/drivers/media/pci/cx23885/cx23885-video.c b/drivers/media/pci/cx23885/cx23885-video.c
index ecc580af0148..a03dcb662953 100644
--- a/drivers/media/pci/cx23885/cx23885-video.c
+++ b/drivers/media/pci/cx23885/cx23885-video.c
@@ -1146,7 +1146,7 @@ static struct video_device cx23885_vbi_template;
static struct video_device cx23885_video_template = {
.name = "cx23885-video",
.fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
+ .ioctl_ops = &video_ioctl_ops,
.tvnorms = CX23885_NORMS,
};
diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h
index 6aab713e0476..2a17209eb4f6 100644
--- a/drivers/media/pci/cx23885/cx23885.h
+++ b/drivers/media/pci/cx23885/cx23885.h
@@ -357,7 +357,7 @@ struct cx23885_audio_dev {
struct cx23885_dev {
atomic_t refcount;
- struct v4l2_device v4l2_dev;
+ struct v4l2_device v4l2_dev;
struct v4l2_ctrl_handler ctrl_handler;
/* pci stuff */
@@ -407,7 +407,7 @@ struct cx23885_dev {
unsigned int tuner_bus;
unsigned int radio_type;
unsigned char radio_addr;
- struct v4l2_subdev *sd_cx25840;
+ struct v4l2_subdev *sd_cx25840;
struct work_struct cx25840_work;
/* Infrared */
diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c
index 040323b0f945..00329f668b59 100644
--- a/drivers/media/pci/cx23885/cx23888-ir.c
+++ b/drivers/media/pci/cx23885/cx23888-ir.c
@@ -29,7 +29,7 @@ static unsigned int ir_888_debug;
module_param(ir_888_debug, int, 0644);
MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]");
-#define CX23888_IR_REG_BASE 0x170000
+#define CX23888_IR_REG_BASE 0x170000
/*
* These CX23888 register offsets have a straightforward one to one mapping
* to the CX23885 register offsets of 0x200 through 0x218
@@ -170,7 +170,7 @@ static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr,
* Rx and Tx Clock Divider register computations
*
* Note the largest clock divider value of 0xffff corresponds to:
- * (0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
+ * (0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns
* which fits in 21 bits, so we'll use unsigned int for time arguments.
*/
static inline u16 count_to_clock_divider(unsigned int d)
@@ -226,7 +226,7 @@ static inline unsigned int clock_divider_to_freq(unsigned int divider,
* Low Pass Filter register calculations
*
* Note the largest count value of 0xffff corresponds to:
- * 0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
+ * 0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns
* which fits in 21 bits, so we'll use unsigned int for time arguments.
*/
static inline u16 count_to_lpf_count(unsigned int d)
diff --git a/drivers/media/pci/cx25821/Makefile b/drivers/media/pci/cx25821/Makefile
index d14d65b1b042..94633d02ac7f 100644
--- a/drivers/media/pci/cx25821/Makefile
+++ b/drivers/media/pci/cx25821/Makefile
@@ -5,5 +5,3 @@ 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/i2c
diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c
index 2b34990e86f2..a45bf0331eeb 100644
--- a/drivers/media/pci/cx25821/cx25821-alsa.c
+++ b/drivers/media/pci/cx25821/cx25821-alsa.c
@@ -152,8 +152,8 @@ static int cx25821_alsa_dma_init(struct cx25821_audio_dev *chip, int nr_pages)
return -ENOMEM;
}
- dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
- (unsigned long)buf->vaddr,
+ dprintk(1, "vmalloc is at addr 0x%p, size=%d\n",
+ buf->vaddr,
nr_pages << PAGE_SHIFT);
memset(buf->vaddr, 0, nr_pages << PAGE_SHIFT);
diff --git a/drivers/media/pci/cx88/Makefile b/drivers/media/pci/cx88/Makefile
index 86646eee4e6b..d0f45d652d6e 100644
--- a/drivers/media/pci/cx88/Makefile
+++ b/drivers/media/pci/cx88/Makefile
@@ -10,8 +10,5 @@ obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o
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/i2c
ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/cx88/cx88-blackbird.c b/drivers/media/pci/cx88/cx88-blackbird.c
index e3101f04941c..0e0952e60795 100644
--- a/drivers/media/pci/cx88/cx88-blackbird.c
+++ b/drivers/media/pci/cx88/cx88-blackbird.c
@@ -805,8 +805,7 @@ static int vidioc_querycap(struct file *file, void *priv,
strcpy(cap->driver, "cx88_blackbird");
sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
- cx88_querycap(file, core, cap);
- return 0;
+ return cx88_querycap(file, core, cap);
}
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c
index 7d25ecd4404b..9be682cdb644 100644
--- a/drivers/media/pci/cx88/cx88-video.c
+++ b/drivers/media/pci/cx88/cx88-video.c
@@ -806,8 +806,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-void cx88_querycap(struct file *file, struct cx88_core *core,
- struct v4l2_capability *cap)
+int cx88_querycap(struct file *file, struct cx88_core *core,
+ struct v4l2_capability *cap)
{
struct video_device *vdev = video_devdata(file);
@@ -825,11 +825,14 @@ void cx88_querycap(struct file *file, struct cx88_core *core,
case VFL_TYPE_VBI:
cap->device_caps |= V4L2_CAP_VBI_CAPTURE;
break;
+ default:
+ return -EINVAL;
}
cap->capabilities = cap->device_caps | V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_VBI_CAPTURE | V4L2_CAP_DEVICE_CAPS;
if (core->board.radio.type == CX88_RADIO)
cap->capabilities |= V4L2_CAP_RADIO;
+ return 0;
}
EXPORT_SYMBOL(cx88_querycap);
@@ -841,8 +844,7 @@ static int vidioc_querycap(struct file *file, void *priv,
strcpy(cap->driver, "cx8800");
sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
- cx88_querycap(file, core, cap);
- return 0;
+ return cx88_querycap(file, core, cap);
}
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
diff --git a/drivers/media/pci/cx88/cx88.h b/drivers/media/pci/cx88/cx88.h
index 6777926f20f2..07a33f02fef4 100644
--- a/drivers/media/pci/cx88/cx88.h
+++ b/drivers/media/pci/cx88/cx88.h
@@ -734,7 +734,7 @@ int cx8802_start_dma(struct cx8802_dev *dev,
int cx88_enum_input(struct cx88_core *core, struct v4l2_input *i);
int cx88_set_freq(struct cx88_core *core, const struct v4l2_frequency *f);
int cx88_video_mux(struct cx88_core *core, unsigned int input);
-void cx88_querycap(struct file *file, struct cx88_core *core,
- struct v4l2_capability *cap);
+int cx88_querycap(struct file *file, struct cx88_core *core,
+ struct v4l2_capability *cap);
#endif
diff --git a/drivers/media/pci/ddbridge/Makefile b/drivers/media/pci/ddbridge/Makefile
index 7453b65104ff..f58fdec50eab 100644
--- a/drivers/media/pci/ddbridge/Makefile
+++ b/drivers/media/pci/ddbridge/Makefile
@@ -3,12 +3,11 @@
# Makefile for the ddbridge device driver
#
-ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-hw.o \
- ddbridge-i2c.o ddbridge-maxs8.o
+ddbridge-objs := ddbridge-main.o ddbridge-core.o ddbridge-ci.o \
+ ddbridge-hw.o ddbridge-i2c.o ddbridge-max.o
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
-ccflags-y += -Idrivers/media/dvb-core/
ccflags-y += -Idrivers/media/dvb-frontends/
ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/media/pci/ddbridge/ddbridge-ci.c b/drivers/media/pci/ddbridge/ddbridge-ci.c
new file mode 100644
index 000000000000..5828111487b0
--- /dev/null
+++ b/drivers/media/pci/ddbridge/ddbridge-ci.c
@@ -0,0 +1,359 @@
+/*
+ * ddbridge-ci.c: Digital Devices bridge CI (DuoFlex, CI Bridge) support
+ *
+ * Copyright (C) 2010-2017 Digital Devices GmbH
+ * Marcus Metzler <mocm@metzlerbros.de>
+ * Ralph Metzler <rjkm@metzlerbros.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "ddbridge.h"
+#include "ddbridge-regs.h"
+#include "ddbridge-ci.h"
+#include "ddbridge-io.h"
+#include "ddbridge-i2c.h"
+
+#include "cxd2099.h"
+
+/* Octopus CI internal CI interface */
+
+static int wait_ci_ready(struct ddb_ci *ci)
+{
+ u32 count = 10;
+
+ ndelay(500);
+ do {
+ if (ddbreadl(ci->port->dev,
+ CI_CONTROL(ci->nr)) & CI_READY)
+ break;
+ usleep_range(1, 2);
+ if ((--count) == 0)
+ return -1;
+ } while (1);
+ return 0;
+}
+
+static int read_attribute_mem(struct dvb_ca_en50221 *ca,
+ int slot, int address)
+{
+ struct ddb_ci *ci = ca->data;
+ u32 val, off = (address >> 1) & (CI_BUFFER_SIZE - 1);
+
+ if (address > CI_BUFFER_SIZE)
+ return -1;
+ ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address,
+ CI_DO_READ_ATTRIBUTES(ci->nr));
+ wait_ci_ready(ci);
+ val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off);
+ return val;
+}
+
+static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
+ int address, u8 value)
+{
+ struct ddb_ci *ci = ca->data;
+
+ ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
+ CI_DO_ATTRIBUTE_RW(ci->nr));
+ wait_ci_ready(ci);
+ return 0;
+}
+
+static int read_cam_control(struct dvb_ca_en50221 *ca,
+ int slot, u8 address)
+{
+ u32 count = 100;
+ struct ddb_ci *ci = ca->data;
+ u32 res;
+
+ ddbwritel(ci->port->dev, CI_READ_CMD | address,
+ CI_DO_IO_RW(ci->nr));
+ ndelay(500);
+ do {
+ res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr));
+ if (res & CI_READY)
+ break;
+ usleep_range(1, 2);
+ if ((--count) == 0)
+ return -1;
+ } while (1);
+ return 0xff & res;
+}
+
+static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
+ u8 address, u8 value)
+{
+ struct ddb_ci *ci = ca->data;
+
+ ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
+ CI_DO_IO_RW(ci->nr));
+ wait_ci_ready(ci);
+ return 0;
+}
+
+static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
+{
+ struct ddb_ci *ci = ca->data;
+
+ ddbwritel(ci->port->dev, CI_POWER_ON,
+ CI_CONTROL(ci->nr));
+ msleep(100);
+ ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM,
+ CI_CONTROL(ci->nr));
+ ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM,
+ CI_CONTROL(ci->nr));
+ usleep_range(20, 25);
+ ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON,
+ CI_CONTROL(ci->nr));
+ return 0;
+}
+
+static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
+{
+ struct ddb_ci *ci = ca->data;
+
+ ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr));
+ msleep(300);
+ return 0;
+}
+
+static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
+{
+ struct ddb_ci *ci = ca->data;
+ u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
+
+ ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE,
+ CI_CONTROL(ci->nr));
+ return 0;
+}
+
+static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+ struct ddb_ci *ci = ca->data;
+ u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
+ int stat = 0;
+
+ if (val & CI_CAM_DETECT)
+ stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
+ if (val & CI_CAM_READY)
+ stat |= DVB_CA_EN50221_POLL_CAM_READY;
+ return stat;
+}
+
+static struct dvb_ca_en50221 en_templ = {
+ .read_attribute_mem = read_attribute_mem,
+ .write_attribute_mem = write_attribute_mem,
+ .read_cam_control = read_cam_control,
+ .write_cam_control = write_cam_control,
+ .slot_reset = slot_reset,
+ .slot_shutdown = slot_shutdown,
+ .slot_ts_enable = slot_ts_enable,
+ .poll_slot_status = poll_slot_status,
+};
+
+static void ci_attach(struct ddb_port *port)
+{
+ struct ddb_ci *ci = NULL;
+
+ ci = kzalloc(sizeof(*ci), GFP_KERNEL);
+ if (!ci)
+ return;
+ memcpy(&ci->en, &en_templ, sizeof(en_templ));
+ ci->en.data = ci;
+ port->en = &ci->en;
+ ci->port = port;
+ ci->nr = port->nr - 2;
+}
+
+/* DuoFlex Dual CI support */
+
+static int write_creg(struct ddb_ci *ci, u8 data, u8 mask)
+{
+ struct i2c_adapter *i2c = &ci->port->i2c->adap;
+ u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+
+ ci->port->creg = (ci->port->creg & ~mask) | data;
+ return i2c_write_reg(i2c, adr, 0x02, ci->port->creg);
+}
+
+static int read_attribute_mem_xo2(struct dvb_ca_en50221 *ca,
+ int slot, int address)
+{
+ struct ddb_ci *ci = ca->data;
+ struct i2c_adapter *i2c = &ci->port->i2c->adap;
+ u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+ int res;
+ u8 val;
+
+ res = i2c_read_reg16(i2c, adr, 0x8000 | address, &val);
+ return res ? res : val;
+}
+
+static int write_attribute_mem_xo2(struct dvb_ca_en50221 *ca, int slot,
+ int address, u8 value)
+{
+ struct ddb_ci *ci = ca->data;
+ struct i2c_adapter *i2c = &ci->port->i2c->adap;
+ u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+
+ return i2c_write_reg16(i2c, adr, 0x8000 | address, value);
+}
+
+static int read_cam_control_xo2(struct dvb_ca_en50221 *ca,
+ int slot, u8 address)
+{
+ struct ddb_ci *ci = ca->data;
+ struct i2c_adapter *i2c = &ci->port->i2c->adap;
+ u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+ u8 val;
+ int res;
+
+ res = i2c_read_reg(i2c, adr, 0x20 | (address & 3), &val);
+ return res ? res : val;
+}
+
+static int write_cam_control_xo2(struct dvb_ca_en50221 *ca, int slot,
+ u8 address, u8 value)
+{
+ struct ddb_ci *ci = ca->data;
+ struct i2c_adapter *i2c = &ci->port->i2c->adap;
+ u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+
+ return i2c_write_reg(i2c, adr, 0x20 | (address & 3), value);
+}
+
+static int slot_reset_xo2(struct dvb_ca_en50221 *ca, int slot)
+{
+ struct ddb_ci *ci = ca->data;
+
+ dev_dbg(ci->port->dev->dev, "%s\n", __func__);
+ write_creg(ci, 0x01, 0x01);
+ write_creg(ci, 0x04, 0x04);
+ msleep(20);
+ write_creg(ci, 0x02, 0x02);
+ write_creg(ci, 0x00, 0x04);
+ write_creg(ci, 0x18, 0x18);
+ return 0;
+}
+
+static int slot_shutdown_xo2(struct dvb_ca_en50221 *ca, int slot)
+{
+ struct ddb_ci *ci = ca->data;
+
+ dev_dbg(ci->port->dev->dev, "%s\n", __func__);
+ write_creg(ci, 0x10, 0xff);
+ write_creg(ci, 0x08, 0x08);
+ return 0;
+}
+
+static int slot_ts_enable_xo2(struct dvb_ca_en50221 *ca, int slot)
+{
+ struct ddb_ci *ci = ca->data;
+
+ dev_dbg(ci->port->dev->dev, "%s\n", __func__);
+ write_creg(ci, 0x00, 0x10);
+ return 0;
+}
+
+static int poll_slot_status_xo2(struct dvb_ca_en50221 *ca, int slot, int open)
+{
+ struct ddb_ci *ci = ca->data;
+ struct i2c_adapter *i2c = &ci->port->i2c->adap;
+ u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
+ u8 val = 0;
+ int stat = 0;
+
+ i2c_read_reg(i2c, adr, 0x01, &val);
+
+ if (val & 2)
+ stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
+ if (val & 1)
+ stat |= DVB_CA_EN50221_POLL_CAM_READY;
+ return stat;
+}
+
+static struct dvb_ca_en50221 en_xo2_templ = {
+ .read_attribute_mem = read_attribute_mem_xo2,
+ .write_attribute_mem = write_attribute_mem_xo2,
+ .read_cam_control = read_cam_control_xo2,
+ .write_cam_control = write_cam_control_xo2,
+ .slot_reset = slot_reset_xo2,
+ .slot_shutdown = slot_shutdown_xo2,
+ .slot_ts_enable = slot_ts_enable_xo2,
+ .poll_slot_status = poll_slot_status_xo2,
+};
+
+static void ci_xo2_attach(struct ddb_port *port)
+{
+ struct ddb_ci *ci;
+
+ ci = kzalloc(sizeof(*ci), GFP_KERNEL);
+ if (!ci)
+ return;
+ memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ));
+ ci->en.data = ci;
+ port->en = &ci->en;
+ ci->port = port;
+ ci->nr = port->nr - 2;
+ ci->port->creg = 0;
+ write_creg(ci, 0x10, 0xff);
+ write_creg(ci, 0x08, 0x08);
+}
+
+static struct cxd2099_cfg cxd_cfg = {
+ .bitrate = 72000,
+ .adr = 0x40,
+ .polarity = 1,
+ .clock_mode = 1,
+ .max_i2c = 512,
+};
+
+int ddb_ci_attach(struct ddb_port *port, u32 bitrate)
+{
+ switch (port->type) {
+ case DDB_CI_EXTERNAL_SONY:
+ cxd_cfg.bitrate = bitrate;
+ port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap);
+ if (!port->en)
+ return -ENODEV;
+ break;
+
+ case DDB_CI_EXTERNAL_XO2:
+ case DDB_CI_EXTERNAL_XO2_B:
+ ci_xo2_attach(port);
+ if (!port->en)
+ return -ENODEV;
+ break;
+
+ case DDB_CI_INTERNAL:
+ ci_attach(port);
+ if (!port->en)
+ return -ENODEV;
+ break;
+ }
+
+ dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1);
+ return 0;
+}
+
+void ddb_ci_detach(struct ddb_port *port)
+{
+ if (port->dvb[0].dev)
+ dvb_unregister_device(port->dvb[0].dev);
+ if (port->en) {
+ dvb_ca_en50221_release(port->en);
+ kfree(port->en->data);
+ port->en = NULL;
+ }
+}
diff --git a/drivers/media/pci/ddbridge/ddbridge-ci.h b/drivers/media/pci/ddbridge/ddbridge-ci.h
new file mode 100644
index 000000000000..35a39182dd83
--- /dev/null
+++ b/drivers/media/pci/ddbridge/ddbridge-ci.h
@@ -0,0 +1,31 @@
+/*
+ * ddbridge-ci.h: Digital Devices bridge CI (DuoFlex, CI Bridge) support
+ *
+ * Copyright (C) 2010-2017 Digital Devices GmbH
+ * Marcus Metzler <mocm@metzlerbros.de>
+ * Ralph Metzler <rjkm@metzlerbros.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 only, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * To obtain the license, point your browser to
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __DDBRIDGE_CI_H__
+#define __DDBRIDGE_CI_H__
+
+#include "ddbridge.h"
+
+/******************************************************************************/
+
+int ddb_ci_attach(struct ddb_port *port, u32 bitrate);
+void ddb_ci_detach(struct ddb_port *port);
+
+#endif /* __DDBRIDGE_CI_H__ */
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c
index 09a25d6c2cd1..42b42824382c 100644
--- a/drivers/media/pci/ddbridge/ddbridge-core.c
+++ b/drivers/media/pci/ddbridge/ddbridge-core.c
@@ -37,7 +37,8 @@
#include "ddbridge.h"
#include "ddbridge-i2c.h"
#include "ddbridge-regs.h"
-#include "ddbridge-maxs8.h"
+#include "ddbridge-max.h"
+#include "ddbridge-ci.h"
#include "ddbridge-io.h"
#include "tda18271c2dd.h"
@@ -112,7 +113,6 @@ static void ddb_set_dma_tables(struct ddb *dev)
}
}
-
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
@@ -210,8 +210,9 @@ static int ddb_redirect(u32 i, u32 p)
if (input->redi) {
input2->redi = input->redi;
input->redi = NULL;
- } else
+ } else {
input2->redi = input;
+ }
}
input->redo = port->output;
port->output->redi = input;
@@ -357,9 +358,9 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
max_bitrate = 0;
gap = 0;
if (bitrate != 72000) {
- if (bitrate >= 96000)
+ if (bitrate >= 96000) {
*con |= 0x800;
- else {
+ } else {
*con |= 0x1000;
nco = (bitrate * 8192 + 71999)
/ 72000;
@@ -506,7 +507,6 @@ static void ddb_input_start(struct ddb_input *input)
}
}
-
static void ddb_input_start_all(struct ddb_input *input)
{
struct ddb_input *i = input;
@@ -572,7 +572,7 @@ static ssize_t ddb_output_write(struct ddb_output *output,
while (left) {
len = output->dma->size - output->dma->coff;
if ((((output->dma->cbuf + 1) % output->dma->num) == idx) &&
- (off == 0)) {
+ off == 0) {
if (len <= 188)
break;
len -= 188;
@@ -593,7 +593,8 @@ static ssize_t ddb_output_write(struct ddb_output *output,
buf, len))
return -EIO;
if (alt_dma)
- dma_sync_single_for_device(dev->dev,
+ dma_sync_single_for_device(
+ dev->dev,
output->dma->pbuf[output->dma->cbuf],
output->dma->size, DMA_TO_DEVICE);
left -= len;
@@ -632,7 +633,7 @@ static u32 ddb_input_avail(struct ddb_input *input)
}
static ssize_t ddb_input_read(struct ddb_input *input,
- __user u8 *buf, size_t count)
+ __user u8 *buf, size_t count)
{
struct ddb *dev = input->port->dev;
u32 left = count;
@@ -648,7 +649,8 @@ static ssize_t ddb_input_read(struct ddb_input *input,
if (free > left)
free = left;
if (alt_dma)
- dma_sync_single_for_cpu(dev->dev,
+ dma_sync_single_for_cpu(
+ dev->dev,
input->dma->pbuf[input->dma->cbuf],
input->dma->size, DMA_FROM_DEVICE);
ret = copy_to_user(buf, input->dma->vbuf[input->dma->cbuf] +
@@ -792,8 +794,10 @@ static int ts_open(struct inode *inode, struct file *file)
} else if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
if (!output)
return -EINVAL;
- } else
+ } else {
return -EINVAL;
+ }
+
err = dvb_generic_open(inode, file);
if (err < 0)
return err;
@@ -822,7 +826,6 @@ static struct dvb_device dvbdev_ci = {
.fops = &ci_fops,
};
-
/****************************************************************************/
/****************************************************************************/
@@ -848,21 +851,20 @@ static int demod_attach_drxk(struct ddb_input *input)
struct i2c_adapter *i2c = &input->port->i2c->adap;
struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
struct device *dev = input->port->dev->dev;
- struct dvb_frontend *fe;
struct drxk_config config;
memset(&config, 0, sizeof(config));
config.adr = 0x29 + (input->nr & 1);
config.microcode_name = "drxk_a3.mc";
- fe = dvb->fe = dvb_attach(drxk_attach, &config, i2c);
- if (!fe) {
+ dvb->fe = dvb_attach(drxk_attach, &config, i2c);
+ if (!dvb->fe) {
dev_err(dev, "No DRXK found!\n");
return -ENODEV;
}
- fe->sec_priv = input;
- dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl;
- fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
+ dvb->fe->sec_priv = input;
+ dvb->i2c_gate_ctrl = dvb->fe->ops.i2c_gate_ctrl;
+ dvb->fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
return 0;
}
@@ -912,19 +914,18 @@ static int demod_attach_stv0367(struct ddb_input *input)
struct i2c_adapter *i2c = &input->port->i2c->adap;
struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
struct device *dev = input->port->dev->dev;
- struct dvb_frontend *fe;
/* attach frontend */
- fe = dvb->fe = dvb_attach(stv0367ddb_attach,
- &ddb_stv0367_config[(input->nr & 1)], i2c);
+ dvb->fe = dvb_attach(stv0367ddb_attach,
+ &ddb_stv0367_config[(input->nr & 1)], i2c);
if (!dvb->fe) {
dev_err(dev, "No stv0367 found!\n");
return -ENODEV;
}
- fe->sec_priv = input;
- dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl;
- fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
+ dvb->fe->sec_priv = input;
+ dvb->i2c_gate_ctrl = dvb->fe->ops.i2c_gate_ctrl;
+ dvb->fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
return 0;
}
@@ -956,7 +957,6 @@ static int demod_attach_cxd28xx(struct ddb_input *input, int par, int osc24)
struct i2c_adapter *i2c = &input->port->i2c->adap;
struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
struct device *dev = input->port->dev->dev;
- struct dvb_frontend *fe;
struct cxd2841er_config cfg;
/* the cxd2841er driver expects 8bit/shifted I2C addresses */
@@ -971,15 +971,15 @@ static int demod_attach_cxd28xx(struct ddb_input *input, int par, int osc24)
cfg.flags |= CXD2841ER_TS_SERIAL;
/* attach frontend */
- fe = dvb->fe = dvb_attach(cxd2841er_attach_t_c, &cfg, i2c);
+ dvb->fe = dvb_attach(cxd2841er_attach_t_c, &cfg, i2c);
if (!dvb->fe) {
dev_err(dev, "No cxd2837/38/43/54 found!\n");
return -ENODEV;
}
- fe->sec_priv = input;
- dvb->i2c_gate_ctrl = fe->ops.i2c_gate_ctrl;
- fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
+ dvb->fe->sec_priv = input;
+ dvb->i2c_gate_ctrl = dvb->fe->ops.i2c_gate_ctrl;
+ dvb->fe->ops.i2c_gate_ctrl = locked_gate_ctrl;
return 0;
}
@@ -1020,7 +1020,7 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype)
/* perform tuner init/attach */
client = i2c_new_device(adapter, &board_info);
- if (client == NULL || client->dev.driver == NULL)
+ if (!client || !client->dev.driver)
goto err;
if (!try_module_get(client->dev.driver->owner)) {
@@ -1032,7 +1032,7 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype)
return 0;
err:
- dev_notice(dev, "TDA18212 tuner not found. Device is not fully operational.\n");
+ dev_err(dev, "TDA18212 tuner not found. Device is not fully operational.\n");
return -ENODEV;
}
@@ -1114,6 +1114,7 @@ static int demod_attach_stv0900(struct ddb_input *input, int type)
0, (input->nr & 1) ?
(0x09 - type) : (0x0b - type))) {
dev_err(dev, "No LNBH24 found!\n");
+ dvb_frontend_detach(dvb->fe);
return -ENODEV;
}
return 0;
@@ -1135,7 +1136,7 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type)
return -ENODEV;
}
dev_info(dev, "attach tuner input %d adr %02x\n",
- input->nr, tunerconf->addr);
+ input->nr, tunerconf->addr);
feconf->tuner_init = ctl->tuner_init;
feconf->tuner_sleep = ctl->tuner_sleep;
@@ -1196,6 +1197,7 @@ static int demod_attach_stv0910(struct ddb_input *input, int type)
lnbcfg.i2c_address = (((input->nr & 1) ? 0x09 : 0x08) << 1);
if (!dvb_attach(lnbh25_attach, dvb->fe, &lnbcfg, i2c)) {
dev_err(dev, "No LNBH25 found!\n");
+ dvb_frontend_detach(dvb->fe);
return -ENODEV;
}
}
@@ -1261,19 +1263,22 @@ static void dvb_input_detach(struct ddb_input *input)
dvb_unregister_frontend(dvb->fe);
/* fallthrough */
case 0x30:
- if (dvb->fe2)
- dvb_frontend_detach(dvb->fe2);
- if (dvb->fe)
- dvb_frontend_detach(dvb->fe);
- dvb->fe = dvb->fe2 = NULL;
- /* fallthrough */
- case 0x20:
client = dvb->i2c_client[0];
if (client) {
module_put(client->dev.driver->owner);
i2c_unregister_device(client);
+ dvb->i2c_client[0] = NULL;
+ client = NULL;
}
+ if (dvb->fe2)
+ dvb_frontend_detach(dvb->fe2);
+ if (dvb->fe)
+ dvb_frontend_detach(dvb->fe);
+ dvb->fe = NULL;
+ dvb->fe2 = NULL;
+ /* fallthrough */
+ case 0x20:
dvb_net_release(&dvb->dvbnet);
/* fallthrough */
case 0x12:
@@ -1409,7 +1414,8 @@ static int dvb_input_attach(struct ddb_input *input)
DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
dvbdemux->start_feed = start_feed;
dvbdemux->stop_feed = stop_feed;
- dvbdemux->filternum = dvbdemux->feednum = 256;
+ dvbdemux->filternum = 256;
+ dvbdemux->feednum = 256;
ret = dvb_dmx_init(dvbdemux);
if (ret < 0)
return ret;
@@ -1419,7 +1425,7 @@ static int dvb_input_attach(struct ddb_input *input)
dvb->dmxdev.demux = &dvbdemux->dmx;
ret = dvb_dmxdev_init(&dvb->dmxdev, adap);
if (ret < 0)
- return ret;
+ goto err_detach;
dvb->attached = 0x11;
dvb->mem_frontend.source = DMX_MEMORY_FE;
@@ -1428,66 +1434,62 @@ static int dvb_input_attach(struct ddb_input *input)
dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->hw_frontend);
ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &dvb->hw_frontend);
if (ret < 0)
- return ret;
+ goto err_detach;
dvb->attached = 0x12;
ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux);
if (ret < 0)
- return ret;
+ goto err_detach;
dvb->attached = 0x20;
- dvb->fe = dvb->fe2 = NULL;
+ dvb->fe = NULL;
+ dvb->fe2 = NULL;
switch (port->type) {
case DDB_TUNER_MXL5XX:
- if (fe_attach_mxl5xx(input) < 0)
- return -ENODEV;
+ if (ddb_fe_attach_mxl5xx(input) < 0)
+ goto err_detach;
break;
case DDB_TUNER_DVBS_ST:
if (demod_attach_stv0900(input, 0) < 0)
- return -ENODEV;
+ goto err_detach;
if (tuner_attach_stv6110(input, 0) < 0)
- return -ENODEV;
+ goto err_tuner;
break;
case DDB_TUNER_DVBS_ST_AA:
if (demod_attach_stv0900(input, 1) < 0)
- return -ENODEV;
+ goto err_detach;
if (tuner_attach_stv6110(input, 1) < 0)
- return -ENODEV;
+ goto err_tuner;
break;
case DDB_TUNER_DVBS_STV0910:
if (demod_attach_stv0910(input, 0) < 0)
- return -ENODEV;
+ goto err_detach;
if (tuner_attach_stv6111(input, 0) < 0)
- return -ENODEV;
+ goto err_tuner;
break;
case DDB_TUNER_DVBS_STV0910_PR:
if (demod_attach_stv0910(input, 1) < 0)
- return -ENODEV;
+ goto err_detach;
if (tuner_attach_stv6111(input, 1) < 0)
- return -ENODEV;
+ goto err_tuner;
break;
case DDB_TUNER_DVBS_STV0910_P:
if (demod_attach_stv0910(input, 0) < 0)
- return -ENODEV;
+ goto err_detach;
if (tuner_attach_stv6111(input, 1) < 0)
- return -ENODEV;
+ goto err_tuner;
break;
case DDB_TUNER_DVBCT_TR:
if (demod_attach_drxk(input) < 0)
- return -ENODEV;
+ goto err_detach;
if (tuner_attach_tda18271(input) < 0)
- return -ENODEV;
+ goto err_tuner;
break;
case DDB_TUNER_DVBCT_ST:
if (demod_attach_stv0367(input) < 0)
- return -ENODEV;
- if (tuner_attach_tda18212(input, port->type) < 0) {
- if (dvb->fe2)
- dvb_frontend_detach(dvb->fe2);
- if (dvb->fe)
- dvb_frontend_detach(dvb->fe);
- return -ENODEV;
- }
+ goto err_detach;
+ if (tuner_attach_tda18212(input, port->type) < 0)
+ goto err_tuner;
break;
case DDB_TUNER_DVBC2T2I_SONY_P:
if (input->port->dev->link[input->port->lnr].info->ts_quirks &
@@ -1505,14 +1507,9 @@ static int dvb_input_attach(struct ddb_input *input)
else
par = 1;
if (demod_attach_cxd28xx(input, par, osc24) < 0)
- return -ENODEV;
- if (tuner_attach_tda18212(input, port->type) < 0) {
- if (dvb->fe2)
- dvb_frontend_detach(dvb->fe2);
- if (dvb->fe)
- dvb_frontend_detach(dvb->fe);
- return -ENODEV;
- }
+ goto err_detach;
+ if (tuner_attach_tda18212(input, port->type) < 0)
+ goto err_tuner;
break;
case DDB_TUNER_DVBC2T2I_SONY:
osc24 = 1;
@@ -1521,14 +1518,9 @@ static int dvb_input_attach(struct ddb_input *input)
case DDB_TUNER_DVBC2T2_SONY:
case DDB_TUNER_ISDBT_SONY:
if (demod_attach_cxd28xx(input, 0, osc24) < 0)
- return -ENODEV;
- if (tuner_attach_tda18212(input, port->type) < 0) {
- if (dvb->fe2)
- dvb_frontend_detach(dvb->fe2);
- if (dvb->fe)
- dvb_frontend_detach(dvb->fe);
- return -ENODEV;
- }
+ goto err_detach;
+ if (tuner_attach_tda18212(input, port->type) < 0)
+ goto err_tuner;
break;
default:
return 0;
@@ -1537,11 +1529,13 @@ static int dvb_input_attach(struct ddb_input *input)
if (dvb->fe) {
if (dvb_register_frontend(adap, dvb->fe) < 0)
- return -ENODEV;
+ goto err_detach;
if (dvb->fe2) {
- if (dvb_register_frontend(adap, dvb->fe2) < 0)
- return -ENODEV;
+ if (dvb_register_frontend(adap, dvb->fe2) < 0) {
+ dvb_unregister_frontend(dvb->fe);
+ goto err_detach;
+ }
dvb->fe2->tuner_priv = dvb->fe->tuner_priv;
memcpy(&dvb->fe2->ops.tuner_ops,
&dvb->fe->ops.tuner_ops,
@@ -1551,6 +1545,22 @@ static int dvb_input_attach(struct ddb_input *input)
dvb->attached = 0x31;
return 0;
+
+err_tuner:
+ dev_err(port->dev->dev, "tuner attach failed!\n");
+
+ if (dvb->fe2)
+ dvb_frontend_detach(dvb->fe2);
+ if (dvb->fe)
+ dvb_frontend_detach(dvb->fe);
+err_detach:
+ dvb_input_detach(input);
+
+ /* return error from ret if set */
+ if (ret < 0)
+ return ret;
+
+ return -ENODEV;
}
static int port_has_encti(struct ddb_port *port)
@@ -1703,11 +1713,11 @@ static int init_xo2_ci(struct ddb_port *port)
if (data[0] > 1) {
dev_info(dev->dev, "Port %d: invalid XO2 CI %02x\n",
- port->nr, data[0]);
+ port->nr, data[0]);
return -1;
}
dev_info(dev->dev, "Port %d: DuoFlex CI %u.%u\n",
- port->nr, data[0], data[1]);
+ port->nr, data[0], data[1]);
i2c_read_reg(i2c, 0x10, 0x08, &val);
if (val != 0) {
@@ -1718,7 +1728,6 @@ static int init_xo2_ci(struct ddb_port *port)
i2c_write_reg(i2c, 0x10, 0x08, 3);
usleep_range(2000, 3000);
-
/* speed: 0=55,1=75,2=90,3=104 MBit/s */
i2c_write_reg(i2c, 0x10, 0x09, 1);
@@ -1821,7 +1830,7 @@ static void ddb_port_probe(struct ddb_port *port)
port->i2c->regs + I2C_TIMING);
} else {
dev_info(dev->dev, "Port %d: Uninitialized DuoFlex\n",
- port->nr);
+ port->nr);
return;
}
} else if (port_has_xo2(port, &type, &id)) {
@@ -1912,338 +1921,10 @@ static void ddb_port_probe(struct ddb_port *port)
}
}
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-static int wait_ci_ready(struct ddb_ci *ci)
-{
- u32 count = 10;
-
- ndelay(500);
- do {
- if (ddbreadl(ci->port->dev,
- CI_CONTROL(ci->nr)) & CI_READY)
- break;
- usleep_range(1, 2);
- if ((--count) == 0)
- return -1;
- } while (1);
- return 0;
-}
-
-static int read_attribute_mem(struct dvb_ca_en50221 *ca,
- int slot, int address)
-{
- struct ddb_ci *ci = ca->data;
- u32 val, off = (address >> 1) & (CI_BUFFER_SIZE - 1);
-
- if (address > CI_BUFFER_SIZE)
- return -1;
- ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address,
- CI_DO_READ_ATTRIBUTES(ci->nr));
- wait_ci_ready(ci);
- val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off);
- return val;
-}
-
-static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
- int address, u8 value)
-{
- struct ddb_ci *ci = ca->data;
-
- ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
- CI_DO_ATTRIBUTE_RW(ci->nr));
- wait_ci_ready(ci);
- return 0;
-}
-
-static int read_cam_control(struct dvb_ca_en50221 *ca,
- int slot, u8 address)
-{
- u32 count = 100;
- struct ddb_ci *ci = ca->data;
- u32 res;
-
- ddbwritel(ci->port->dev, CI_READ_CMD | address,
- CI_DO_IO_RW(ci->nr));
- ndelay(500);
- do {
- res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr));
- if (res & CI_READY)
- break;
- usleep_range(1, 2);
- if ((--count) == 0)
- return -1;
- } while (1);
- return 0xff & res;
-}
-
-static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
- u8 address, u8 value)
-{
- struct ddb_ci *ci = ca->data;
-
- ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
- CI_DO_IO_RW(ci->nr));
- wait_ci_ready(ci);
- return 0;
-}
-
-static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
-{
- struct ddb_ci *ci = ca->data;
-
- ddbwritel(ci->port->dev, CI_POWER_ON,
- CI_CONTROL(ci->nr));
- msleep(100);
- ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM,
- CI_CONTROL(ci->nr));
- ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM,
- CI_CONTROL(ci->nr));
- udelay(20);
- ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON,
- CI_CONTROL(ci->nr));
- return 0;
-}
-
-static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
-{
- struct ddb_ci *ci = ca->data;
-
- ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr));
- msleep(300);
- return 0;
-}
-
-static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
-{
- struct ddb_ci *ci = ca->data;
- u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
-
- ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE,
- CI_CONTROL(ci->nr));
- return 0;
-}
-
-static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
-{
- struct ddb_ci *ci = ca->data;
- u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
- int stat = 0;
-
- if (val & CI_CAM_DETECT)
- stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
- if (val & CI_CAM_READY)
- stat |= DVB_CA_EN50221_POLL_CAM_READY;
- return stat;
-}
-
-static struct dvb_ca_en50221 en_templ = {
- .read_attribute_mem = read_attribute_mem,
- .write_attribute_mem = write_attribute_mem,
- .read_cam_control = read_cam_control,
- .write_cam_control = write_cam_control,
- .slot_reset = slot_reset,
- .slot_shutdown = slot_shutdown,
- .slot_ts_enable = slot_ts_enable,
- .poll_slot_status = poll_slot_status,
-};
-
-static void ci_attach(struct ddb_port *port)
-{
- struct ddb_ci *ci = NULL;
-
- ci = kzalloc(sizeof(*ci), GFP_KERNEL);
- if (!ci)
- return;
- memcpy(&ci->en, &en_templ, sizeof(en_templ));
- ci->en.data = ci;
- port->en = &ci->en;
- ci->port = port;
- ci->nr = port->nr - 2;
-}
-
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
-static int write_creg(struct ddb_ci *ci, u8 data, u8 mask)
-{
- struct i2c_adapter *i2c = &ci->port->i2c->adap;
- u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
-
- ci->port->creg = (ci->port->creg & ~mask) | data;
- return i2c_write_reg(i2c, adr, 0x02, ci->port->creg);
-}
-
-static int read_attribute_mem_xo2(struct dvb_ca_en50221 *ca,
- int slot, int address)
-{
- struct ddb_ci *ci = ca->data;
- struct i2c_adapter *i2c = &ci->port->i2c->adap;
- u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
- int res;
- u8 val;
-
- res = i2c_read_reg16(i2c, adr, 0x8000 | address, &val);
- return res ? res : val;
-}
-
-static int write_attribute_mem_xo2(struct dvb_ca_en50221 *ca, int slot,
- int address, u8 value)
-{
- struct ddb_ci *ci = ca->data;
- struct i2c_adapter *i2c = &ci->port->i2c->adap;
- u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
-
- return i2c_write_reg16(i2c, adr, 0x8000 | address, value);
-}
-
-static int read_cam_control_xo2(struct dvb_ca_en50221 *ca,
- int slot, u8 address)
-{
- struct ddb_ci *ci = ca->data;
- struct i2c_adapter *i2c = &ci->port->i2c->adap;
- u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
- u8 val;
- int res;
-
- res = i2c_read_reg(i2c, adr, 0x20 | (address & 3), &val);
- return res ? res : val;
-}
-
-static int write_cam_control_xo2(struct dvb_ca_en50221 *ca, int slot,
- u8 address, u8 value)
-{
- struct ddb_ci *ci = ca->data;
- struct i2c_adapter *i2c = &ci->port->i2c->adap;
- u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
-
- return i2c_write_reg(i2c, adr, 0x20 | (address & 3), value);
-}
-
-static int slot_reset_xo2(struct dvb_ca_en50221 *ca, int slot)
-{
- struct ddb_ci *ci = ca->data;
-
- dev_dbg(ci->port->dev->dev, "%s\n", __func__);
- write_creg(ci, 0x01, 0x01);
- write_creg(ci, 0x04, 0x04);
- msleep(20);
- write_creg(ci, 0x02, 0x02);
- write_creg(ci, 0x00, 0x04);
- write_creg(ci, 0x18, 0x18);
- return 0;
-}
-
-static int slot_shutdown_xo2(struct dvb_ca_en50221 *ca, int slot)
-{
- struct ddb_ci *ci = ca->data;
-
- dev_dbg(ci->port->dev->dev, "%s\n", __func__);
- write_creg(ci, 0x10, 0xff);
- write_creg(ci, 0x08, 0x08);
- return 0;
-}
-
-static int slot_ts_enable_xo2(struct dvb_ca_en50221 *ca, int slot)
-{
- struct ddb_ci *ci = ca->data;
-
- dev_info(ci->port->dev->dev, "%s\n", __func__);
- write_creg(ci, 0x00, 0x10);
- return 0;
-}
-
-static int poll_slot_status_xo2(struct dvb_ca_en50221 *ca, int slot, int open)
-{
- struct ddb_ci *ci = ca->data;
- struct i2c_adapter *i2c = &ci->port->i2c->adap;
- u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
- u8 val = 0;
- int stat = 0;
-
- i2c_read_reg(i2c, adr, 0x01, &val);
-
- if (val & 2)
- stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
- if (val & 1)
- stat |= DVB_CA_EN50221_POLL_CAM_READY;
- return stat;
-}
-
-static struct dvb_ca_en50221 en_xo2_templ = {
- .read_attribute_mem = read_attribute_mem_xo2,
- .write_attribute_mem = write_attribute_mem_xo2,
- .read_cam_control = read_cam_control_xo2,
- .write_cam_control = write_cam_control_xo2,
- .slot_reset = slot_reset_xo2,
- .slot_shutdown = slot_shutdown_xo2,
- .slot_ts_enable = slot_ts_enable_xo2,
- .poll_slot_status = poll_slot_status_xo2,
-};
-
-static void ci_xo2_attach(struct ddb_port *port)
-{
- struct ddb_ci *ci;
-
- ci = kzalloc(sizeof(*ci), GFP_KERNEL);
- if (!ci)
- return;
- memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ));
- ci->en.data = ci;
- port->en = &ci->en;
- ci->port = port;
- ci->nr = port->nr - 2;
- ci->port->creg = 0;
- write_creg(ci, 0x10, 0xff);
- write_creg(ci, 0x08, 0x08);
-}
-
-/****************************************************************************/
-/****************************************************************************/
-/****************************************************************************/
-
-static struct cxd2099_cfg cxd_cfg = {
- .bitrate = 72000,
- .adr = 0x40,
- .polarity = 1,
- .clock_mode = 1,
- .max_i2c = 512,
-};
-
-static int ddb_ci_attach(struct ddb_port *port)
-{
- switch (port->type) {
- case DDB_CI_EXTERNAL_SONY:
- cxd_cfg.bitrate = ci_bitrate;
- port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap);
- if (!port->en)
- return -ENODEV;
- dvb_ca_en50221_init(port->dvb[0].adap,
- port->en, 0, 1);
- break;
-
- case DDB_CI_EXTERNAL_XO2:
- case DDB_CI_EXTERNAL_XO2_B:
- ci_xo2_attach(port);
- if (!port->en)
- return -ENODEV;
- dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1);
- break;
-
- case DDB_CI_INTERNAL:
- ci_attach(port);
- if (!port->en)
- return -ENODEV;
- dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1);
- break;
- }
- return 0;
-}
-
static int ddb_port_attach(struct ddb_port *port)
{
int ret = 0;
@@ -2254,20 +1935,22 @@ static int ddb_port_attach(struct ddb_port *port)
if (ret < 0)
break;
ret = dvb_input_attach(port->input[1]);
- if (ret < 0)
+ if (ret < 0) {
+ dvb_input_detach(port->input[0]);
break;
+ }
port->input[0]->redi = port->input[0];
port->input[1]->redi = port->input[1];
break;
case DDB_PORT_CI:
- ret = ddb_ci_attach(port);
+ ret = ddb_ci_attach(port, ci_bitrate);
if (ret < 0)
break;
/* fall-through */
case DDB_PORT_LOOP:
ret = dvb_register_device(port->dvb[0].adap,
&port->dvb[0].dev,
- &dvbdev_ci, (void *) port->output,
+ &dvbdev_ci, (void *)port->output,
DVB_DEVICE_SEC, 0);
break;
default:
@@ -2281,7 +1964,7 @@ static int ddb_port_attach(struct ddb_port *port)
int ddb_ports_attach(struct ddb *dev)
{
- int i, ret = 0;
+ int i, numports, err_ports = 0, ret = 0;
struct ddb_port *port;
if (dev->port_num) {
@@ -2291,11 +1974,31 @@ int ddb_ports_attach(struct ddb *dev)
return ret;
}
}
+
+ numports = dev->port_num;
+
for (i = 0; i < dev->port_num; i++) {
port = &dev->port[i];
- ret = ddb_port_attach(port);
+ if (port->class != DDB_PORT_NONE) {
+ ret = ddb_port_attach(port);
+ if (ret)
+ err_ports++;
+ } else {
+ numports--;
+ }
}
- return ret;
+
+ if (err_ports) {
+ if (err_ports == numports) {
+ dev_err(dev->dev, "All connected ports failed to initialise!\n");
+ return -ENODEV;
+ }
+
+ dev_warn(dev->dev, "%d of %d connected ports failed to initialise!\n",
+ err_ports, numports);
+ }
+
+ return 0;
}
void ddb_ports_detach(struct ddb *dev)
@@ -2308,25 +2011,18 @@ void ddb_ports_detach(struct ddb *dev)
switch (port->class) {
case DDB_PORT_TUNER:
- dvb_input_detach(port->input[0]);
dvb_input_detach(port->input[1]);
+ dvb_input_detach(port->input[0]);
break;
case DDB_PORT_CI:
case DDB_PORT_LOOP:
- if (port->dvb[0].dev)
- dvb_unregister_device(port->dvb[0].dev);
- if (port->en) {
- dvb_ca_en50221_release(port->en);
- kfree(port->en);
- port->en = NULL;
- }
+ ddb_ci_detach(port);
break;
}
}
dvb_unregister_adapters(dev);
}
-
/* Copy input DMA pointers to output DMA and ACK. */
static void input_write_output(struct ddb_input *input,
@@ -2353,16 +2049,18 @@ static void input_write_dvb(struct ddb_input *input,
struct ddb *dev = input->port->dev;
int ack = 1;
- dma = dma2 = input->dma;
- /* if there also is an output connected, do not ACK.
+ dma = input->dma;
+ dma2 = input->dma;
+ /*
+ * if there also is an output connected, do not ACK.
* input_write_output will ACK.
*/
if (input->redo) {
dma2 = input->redo->dma;
ack = 0;
}
- while (dma->cbuf != ((dma->stat >> 11) & 0x1f)
- || (4 & dma->ctrl)) {
+ while (dma->cbuf != ((dma->stat >> 11) & 0x1f) ||
+ (4 & dma->ctrl)) {
if (4 & dma->ctrl) {
/* dev_err(dev->dev, "Overflow dma %d\n", dma->nr); */
ack = 1;
@@ -2385,7 +2083,7 @@ static void input_write_dvb(struct ddb_input *input,
static void input_work(struct work_struct *work)
{
struct ddb_dma *dma = container_of(work, struct ddb_dma, work);
- struct ddb_input *input = (struct ddb_input *) dma->io;
+ struct ddb_input *input = (struct ddb_input *)dma->io;
struct ddb *dev = input->port->dev;
unsigned long flags;
@@ -2407,11 +2105,11 @@ static void input_work(struct work_struct *work)
static void input_handler(unsigned long data)
{
- struct ddb_input *input = (struct ddb_input *) data;
+ struct ddb_input *input = (struct ddb_input *)data;
struct ddb_dma *dma = input->dma;
-
- /* If there is no input connected, input_tasklet() will
+ /*
+ * If there is no input connected, input_tasklet() will
* just copy pointers and ACK. So, there is no need to go
* through the tasklet scheduler.
*/
@@ -2423,7 +2121,7 @@ static void input_handler(unsigned long data)
static void output_handler(unsigned long data)
{
- struct ddb_output *output = (struct ddb_output *) data;
+ struct ddb_output *output = (struct ddb_output *)data;
struct ddb_dma *dma = output->dma;
struct ddb *dev = output->port->dev;
@@ -2512,10 +2210,10 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr)
dma_nr += 32 + (port->lnr - 1) * 8;
dev_dbg(dev->dev, "init link %u, input %u, handler %u\n",
- port->lnr, nr, dma_nr + base);
+ port->lnr, nr, dma_nr + base);
dev->handler[0][dma_nr + base] = input_handler;
- dev->handler_data[0][dma_nr + base] = (unsigned long) input;
+ dev->handler_data[0][dma_nr + base] = (unsigned long)input;
ddb_dma_init(input, dma_nr, 0);
}
}
@@ -2534,14 +2232,14 @@ static void ddb_output_init(struct ddb_port *port, int nr)
(rm->output->base + rm->output->size * nr);
dev_dbg(dev->dev, "init link %u, output %u, regs %08x\n",
- port->lnr, nr, output->regs);
+ port->lnr, nr, output->regs);
if (dev->has_dma) {
const struct ddb_regmap *rm0 = io_regmap(output, 0);
u32 base = rm0->irq_base_odma;
dev->handler[0][nr + base] = output_handler;
- dev->handler_data[0][nr + base] = (unsigned long) output;
+ dev->handler_data[0][nr + base] = (unsigned long)output;
ddb_dma_init(output, nr, 1);
}
}
@@ -2609,7 +2307,7 @@ void ddb_ports_init(struct ddb *dev)
port->dvb[0].adap = &dev->adap[2 * p];
port->dvb[1].adap = &dev->adap[2 * p + 1];
- if ((port->class == DDB_PORT_NONE) && i && p &&
+ if (port->class == DDB_PORT_NONE && i && p &&
dev->port[p - 1].type == DDB_CI_EXTERNAL_XO2) {
port->class = DDB_PORT_CI;
port->type = DDB_CI_EXTERNAL_XO2_B;
@@ -2618,8 +2316,8 @@ void ddb_ports_init(struct ddb *dev)
}
dev_info(dev->dev, "Port %u: Link %u, Link Port %u (TAB %u): %s\n",
- port->pnr, port->lnr, port->nr, port->nr + 1,
- port->name);
+ port->pnr, port->lnr, port->nr, port->nr + 1,
+ port->name);
if (port->class == DDB_PORT_CI &&
port->type == DDB_CI_EXTERNAL_XO2) {
@@ -2741,7 +2439,7 @@ static void irq_handle_io(struct ddb *dev, u32 s)
irqreturn_t ddb_irq_handler0(int irq, void *dev_id)
{
- struct ddb *dev = (struct ddb *) dev_id;
+ struct ddb *dev = (struct ddb *)dev_id;
u32 s = ddbreadl(dev, INTERRUPT_STATUS);
do {
@@ -2758,7 +2456,7 @@ irqreturn_t ddb_irq_handler0(int irq, void *dev_id)
irqreturn_t ddb_irq_handler1(int irq, void *dev_id)
{
- struct ddb *dev = (struct ddb *) dev_id;
+ struct ddb *dev = (struct ddb *)dev_id;
u32 s = ddbreadl(dev, INTERRUPT_STATUS);
do {
@@ -2775,7 +2473,7 @@ irqreturn_t ddb_irq_handler1(int irq, void *dev_id)
irqreturn_t ddb_irq_handler(int irq, void *dev_id)
{
- struct ddb *dev = (struct ddb *) dev_id;
+ struct ddb *dev = (struct ddb *)dev_id;
u32 s = ddbreadl(dev, INTERRUPT_STATUS);
int ret = IRQ_HANDLED;
@@ -2812,7 +2510,7 @@ static int reg_wait(struct ddb *dev, u32 reg, u32 bit)
}
static int flashio(struct ddb *dev, u32 lnr, u8 *wbuf, u32 wlen, u8 *rbuf,
- u32 rlen)
+ u32 rlen)
{
u32 data, shift;
u32 tag = DDB_LINK_TAG(lnr);
@@ -2823,7 +2521,7 @@ static int flashio(struct ddb *dev, u32 lnr, u8 *wbuf, u32 wlen, u8 *rbuf,
ddbwritel(dev, 1, tag | SPI_CONTROL);
while (wlen > 4) {
/* FIXME: check for big-endian */
- data = swab32(*(u32 *) wbuf);
+ data = swab32(*(u32 *)wbuf);
wbuf += 4;
wlen -= 4;
ddbwritel(dev, data, tag | SPI_DATA);
@@ -2863,12 +2561,12 @@ static int flashio(struct ddb *dev, u32 lnr, u8 *wbuf, u32 wlen, u8 *rbuf,
if (reg_wait(dev, tag | SPI_CONTROL, 4))
goto fail;
data = ddbreadl(dev, tag | SPI_DATA);
- *(u32 *) rbuf = swab32(data);
+ *(u32 *)rbuf = swab32(data);
rbuf += 4;
rlen -= 4;
}
ddbwritel(dev, 0x0003 | ((rlen << (8 + 3)) & 0x1F00),
- tag | SPI_CONTROL);
+ tag | SPI_CONTROL);
ddbwritel(dev, 0xffffffff, tag | SPI_DATA);
if (reg_wait(dev, tag | SPI_CONTROL, 4))
goto fail;
@@ -3011,7 +2709,7 @@ static ssize_t fan_store(struct device *device, struct device_attribute *d,
}
static ssize_t fanspeed_show(struct device *device,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct ddb *dev = dev_get_drvdata(device);
int num = attr->attr.name[8] - 0x30;
@@ -3049,7 +2747,7 @@ static ssize_t temp_show(struct device *device,
}
static ssize_t ctemp_show(struct device *device,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct ddb *dev = dev_get_drvdata(device);
struct i2c_adapter *adap;
@@ -3076,7 +2774,6 @@ static ssize_t led_show(struct device *device,
return sprintf(buf, "%d\n", dev->leds & (1 << num) ? 1 : 0);
}
-
static void ddb_set_led(struct ddb *dev, int num, int val)
{
if (!dev->link[0].info->led_num)
@@ -3163,7 +2860,7 @@ static ssize_t bsnr_show(struct device *device,
}
static ssize_t bpsnr_show(struct device *device,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct ddb *dev = dev_get_drvdata(device);
unsigned char snr[32];
@@ -3208,7 +2905,6 @@ static ssize_t gap_show(struct device *device,
int num = attr->attr.name[3] - 0x30;
return sprintf(buf, "%d\n", dev->port[num].gap);
-
}
static ssize_t gap_store(struct device *device, struct device_attribute *attr,
@@ -3254,7 +2950,7 @@ static ssize_t regmap_show(struct device *device,
}
static ssize_t fmode_show(struct device *device,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
int num = attr->attr.name[5] - 0x30;
struct ddb *dev = dev_get_drvdata(device);
@@ -3272,7 +2968,7 @@ static ssize_t devid_show(struct device *device,
}
static ssize_t fmode_store(struct device *device, struct device_attribute *attr,
- const char *buf, size_t count)
+ const char *buf, size_t count)
{
struct ddb *dev = dev_get_drvdata(device);
int num = attr->attr.name[5] - 0x30;
@@ -3282,7 +2978,7 @@ static ssize_t fmode_store(struct device *device, struct device_attribute *attr,
return -EINVAL;
if (val > 3)
return -EINVAL;
- lnb_init_fmode(dev, &dev->link[num], val);
+ ddb_lnb_init_fmode(dev, &dev->link[num], val);
return count;
}
@@ -3387,7 +3083,7 @@ static void ddb_device_attrs_del(struct ddb *dev)
device_remove_file(dev->ddb_dev, &ddb_attrs_snr[i]);
device_remove_file(dev->ddb_dev, &ddb_attrs_ctemp[i]);
}
- for (i = 0; ddb_attrs[i].attr.name != NULL; i++)
+ for (i = 0; ddb_attrs[i].attr.name; i++)
device_remove_file(dev->ddb_dev, &ddb_attrs[i]);
}
@@ -3395,7 +3091,7 @@ static int ddb_device_attrs_add(struct ddb *dev)
{
int i;
- for (i = 0; ddb_attrs[i].attr.name != NULL; i++)
+ for (i = 0; ddb_attrs[i].attr.name; i++)
if (device_create_file(dev->ddb_dev, &ddb_attrs[i]))
goto fail;
for (i = 0; i < dev->link[0].info->temp_num; i++)
@@ -3447,8 +3143,9 @@ int ddb_device_create(struct ddb *dev)
device_destroy(&ddb_class, MKDEV(ddb_major, dev->nr));
ddbs[dev->nr] = NULL;
dev->ddb_dev = ERR_PTR(-ENODEV);
- } else
+ } else {
ddb_num++;
+ }
fail:
mutex_unlock(&ddb_mutex);
return res;
@@ -3500,7 +3197,7 @@ static void tempmon_setfan(struct ddb_link *link)
static void temp_handler(unsigned long data)
{
- struct ddb_link *link = (struct ddb_link *) data;
+ struct ddb_link *link = (struct ddb_link *)data;
spin_lock(&link->temp_lock);
tempmon_setfan(link);
@@ -3519,10 +3216,10 @@ static int tempmon_init(struct ddb_link *link, int first_time)
30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80 };
memcpy(link->temp_tab, temperature_table,
- sizeof(temperature_table));
+ sizeof(temperature_table));
}
dev->handler[l][link->info->tempmon_irq] = temp_handler;
- dev->handler_data[l][link->info->tempmon_irq] = (unsigned long) link;
+ dev->handler_data[l][link->info->tempmon_irq] = (unsigned long)link;
ddblwritel(link, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN |
TEMPMON_CONTROL_INTENABLE),
TEMPMON_CONTROL);
@@ -3574,11 +3271,11 @@ static int ddb_init_boards(struct ddb *dev)
ddbwritel(dev, 0, DDB_LINK_TAG(l) | BOARD_CONTROL);
msleep(100);
ddbwritel(dev, info->board_control_2,
- DDB_LINK_TAG(l) | BOARD_CONTROL);
+ DDB_LINK_TAG(l) | BOARD_CONTROL);
usleep_range(2000, 3000);
ddbwritel(dev,
- info->board_control_2 | info->board_control,
- DDB_LINK_TAG(l) | BOARD_CONTROL);
+ info->board_control_2 | info->board_control,
+ DDB_LINK_TAG(l) | BOARD_CONTROL);
usleep_range(2000, 3000);
}
ddb_init_tempmon(link);
@@ -3598,7 +3295,7 @@ int ddb_init(struct ddb *dev)
ddb_init_boards(dev);
if (ddb_i2c_init(dev) < 0)
- goto fail;
+ goto fail1;
ddb_ports_init(dev);
if (ddb_buffers_alloc(dev) < 0) {
dev_info(dev->dev, "Could not allocate buffer memory\n");
@@ -3616,14 +3313,14 @@ int ddb_init(struct ddb *dev)
return 0;
fail3:
- ddb_ports_detach(dev);
dev_err(dev->dev, "fail3\n");
- ddb_ports_release(dev);
+ ddb_ports_detach(dev);
+ ddb_buffers_free(dev);
fail2:
dev_err(dev->dev, "fail2\n");
- ddb_buffers_free(dev);
+ ddb_ports_release(dev);
ddb_i2c_release(dev);
-fail:
+fail1:
dev_err(dev->dev, "fail1\n");
return -1;
}
diff --git a/drivers/media/pci/ddbridge/ddbridge-hw.c b/drivers/media/pci/ddbridge/ddbridge-hw.c
index 48248bcd59c2..c6d14925e2fc 100644
--- a/drivers/media/pci/ddbridge/ddbridge-hw.c
+++ b/drivers/media/pci/ddbridge/ddbridge-hw.c
@@ -185,7 +185,7 @@ static const struct ddb_info ddb_ctv7 = {
.board_control_2 = 4,
};
-static const struct ddb_info ddb_satixS2v3 = {
+static const struct ddb_info ddb_satixs2v3 = {
.type = DDB_OCTOPUS,
.name = "Mystique SaTiX-S2 V3 DVB adapter",
.regmap = &octopus_map,
@@ -336,7 +336,7 @@ static const struct ddb_device_id ddb_device_ids[] = {
DDB_DEVID(0x0006, 0x0022, ddb_v7),
DDB_DEVID(0x0006, 0x0024, ddb_v7a),
DDB_DEVID(0x0003, 0x0030, ddb_dvbct),
- DDB_DEVID(0x0003, 0xdb03, ddb_satixS2v3),
+ DDB_DEVID(0x0003, 0xdb03, ddb_satixs2v3),
DDB_DEVID(0x0006, 0x0031, ddb_ctv7),
DDB_DEVID(0x0006, 0x0032, ddb_ctv7),
DDB_DEVID(0x0006, 0x0033, ddb_ctv7),
@@ -367,8 +367,8 @@ const struct ddb_info *get_ddb_info(u16 vendor, u16 device,
if (vendor == id->vendor &&
device == id->device &&
subvendor == id->subvendor &&
- ((subdevice == id->subdevice) ||
- (id->subdevice == 0xffff)))
+ (subdevice == id->subdevice ||
+ id->subdevice == 0xffff))
return id->info;
}
diff --git a/drivers/media/pci/ddbridge/ddbridge-i2c.c b/drivers/media/pci/ddbridge/ddbridge-i2c.c
index e4d39c3270ae..82a9a0e806fc 100644
--- a/drivers/media/pci/ddbridge/ddbridge-i2c.c
+++ b/drivers/media/pci/ddbridge/ddbridge-i2c.c
@@ -81,7 +81,7 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
static int ddb_i2c_master_xfer(struct i2c_adapter *adapter,
struct i2c_msg msg[], int num)
{
- struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter);
+ struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter);
struct ddb *dev = i2c->dev;
u8 addr = 0;
@@ -149,7 +149,7 @@ void ddb_i2c_release(struct ddb *dev)
static void i2c_handler(unsigned long priv)
{
- struct ddb_i2c *i2c = (struct ddb_i2c *) priv;
+ struct ddb_i2c *i2c = (struct ddb_i2c *)priv;
complete(&i2c->completion);
}
@@ -171,20 +171,20 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
(regmap->i2c->base + regmap->i2c->size * i);
ddbwritel(dev, I2C_SPEED_100, i2c->regs + I2C_TIMING);
ddbwritel(dev, ((i2c->rbuf & 0xffff) << 16) | (i2c->wbuf & 0xffff),
- i2c->regs + I2C_TASKADDRESS);
+ i2c->regs + I2C_TASKADDRESS);
init_completion(&i2c->completion);
adap = &i2c->adap;
i2c_set_adapdata(adap, i2c);
#ifdef I2C_ADAP_CLASS_TV_DIGITAL
- adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG;
+ adap->class = I2C_ADAP_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG;
#else
#ifdef I2C_CLASS_TV_ANALOG
adap->class = I2C_CLASS_TV_ANALOG;
#endif
#endif
snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x",
- dev->nr, i2c->link, i);
+ dev->nr, i2c->link, i);
adap->algo = &ddb_i2c_algo;
adap->algo_data = (void *)i2c;
adap->dev.parent = dev->dev;
@@ -210,7 +210,7 @@ int ddb_i2c_init(struct ddb *dev)
if (!(dev->link[l].info->i2c_mask & (1 << i)))
continue;
i2c = &dev->i2c[num];
- dev->handler_data[l][i + base] = (unsigned long) i2c;
+ dev->handler_data[l][i + base] = (unsigned long)i2c;
dev->handler[l][i + base] = i2c_handler;
stat = ddb_i2c_add(dev, i2c, regmap, l, i, num);
if (stat)
@@ -224,7 +224,9 @@ int ddb_i2c_init(struct ddb *dev)
adap = &i2c->adap;
i2c_del_adapter(adap);
}
- } else
+ } else {
dev->i2c_num = num;
+ }
+
return stat;
}
diff --git a/drivers/media/pci/ddbridge/ddbridge-main.c b/drivers/media/pci/ddbridge/ddbridge-main.c
index ccac7fe31336..26497d6b1395 100644
--- a/drivers/media/pci/ddbridge/ddbridge-main.c
+++ b/drivers/media/pci/ddbridge/ddbridge-main.c
@@ -107,7 +107,7 @@ static void ddb_irq_exit(struct ddb *dev)
static void ddb_remove(struct pci_dev *pdev)
{
- struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev);
+ struct ddb *dev = (struct ddb *)pci_get_drvdata(pdev);
ddb_device_destroy(dev);
ddb_ports_detach(dev);
@@ -132,9 +132,10 @@ static void ddb_irq_msi(struct ddb *dev, int nr)
if (stat >= 1) {
dev->msi = stat;
dev_info(dev->dev, "using %d MSI interrupt(s)\n",
- dev->msi);
- } else
+ dev->msi);
+ } else {
dev_info(dev->dev, "MSI not available.\n");
+ }
}
}
#endif
@@ -160,11 +161,11 @@ static int ddb_irq_init(struct ddb *dev)
irq_flag = 0;
if (dev->msi == 2) {
stat = request_irq(dev->pdev->irq, ddb_irq_handler0,
- irq_flag, "ddbridge", (void *) dev);
+ irq_flag, "ddbridge", (void *)dev);
if (stat < 0)
return stat;
stat = request_irq(dev->pdev->irq + 1, ddb_irq_handler1,
- irq_flag, "ddbridge", (void *) dev);
+ irq_flag, "ddbridge", (void *)dev);
if (stat < 0) {
free_irq(dev->pdev->irq, dev);
return stat;
@@ -173,7 +174,7 @@ static int ddb_irq_init(struct ddb *dev)
#endif
{
stat = request_irq(dev->pdev->irq, ddb_irq_handler,
- irq_flag, "ddbridge", (void *) dev);
+ irq_flag, "ddbridge", (void *)dev);
if (stat < 0)
return stat;
}
@@ -188,7 +189,7 @@ static int ddb_irq_init(struct ddb *dev)
}
static int ddb_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
+ const struct pci_device_id *id)
{
struct ddb *dev;
int stat = 0;
@@ -202,8 +203,8 @@ static int ddb_probe(struct pci_dev *pdev,
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
return -ENODEV;
- dev = vzalloc(sizeof(struct ddb));
- if (dev == NULL)
+ dev = vzalloc(sizeof(*dev));
+ if (!dev)
return -ENOMEM;
mutex_init(&dev->mutex);
@@ -242,7 +243,7 @@ static int ddb_probe(struct pci_dev *pdev,
dev->link[0].ids.regmapid = ddbreadl(dev, 4);
dev_info(&pdev->dev, "HW %08x REGMAP %08x\n",
- dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
+ dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
ddbwritel(dev, 0, DMA_BASE_READ);
ddbwritel(dev, 0, DMA_BASE_WRITE);
@@ -317,7 +318,7 @@ static __init int module_init_ddbridge(void)
if (ddb_class_create() < 0)
return -1;
ddb_wq = create_workqueue("ddbridge");
- if (ddb_wq == NULL)
+ if (!ddb_wq)
goto exit1;
stat = pci_register_driver(&ddb_pci_driver);
if (stat < 0)
diff --git a/drivers/media/pci/ddbridge/ddbridge-maxs8.c b/drivers/media/pci/ddbridge/ddbridge-max.c
index f8a53bc7c86c..dc6b81488746 100644
--- a/drivers/media/pci/ddbridge/ddbridge-maxs8.c
+++ b/drivers/media/pci/ddbridge/ddbridge-max.c
@@ -1,5 +1,5 @@
/*
- * ddbridge-maxs8.c: Digital Devices bridge MaxS4/8 support
+ * ddbridge-max.c: Digital Devices bridge MAX card support
*
* Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de>
@@ -34,7 +34,7 @@
#include "ddbridge-regs.h"
#include "ddbridge-io.h"
-#include "ddbridge-maxs8.h"
+#include "ddbridge-max.h"
#include "mxl5xx.h"
/******************************************************************************/
@@ -68,7 +68,7 @@ static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
}
if (c == 10)
dev_info(dev->dev, "%s lnb = %08x cmd = %08x\n",
- __func__, lnb, cmd);
+ __func__, lnb, cmd);
return 0;
}
@@ -123,7 +123,7 @@ static int lnb_set_sat(struct ddb *dev, u32 link, u32 input, u32 sat, u32 band,
}
static int lnb_set_tone(struct ddb *dev, u32 link, u32 input,
- enum fe_sec_tone_mode tone)
+ enum fe_sec_tone_mode tone)
{
int s = 0;
u32 mask = (1ULL << input);
@@ -149,7 +149,7 @@ static int lnb_set_tone(struct ddb *dev, u32 link, u32 input,
}
static int lnb_set_voltage(struct ddb *dev, u32 link, u32 input,
- enum fe_sec_voltage voltage)
+ enum fe_sec_voltage voltage)
{
int s = 0;
@@ -291,34 +291,45 @@ static int max_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
if (nv != ov) {
if (nv) {
- lnb_set_voltage(dev,
- port->lnr, 0, SEC_VOLTAGE_13);
+ lnb_set_voltage(
+ dev, port->lnr,
+ 0, SEC_VOLTAGE_13);
if (fmode == 1) {
- lnb_set_voltage(dev, port->lnr,
+ lnb_set_voltage(
+ dev, port->lnr,
0, SEC_VOLTAGE_13);
if (old_quattro) {
- lnb_set_voltage(dev, port->lnr,
+ lnb_set_voltage(
+ dev, port->lnr,
1, SEC_VOLTAGE_18);
- lnb_set_voltage(dev, port->lnr,
+ lnb_set_voltage(
+ dev, port->lnr,
2, SEC_VOLTAGE_13);
} else {
- lnb_set_voltage(dev, port->lnr,
+ lnb_set_voltage(
+ dev, port->lnr,
1, SEC_VOLTAGE_13);
- lnb_set_voltage(dev, port->lnr,
+ lnb_set_voltage(
+ dev, port->lnr,
2, SEC_VOLTAGE_18);
}
- lnb_set_voltage(dev, port->lnr,
+ lnb_set_voltage(
+ dev, port->lnr,
3, SEC_VOLTAGE_18);
}
} else {
- lnb_set_voltage(dev, port->lnr,
+ lnb_set_voltage(
+ dev, port->lnr,
0, SEC_VOLTAGE_OFF);
if (fmode == 1) {
- lnb_set_voltage(dev, port->lnr,
+ lnb_set_voltage(
+ dev, port->lnr,
1, SEC_VOLTAGE_OFF);
- lnb_set_voltage(dev, port->lnr,
+ lnb_set_voltage(
+ dev, port->lnr,
2, SEC_VOLTAGE_OFF);
- lnb_set_voltage(dev, port->lnr,
+ lnb_set_voltage(
+ dev, port->lnr,
3, SEC_VOLTAGE_OFF);
}
}
@@ -331,7 +342,6 @@ static int max_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
static int max_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
{
-
return 0;
}
@@ -350,7 +360,7 @@ static int mxl_fw_read(void *priv, u8 *buf, u32 len)
return ddbridge_flashread(dev, link->nr, buf, 0xc0000, len);
}
-int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm)
+int ddb_lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm)
{
u32 l = link->nr;
@@ -394,7 +404,7 @@ static struct mxl5xx_cfg mxl5xx = {
.fw_read = mxl_fw_read,
};
-int fe_attach_mxl5xx(struct ddb_input *input)
+int ddb_fe_attach_mxl5xx(struct ddb_input *input)
{
struct ddb *dev = input->port->dev;
struct i2c_adapter *i2c = &input->port->i2c->adap;
@@ -414,7 +424,7 @@ int fe_attach_mxl5xx(struct ddb_input *input)
tuner = 0;
dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg,
- demod, tuner, &dvb->set_input);
+ demod, tuner, &dvb->set_input);
if (!dvb->fe) {
dev_err(dev->dev, "No MXL5XX found!\n");
@@ -430,7 +440,7 @@ int fe_attach_mxl5xx(struct ddb_input *input)
lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT);
lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF);
}
- lnb_init_fmode(dev, link, fmode);
+ ddb_lnb_init_fmode(dev, link, fmode);
dvb->fe->ops.set_voltage = max_set_voltage;
dvb->fe->ops.enable_high_lnb_voltage = max_enable_high_lnb_voltage;
diff --git a/drivers/media/pci/ddbridge/ddbridge-maxs8.h b/drivers/media/pci/ddbridge/ddbridge-max.h
index bb8884811a46..bf8bf38739f6 100644
--- a/drivers/media/pci/ddbridge/ddbridge-maxs8.h
+++ b/drivers/media/pci/ddbridge/ddbridge-max.h
@@ -1,5 +1,5 @@
/*
- * ddbridge-maxs8.h: Digital Devices bridge MaxS4/8 support
+ * ddbridge-max.h: Digital Devices bridge MAX card support
*
* Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de>
@@ -16,14 +16,14 @@
*
*/
-#ifndef _DDBRIDGE_MAXS8_H_
-#define _DDBRIDGE_MAXS8_H_
+#ifndef _DDBRIDGE_MAX_H_
+#define _DDBRIDGE_MAX_H_
#include "ddbridge.h"
/******************************************************************************/
-int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm);
-int fe_attach_mxl5xx(struct ddb_input *input);
+int ddb_lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm);
+int ddb_fe_attach_mxl5xx(struct ddb_input *input);
-#endif /* _DDBRIDGE_MAXS8_H */
+#endif /* _DDBRIDGE_MAX_H */
diff --git a/drivers/media/pci/ddbridge/ddbridge-regs.h b/drivers/media/pci/ddbridge/ddbridge-regs.h
index 9d44f8d3af75..23d74ff83fe4 100644
--- a/drivers/media/pci/ddbridge/ddbridge-regs.h
+++ b/drivers/media/pci/ddbridge/ddbridge-regs.h
@@ -95,27 +95,27 @@
#define DMA_BASE_WRITE (0x100)
#define DMA_BASE_READ (0x140)
-#define TS_CONTROL(_io) (_io->regs + 0x00)
-#define TS_CONTROL2(_io) (_io->regs + 0x04)
+#define TS_CONTROL(_io) ((_io)->regs + 0x00)
+#define TS_CONTROL2(_io) ((_io)->regs + 0x04)
/* ------------------------------------------------------------------------- */
/* DMA Buffer */
-#define DMA_BUFFER_CONTROL(_dma) (_dma->regs + 0x00)
-#define DMA_BUFFER_ACK(_dma) (_dma->regs + 0x04)
-#define DMA_BUFFER_CURRENT(_dma) (_dma->regs + 0x08)
-#define DMA_BUFFER_SIZE(_dma) (_dma->regs + 0x0c)
+#define DMA_BUFFER_CONTROL(_dma) ((_dma)->regs + 0x00)
+#define DMA_BUFFER_ACK(_dma) ((_dma)->regs + 0x04)
+#define DMA_BUFFER_CURRENT(_dma) ((_dma)->regs + 0x08)
+#define DMA_BUFFER_SIZE(_dma) ((_dma)->regs + 0x0c)
/* ------------------------------------------------------------------------- */
/* CI Interface (only CI-Bridge) */
-#define CI_BASE (0x400)
-#define CI_CONTROL(i) (CI_BASE + (i) * 32 + 0x00)
+#define CI_BASE (0x400)
+#define CI_CONTROL(i) (CI_BASE + (i) * 32 + 0x00)
-#define CI_DO_ATTRIBUTE_RW(i) (CI_BASE + (i) * 32 + 0x04)
-#define CI_DO_IO_RW(i) (CI_BASE + (i) * 32 + 0x08)
-#define CI_READDATA(i) (CI_BASE + (i) * 32 + 0x0c)
-#define CI_DO_READ_ATTRIBUTES(i) (CI_BASE + (i) * 32 + 0x10)
+#define CI_DO_ATTRIBUTE_RW(i) (CI_BASE + (i) * 32 + 0x04)
+#define CI_DO_IO_RW(i) (CI_BASE + (i) * 32 + 0x08)
+#define CI_READDATA(i) (CI_BASE + (i) * 32 + 0x0c)
+#define CI_DO_READ_ATTRIBUTES(i) (CI_BASE + (i) * 32 + 0x10)
#define CI_RESET_CAM (0x00000001)
#define CI_POWER_ON (0x00000002)
@@ -132,7 +132,7 @@
#define CI_BUFFER_BASE (0x3000)
#define CI_BUFFER_SIZE (0x0800)
-#define CI_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE)
+#define CI_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE)
/* ------------------------------------------------------------------------- */
/* LNB commands (mxl5xx / Max S8) */
@@ -140,7 +140,7 @@
#define LNB_BASE (0x400)
#define LNB_CONTROL(i) (LNB_BASE + (i) * 0x20 + 0x00)
-#define LNB_CMD (7ULL << 0)
+#define LNB_CMD (7ULL << 0)
#define LNB_CMD_NOP 0
#define LNB_CMD_INIT 1
#define LNB_CMD_LOW 3
@@ -148,8 +148,8 @@
#define LNB_CMD_OFF 5
#define LNB_CMD_DISEQC 6
-#define LNB_BUSY (1ULL << 4)
-#define LNB_TONE (1ULL << 15)
+#define LNB_BUSY BIT_ULL(4)
+#define LNB_TONE BIT_ULL(15)
#define LNB_BUF_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10)
#define LNB_BUF_WRITE(i) (LNB_BASE + (i) * 0x20 + 0x14)
diff --git a/drivers/media/pci/ddbridge/ddbridge.h b/drivers/media/pci/ddbridge/ddbridge.h
index e9afa96bd9df..095457737bc1 100644
--- a/drivers/media/pci/ddbridge/ddbridge.h
+++ b/drivers/media/pci/ddbridge/ddbridge.h
@@ -55,15 +55,15 @@
#include <linux/device.h>
#include <linux/io.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_ringbuffer.h"
-#include "dvb_ca_en50221.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_ringbuffer.h>
+#include <media/dvb_ca_en50221.h>
+#include <media/dvb_net.h>
-#define DDBRIDGE_VERSION "0.9.31intermediate-integrated"
+#define DDBRIDGE_VERSION "0.9.32-integrated"
#define DDB_MAX_I2C 32
#define DDB_MAX_PORT 32
@@ -143,11 +143,11 @@ struct ddb_info {
#define DMA_MAX_BUFS 32 /* hardware table limit */
#define INPUT_DMA_BUFS 8
-#define INPUT_DMA_SIZE (128*47*21)
+#define INPUT_DMA_SIZE (128 * 47 * 21)
#define INPUT_DMA_IRQ_DIV 1
#define OUTPUT_DMA_BUFS 8
-#define OUTPUT_DMA_SIZE (128*47*21)
+#define OUTPUT_DMA_SIZE (128 * 47 * 21)
#define OUTPUT_DMA_IRQ_DIV 1
struct ddb;
@@ -166,7 +166,7 @@ struct ddb_dma {
u32 bufval;
struct work_struct work;
- spinlock_t lock;
+ spinlock_t lock; /* DMA lock */
wait_queue_head_t wq;
int running;
u32 stat;
@@ -196,17 +196,16 @@ struct ddb_dvb {
int (*i2c_gate_ctrl)(struct dvb_frontend *, int);
int (*set_voltage)(struct dvb_frontend *fe,
- enum fe_sec_voltage voltage);
+ enum fe_sec_voltage voltage);
int (*set_input)(struct dvb_frontend *fe, int input);
int (*diseqc_send_master_cmd)(struct dvb_frontend *fe,
- struct dvb_diseqc_master_cmd *cmd);
+ struct dvb_diseqc_master_cmd *cmd);
};
struct ddb_ci {
struct dvb_ca_en50221 en;
struct ddb_port *port;
u32 nr;
- struct mutex lock;
};
struct ddb_io {
@@ -240,7 +239,7 @@ struct ddb_port {
u32 regs;
u32 lnr;
struct ddb_i2c *i2c;
- struct mutex i2c_gate_lock;
+ struct mutex i2c_gate_lock; /* I2C access lock */
u32 class;
#define DDB_PORT_NONE 0
#define DDB_PORT_CI 1
@@ -297,7 +296,7 @@ struct ddb_port {
#define TS_CAPTURE_LEN (4096)
struct ddb_lnb {
- struct mutex lock;
+ struct mutex lock; /* lock lnb access */
u32 tone;
enum fe_sec_voltage oldvoltage[4];
u32 voltage[4];
@@ -310,54 +309,54 @@ struct ddb_link {
const struct ddb_info *info;
u32 nr;
u32 regs;
- spinlock_t lock;
- struct mutex flash_mutex;
+ spinlock_t lock; /* lock link access */
+ struct mutex flash_mutex; /* lock flash access */
struct ddb_lnb lnb;
struct tasklet_struct tasklet;
struct ddb_ids ids;
- spinlock_t temp_lock;
+ spinlock_t temp_lock; /* lock temp chip access */
int overtemperature_error;
u8 temp_tab[11];
};
struct ddb {
- struct pci_dev *pdev;
- struct platform_device *pfdev;
- struct device *dev;
+ struct pci_dev *pdev;
+ struct platform_device *pfdev;
+ struct device *dev;
- int msi;
+ int msi;
struct workqueue_struct *wq;
- u32 has_dma;
-
- struct ddb_link link[DDB_MAX_LINK];
- unsigned char __iomem *regs;
- u32 regs_len;
- u32 port_num;
- struct ddb_port port[DDB_MAX_PORT];
- u32 i2c_num;
- struct ddb_i2c i2c[DDB_MAX_I2C];
- struct ddb_input input[DDB_MAX_INPUT];
- struct ddb_output output[DDB_MAX_OUTPUT];
- struct dvb_adapter adap[DDB_MAX_INPUT];
- struct ddb_dma idma[DDB_MAX_INPUT];
- struct ddb_dma odma[DDB_MAX_OUTPUT];
-
- void (*handler[4][256])(unsigned long);
- unsigned long handler_data[4][256];
-
- struct device *ddb_dev;
- u32 ddb_dev_users;
- u32 nr;
- u8 iobuf[1028];
-
- u8 leds;
- u32 ts_irq;
- u32 i2c_irq;
-
- struct mutex mutex;
-
- u8 tsbuf[TS_CAPTURE_LEN];
+ u32 has_dma;
+
+ struct ddb_link link[DDB_MAX_LINK];
+ unsigned char __iomem *regs;
+ u32 regs_len;
+ u32 port_num;
+ struct ddb_port port[DDB_MAX_PORT];
+ u32 i2c_num;
+ struct ddb_i2c i2c[DDB_MAX_I2C];
+ struct ddb_input input[DDB_MAX_INPUT];
+ struct ddb_output output[DDB_MAX_OUTPUT];
+ struct dvb_adapter adap[DDB_MAX_INPUT];
+ struct ddb_dma idma[DDB_MAX_INPUT];
+ struct ddb_dma odma[DDB_MAX_OUTPUT];
+
+ void (*handler[4][256])(unsigned long);
+ unsigned long handler_data[4][256];
+
+ struct device *ddb_dev;
+ u32 ddb_dev_users;
+ u32 nr;
+ u8 iobuf[1028];
+
+ u8 leds;
+ u32 ts_irq;
+ u32 i2c_irq;
+
+ struct mutex mutex; /* lock access to global ddb array */
+
+ u8 tsbuf[TS_CAPTURE_LEN];
};
/****************************************************************************/
diff --git a/drivers/media/pci/dm1105/Makefile b/drivers/media/pci/dm1105/Makefile
index 327585143c83..d22c2547ee86 100644
--- a/drivers/media/pci/dm1105/Makefile
+++ b/drivers/media/pci/dm1105/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_DVB_DM1105) += dm1105.o
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c
index 7c3900dec368..c9db108751a7 100644
--- a/drivers/media/pci/dm1105/dm1105.c
+++ b/drivers/media/pci/dm1105/dm1105.c
@@ -27,12 +27,12 @@
#include <linux/slab.h>
#include <media/rc-core.h>
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
#include "dvb-pll.h"
#include "stv0299.h"
diff --git a/drivers/media/pci/intel/Makefile b/drivers/media/pci/intel/Makefile
new file mode 100644
index 000000000000..745c8b2a7819
--- /dev/null
+++ b/drivers/media/pci/intel/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the IPU3 cio2 and ImGU drivers
+#
+
+obj-y += ipu3/
diff --git a/drivers/media/pci/intel/ipu3/Kconfig b/drivers/media/pci/intel/ipu3/Kconfig
new file mode 100644
index 000000000000..a82d3fe277d2
--- /dev/null
+++ b/drivers/media/pci/intel/ipu3/Kconfig
@@ -0,0 +1,19 @@
+config VIDEO_IPU3_CIO2
+ tristate "Intel ipu3-cio2 driver"
+ depends on VIDEO_V4L2 && PCI
+ depends on VIDEO_V4L2_SUBDEV_API
+ depends on X86 || COMPILE_TEST
+ depends on MEDIA_CONTROLLER
+ depends on HAS_DMA
+ depends on ACPI
+ select V4L2_FWNODE
+ select VIDEOBUF2_DMA_SG
+
+ ---help---
+ This is the Intel IPU3 CIO2 CSI-2 receiver unit, found in Intel
+ Skylake and Kaby Lake SoCs and used for capturing images and
+ video from a camera sensor.
+
+ Say Y or M here if you have a Skylake/Kaby Lake SoC with MIPI CSI-2
+ connected camera.
+ The module will be called ipu3-cio2.
diff --git a/drivers/media/pci/intel/ipu3/Makefile b/drivers/media/pci/intel/ipu3/Makefile
new file mode 100644
index 000000000000..20186e3ff2ae
--- /dev/null
+++ b/drivers/media/pci/intel/ipu3/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_VIDEO_IPU3_CIO2) += ipu3-cio2.o
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.c b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
new file mode 100644
index 000000000000..6c4444b31f4b
--- /dev/null
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.c
@@ -0,0 +1,2048 @@
+/*
+ * Copyright (c) 2017 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Based partially on Intel IPU4 driver written by
+ * Sakari Ailus <sakari.ailus@linux.intel.com>
+ * Samu Onkalo <samu.onkalo@intel.com>
+ * Jouni Högander <jouni.hogander@intel.com>
+ * Jouni Ukkonen <jouni.ukkonen@intel.com>
+ * Antti Laakso <antti.laakso@intel.com>
+ * et al.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-dma-sg.h>
+
+#include "ipu3-cio2.h"
+
+struct ipu3_cio2_fmt {
+ u32 mbus_code;
+ u32 fourcc;
+ u8 mipicode;
+};
+
+/*
+ * These are raw formats used in Intel's third generation of
+ * Image Processing Unit known as IPU3.
+ * 10bit raw bayer packed, 32 bytes for every 25 pixels,
+ * last LSB 6 bits unused.
+ */
+static const struct ipu3_cio2_fmt formats[] = {
+ { /* put default entry at beginning */
+ .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
+ .fourcc = V4L2_PIX_FMT_IPU3_SGRBG10,
+ .mipicode = 0x2b,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
+ .fourcc = V4L2_PIX_FMT_IPU3_SGBRG10,
+ .mipicode = 0x2b,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
+ .fourcc = V4L2_PIX_FMT_IPU3_SBGGR10,
+ .mipicode = 0x2b,
+ }, {
+ .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
+ .fourcc = V4L2_PIX_FMT_IPU3_SRGGB10,
+ .mipicode = 0x2b,
+ },
+};
+
+/*
+ * cio2_find_format - lookup color format by fourcc or/and media bus code
+ * @pixelformat: fourcc to match, ignored if null
+ * @mbus_code: media bus code to match, ignored if null
+ */
+static const struct ipu3_cio2_fmt *cio2_find_format(const u32 *pixelformat,
+ const u32 *mbus_code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(formats); i++) {
+ if (pixelformat && *pixelformat != formats[i].fourcc)
+ continue;
+ if (mbus_code && *mbus_code != formats[i].mbus_code)
+ continue;
+
+ return &formats[i];
+ }
+
+ return NULL;
+}
+
+static inline u32 cio2_bytesperline(const unsigned int width)
+{
+ /*
+ * 64 bytes for every 50 pixels, the line length
+ * in bytes is multiple of 64 (line end alignment).
+ */
+ return DIV_ROUND_UP(width, 50) * 64;
+}
+
+/**************** FBPT operations ****************/
+
+static void cio2_fbpt_exit_dummy(struct cio2_device *cio2)
+{
+ if (cio2->dummy_lop) {
+ dma_free_coherent(&cio2->pci_dev->dev, CIO2_PAGE_SIZE,
+ cio2->dummy_lop, cio2->dummy_lop_bus_addr);
+ cio2->dummy_lop = NULL;
+ }
+ if (cio2->dummy_page) {
+ dma_free_coherent(&cio2->pci_dev->dev, CIO2_PAGE_SIZE,
+ cio2->dummy_page, cio2->dummy_page_bus_addr);
+ cio2->dummy_page = NULL;
+ }
+}
+
+static int cio2_fbpt_init_dummy(struct cio2_device *cio2)
+{
+ unsigned int i;
+
+ cio2->dummy_page = dma_alloc_coherent(&cio2->pci_dev->dev,
+ CIO2_PAGE_SIZE,
+ &cio2->dummy_page_bus_addr,
+ GFP_KERNEL);
+ cio2->dummy_lop = dma_alloc_coherent(&cio2->pci_dev->dev,
+ CIO2_PAGE_SIZE,
+ &cio2->dummy_lop_bus_addr,
+ GFP_KERNEL);
+ if (!cio2->dummy_page || !cio2->dummy_lop) {
+ cio2_fbpt_exit_dummy(cio2);
+ return -ENOMEM;
+ }
+ /*
+ * List of Pointers(LOP) contains 1024x32b pointers to 4KB page each
+ * Initialize each entry to dummy_page bus base address.
+ */
+ for (i = 0; i < CIO2_PAGE_SIZE / sizeof(*cio2->dummy_lop); i++)
+ cio2->dummy_lop[i] = cio2->dummy_page_bus_addr >> PAGE_SHIFT;
+
+ return 0;
+}
+
+static void cio2_fbpt_entry_enable(struct cio2_device *cio2,
+ struct cio2_fbpt_entry entry[CIO2_MAX_LOPS])
+{
+ /*
+ * The CPU first initializes some fields in fbpt, then sets
+ * the VALID bit, this barrier is to ensure that the DMA(device)
+ * does not see the VALID bit enabled before other fields are
+ * initialized; otherwise it could lead to havoc.
+ */
+ dma_wmb();
+
+ /*
+ * Request interrupts for start and completion
+ * Valid bit is applicable only to 1st entry
+ */
+ entry[0].first_entry.ctrl = CIO2_FBPT_CTRL_VALID |
+ CIO2_FBPT_CTRL_IOC | CIO2_FBPT_CTRL_IOS;
+}
+
+/* Initialize fpbt entries to point to dummy frame */
+static void cio2_fbpt_entry_init_dummy(struct cio2_device *cio2,
+ struct cio2_fbpt_entry
+ entry[CIO2_MAX_LOPS])
+{
+ unsigned int i;
+
+ entry[0].first_entry.first_page_offset = 0;
+ entry[1].second_entry.num_of_pages =
+ CIO2_PAGE_SIZE / sizeof(u32) * CIO2_MAX_LOPS;
+ entry[1].second_entry.last_page_available_bytes = CIO2_PAGE_SIZE - 1;
+
+ for (i = 0; i < CIO2_MAX_LOPS; i++)
+ entry[i].lop_page_addr = cio2->dummy_lop_bus_addr >> PAGE_SHIFT;
+
+ cio2_fbpt_entry_enable(cio2, entry);
+}
+
+/* Initialize fpbt entries to point to a given buffer */
+static void cio2_fbpt_entry_init_buf(struct cio2_device *cio2,
+ struct cio2_buffer *b,
+ struct cio2_fbpt_entry
+ entry[CIO2_MAX_LOPS])
+{
+ struct vb2_buffer *vb = &b->vbb.vb2_buf;
+ unsigned int length = vb->planes[0].length;
+ int remaining, i;
+
+ entry[0].first_entry.first_page_offset = b->offset;
+ remaining = length + entry[0].first_entry.first_page_offset;
+ entry[1].second_entry.num_of_pages =
+ DIV_ROUND_UP(remaining, CIO2_PAGE_SIZE);
+ /*
+ * last_page_available_bytes has the offset of the last byte in the
+ * last page which is still accessible by DMA. DMA cannot access
+ * beyond this point. Valid range for this is from 0 to 4095.
+ * 0 indicates 1st byte in the page is DMA accessible.
+ * 4095 (CIO2_PAGE_SIZE - 1) means every single byte in the last page
+ * is available for DMA transfer.
+ */
+ entry[1].second_entry.last_page_available_bytes =
+ (remaining & ~PAGE_MASK) ?
+ (remaining & ~PAGE_MASK) - 1 :
+ CIO2_PAGE_SIZE - 1;
+ /* Fill FBPT */
+ remaining = length;
+ i = 0;
+ while (remaining > 0) {
+ entry->lop_page_addr = b->lop_bus_addr[i] >> PAGE_SHIFT;
+ remaining -= CIO2_PAGE_SIZE / sizeof(u32) * CIO2_PAGE_SIZE;
+ entry++;
+ i++;
+ }
+
+ /*
+ * The first not meaningful FBPT entry should point to a valid LOP
+ */
+ entry->lop_page_addr = cio2->dummy_lop_bus_addr >> PAGE_SHIFT;
+
+ cio2_fbpt_entry_enable(cio2, entry);
+}
+
+static int cio2_fbpt_init(struct cio2_device *cio2, struct cio2_queue *q)
+{
+ struct device *dev = &cio2->pci_dev->dev;
+
+ q->fbpt = dma_alloc_coherent(dev, CIO2_FBPT_SIZE, &q->fbpt_bus_addr,
+ GFP_KERNEL);
+ if (!q->fbpt)
+ return -ENOMEM;
+
+ memset(q->fbpt, 0, CIO2_FBPT_SIZE);
+
+ return 0;
+}
+
+static void cio2_fbpt_exit(struct cio2_queue *q, struct device *dev)
+{
+ dma_free_coherent(dev, CIO2_FBPT_SIZE, q->fbpt, q->fbpt_bus_addr);
+}
+
+/**************** CSI2 hardware setup ****************/
+
+/*
+ * The CSI2 receiver has several parameters affecting
+ * the receiver timings. These depend on the MIPI bus frequency
+ * F in Hz (sensor transmitter rate) as follows:
+ * register value = (A/1e9 + B * UI) / COUNT_ACC
+ * where
+ * UI = 1 / (2 * F) in seconds
+ * COUNT_ACC = counter accuracy in seconds
+ * For IPU3 COUNT_ACC = 0.0625
+ *
+ * A and B are coefficients from the table below,
+ * depending whether the register minimum or maximum value is
+ * calculated.
+ * Minimum Maximum
+ * Clock lane A B A B
+ * reg_rx_csi_dly_cnt_termen_clane 0 0 38 0
+ * reg_rx_csi_dly_cnt_settle_clane 95 -8 300 -16
+ * Data lanes
+ * reg_rx_csi_dly_cnt_termen_dlane0 0 0 35 4
+ * reg_rx_csi_dly_cnt_settle_dlane0 85 -2 145 -6
+ * reg_rx_csi_dly_cnt_termen_dlane1 0 0 35 4
+ * reg_rx_csi_dly_cnt_settle_dlane1 85 -2 145 -6
+ * reg_rx_csi_dly_cnt_termen_dlane2 0 0 35 4
+ * reg_rx_csi_dly_cnt_settle_dlane2 85 -2 145 -6
+ * reg_rx_csi_dly_cnt_termen_dlane3 0 0 35 4
+ * reg_rx_csi_dly_cnt_settle_dlane3 85 -2 145 -6
+ *
+ * We use the minimum values of both A and B.
+ */
+
+/*
+ * shift for keeping value range suitable for 32-bit integer arithmetics
+ */
+#define LIMIT_SHIFT 8
+
+static s32 cio2_rx_timing(s32 a, s32 b, s64 freq, int def)
+{
+ const u32 accinv = 16; /* invert of counter resolution */
+ const u32 uiinv = 500000000; /* 1e9 / 2 */
+ s32 r;
+
+ freq >>= LIMIT_SHIFT;
+
+ if (WARN_ON(freq <= 0 || freq > S32_MAX))
+ return def;
+ /*
+ * b could be 0, -2 or -8, so |accinv * b| is always
+ * less than (1 << ds) and thus |r| < 500000000.
+ */
+ r = accinv * b * (uiinv >> LIMIT_SHIFT);
+ r = r / (s32)freq;
+ /* max value of a is 95 */
+ r += accinv * a;
+
+ return r;
+};
+
+/* Calculate the the delay value for termination enable of clock lane HS Rx */
+static int cio2_csi2_calc_timing(struct cio2_device *cio2, struct cio2_queue *q,
+ struct cio2_csi2_timing *timing)
+{
+ struct device *dev = &cio2->pci_dev->dev;
+ struct v4l2_querymenu qm = {.id = V4L2_CID_LINK_FREQ, };
+ struct v4l2_ctrl *link_freq;
+ s64 freq;
+ int r;
+
+ if (!q->sensor)
+ return -ENODEV;
+
+ link_freq = v4l2_ctrl_find(q->sensor->ctrl_handler, V4L2_CID_LINK_FREQ);
+ if (!link_freq) {
+ dev_err(dev, "failed to find LINK_FREQ\n");
+ return -EPIPE;
+ }
+
+ qm.index = v4l2_ctrl_g_ctrl(link_freq);
+ r = v4l2_querymenu(q->sensor->ctrl_handler, &qm);
+ if (r) {
+ dev_err(dev, "failed to get menu item\n");
+ return r;
+ }
+
+ if (!qm.value) {
+ dev_err(dev, "error invalid link_freq\n");
+ return -EINVAL;
+ }
+ freq = qm.value;
+
+ timing->clk_termen = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_A,
+ CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_B,
+ freq,
+ CIO2_CSIRX_DLY_CNT_TERMEN_DEFAULT);
+ timing->clk_settle = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_SETTLE_CLANE_A,
+ CIO2_CSIRX_DLY_CNT_SETTLE_CLANE_B,
+ freq,
+ CIO2_CSIRX_DLY_CNT_SETTLE_DEFAULT);
+ timing->dat_termen = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_TERMEN_DLANE_A,
+ CIO2_CSIRX_DLY_CNT_TERMEN_DLANE_B,
+ freq,
+ CIO2_CSIRX_DLY_CNT_TERMEN_DEFAULT);
+ timing->dat_settle = cio2_rx_timing(CIO2_CSIRX_DLY_CNT_SETTLE_DLANE_A,
+ CIO2_CSIRX_DLY_CNT_SETTLE_DLANE_B,
+ freq,
+ CIO2_CSIRX_DLY_CNT_SETTLE_DEFAULT);
+
+ dev_dbg(dev, "freq ct value is %d\n", timing->clk_termen);
+ dev_dbg(dev, "freq cs value is %d\n", timing->clk_settle);
+ dev_dbg(dev, "freq dt value is %d\n", timing->dat_termen);
+ dev_dbg(dev, "freq ds value is %d\n", timing->dat_settle);
+
+ return 0;
+};
+
+static int cio2_hw_init(struct cio2_device *cio2, struct cio2_queue *q)
+{
+ static const int NUM_VCS = 4;
+ static const int SID; /* Stream id */
+ static const int ENTRY;
+ static const int FBPT_WIDTH = DIV_ROUND_UP(CIO2_MAX_LOPS,
+ CIO2_FBPT_SUBENTRY_UNIT);
+ const u32 num_buffers1 = CIO2_MAX_BUFFERS - 1;
+ const struct ipu3_cio2_fmt *fmt;
+ void __iomem *const base = cio2->base;
+ u8 lanes, csi2bus = q->csi2.port;
+ u8 sensor_vc = SENSOR_VIR_CH_DFLT;
+ struct cio2_csi2_timing timing;
+ int i, r;
+
+ fmt = cio2_find_format(NULL, &q->subdev_fmt.code);
+ if (!fmt)
+ return -EINVAL;
+
+ lanes = q->csi2.lanes;
+
+ r = cio2_csi2_calc_timing(cio2, q, &timing);
+ if (r)
+ return r;
+
+ writel(timing.clk_termen, q->csi_rx_base +
+ CIO2_REG_CSIRX_DLY_CNT_TERMEN(CIO2_CSIRX_DLY_CNT_CLANE_IDX));
+ writel(timing.clk_settle, q->csi_rx_base +
+ CIO2_REG_CSIRX_DLY_CNT_SETTLE(CIO2_CSIRX_DLY_CNT_CLANE_IDX));
+
+ for (i = 0; i < lanes; i++) {
+ writel(timing.dat_termen, q->csi_rx_base +
+ CIO2_REG_CSIRX_DLY_CNT_TERMEN(i));
+ writel(timing.dat_settle, q->csi_rx_base +
+ CIO2_REG_CSIRX_DLY_CNT_SETTLE(i));
+ }
+
+ writel(CIO2_PBM_WMCTRL1_MIN_2CK |
+ CIO2_PBM_WMCTRL1_MID1_2CK |
+ CIO2_PBM_WMCTRL1_MID2_2CK, base + CIO2_REG_PBM_WMCTRL1);
+ writel(CIO2_PBM_WMCTRL2_HWM_2CK << CIO2_PBM_WMCTRL2_HWM_2CK_SHIFT |
+ CIO2_PBM_WMCTRL2_LWM_2CK << CIO2_PBM_WMCTRL2_LWM_2CK_SHIFT |
+ CIO2_PBM_WMCTRL2_OBFFWM_2CK <<
+ CIO2_PBM_WMCTRL2_OBFFWM_2CK_SHIFT |
+ CIO2_PBM_WMCTRL2_TRANSDYN << CIO2_PBM_WMCTRL2_TRANSDYN_SHIFT |
+ CIO2_PBM_WMCTRL2_OBFF_MEM_EN, base + CIO2_REG_PBM_WMCTRL2);
+ writel(CIO2_PBM_ARB_CTRL_LANES_DIV <<
+ CIO2_PBM_ARB_CTRL_LANES_DIV_SHIFT |
+ CIO2_PBM_ARB_CTRL_LE_EN |
+ CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN <<
+ CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN_SHIFT |
+ CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP <<
+ CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP_SHIFT,
+ base + CIO2_REG_PBM_ARB_CTRL);
+ writel(CIO2_CSIRX_STATUS_DLANE_HS_MASK,
+ q->csi_rx_base + CIO2_REG_CSIRX_STATUS_DLANE_HS);
+ writel(CIO2_CSIRX_STATUS_DLANE_LP_MASK,
+ q->csi_rx_base + CIO2_REG_CSIRX_STATUS_DLANE_LP);
+
+ writel(CIO2_FB_HPLL_FREQ, base + CIO2_REG_FB_HPLL_FREQ);
+ writel(CIO2_ISCLK_RATIO, base + CIO2_REG_ISCLK_RATIO);
+
+ /* Configure MIPI backend */
+ for (i = 0; i < NUM_VCS; i++)
+ writel(1, q->csi_rx_base + CIO2_REG_MIPIBE_SP_LUT_ENTRY(i));
+
+ /* There are 16 short packet LUT entry */
+ for (i = 0; i < 16; i++)
+ writel(CIO2_MIPIBE_LP_LUT_ENTRY_DISREGARD,
+ q->csi_rx_base + CIO2_REG_MIPIBE_LP_LUT_ENTRY(i));
+ writel(CIO2_MIPIBE_GLOBAL_LUT_DISREGARD,
+ q->csi_rx_base + CIO2_REG_MIPIBE_GLOBAL_LUT_DISREGARD);
+
+ writel(CIO2_INT_EN_EXT_IE_MASK, base + CIO2_REG_INT_EN_EXT_IE);
+ writel(CIO2_IRQCTRL_MASK, q->csi_rx_base + CIO2_REG_IRQCTRL_MASK);
+ writel(CIO2_IRQCTRL_MASK, q->csi_rx_base + CIO2_REG_IRQCTRL_ENABLE);
+ writel(0, q->csi_rx_base + CIO2_REG_IRQCTRL_EDGE);
+ writel(0, q->csi_rx_base + CIO2_REG_IRQCTRL_LEVEL_NOT_PULSE);
+ writel(CIO2_INT_EN_EXT_OE_MASK, base + CIO2_REG_INT_EN_EXT_OE);
+
+ writel(CIO2_REG_INT_EN_IRQ | CIO2_INT_IOC(CIO2_DMA_CHAN) |
+ CIO2_REG_INT_EN_IOS(CIO2_DMA_CHAN),
+ base + CIO2_REG_INT_EN);
+
+ writel((CIO2_PXM_PXF_FMT_CFG_BPP_10 | CIO2_PXM_PXF_FMT_CFG_PCK_64B)
+ << CIO2_PXM_PXF_FMT_CFG_SID0_SHIFT,
+ base + CIO2_REG_PXM_PXF_FMT_CFG0(csi2bus));
+ writel(SID << CIO2_MIPIBE_LP_LUT_ENTRY_SID_SHIFT |
+ sensor_vc << CIO2_MIPIBE_LP_LUT_ENTRY_VC_SHIFT |
+ fmt->mipicode << CIO2_MIPIBE_LP_LUT_ENTRY_FORMAT_TYPE_SHIFT,
+ q->csi_rx_base + CIO2_REG_MIPIBE_LP_LUT_ENTRY(ENTRY));
+ writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_COMP_FORMAT(sensor_vc));
+ writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_FORCE_RAW8);
+ writel(0, base + CIO2_REG_PXM_SID2BID0(csi2bus));
+
+ writel(lanes, q->csi_rx_base + CIO2_REG_CSIRX_NOF_ENABLED_LANES);
+ writel(CIO2_CGC_PRIM_TGE |
+ CIO2_CGC_SIDE_TGE |
+ CIO2_CGC_XOSC_TGE |
+ CIO2_CGC_D3I3_TGE |
+ CIO2_CGC_CSI2_INTERFRAME_TGE |
+ CIO2_CGC_CSI2_PORT_DCGE |
+ CIO2_CGC_SIDE_DCGE |
+ CIO2_CGC_PRIM_DCGE |
+ CIO2_CGC_ROSC_DCGE |
+ CIO2_CGC_XOSC_DCGE |
+ CIO2_CGC_CLKGATE_HOLDOFF << CIO2_CGC_CLKGATE_HOLDOFF_SHIFT |
+ CIO2_CGC_CSI_CLKGATE_HOLDOFF
+ << CIO2_CGC_CSI_CLKGATE_HOLDOFF_SHIFT, base + CIO2_REG_CGC);
+ writel(CIO2_LTRCTRL_LTRDYNEN, base + CIO2_REG_LTRCTRL);
+ writel(CIO2_LTRVAL0_VAL << CIO2_LTRVAL02_VAL_SHIFT |
+ CIO2_LTRVAL0_SCALE << CIO2_LTRVAL02_SCALE_SHIFT |
+ CIO2_LTRVAL1_VAL << CIO2_LTRVAL13_VAL_SHIFT |
+ CIO2_LTRVAL1_SCALE << CIO2_LTRVAL13_SCALE_SHIFT,
+ base + CIO2_REG_LTRVAL01);
+ writel(CIO2_LTRVAL2_VAL << CIO2_LTRVAL02_VAL_SHIFT |
+ CIO2_LTRVAL2_SCALE << CIO2_LTRVAL02_SCALE_SHIFT |
+ CIO2_LTRVAL3_VAL << CIO2_LTRVAL13_VAL_SHIFT |
+ CIO2_LTRVAL3_SCALE << CIO2_LTRVAL13_SCALE_SHIFT,
+ base + CIO2_REG_LTRVAL23);
+
+ for (i = 0; i < CIO2_NUM_DMA_CHAN; i++) {
+ writel(0, base + CIO2_REG_CDMABA(i));
+ writel(0, base + CIO2_REG_CDMAC0(i));
+ writel(0, base + CIO2_REG_CDMAC1(i));
+ }
+
+ /* Enable DMA */
+ writel(q->fbpt_bus_addr >> PAGE_SHIFT,
+ base + CIO2_REG_CDMABA(CIO2_DMA_CHAN));
+
+ writel(num_buffers1 << CIO2_CDMAC0_FBPT_LEN_SHIFT |
+ FBPT_WIDTH << CIO2_CDMAC0_FBPT_WIDTH_SHIFT |
+ CIO2_CDMAC0_DMA_INTR_ON_FE |
+ CIO2_CDMAC0_FBPT_UPDATE_FIFO_FULL |
+ CIO2_CDMAC0_DMA_EN |
+ CIO2_CDMAC0_DMA_INTR_ON_FS |
+ CIO2_CDMAC0_DMA_HALTED, base + CIO2_REG_CDMAC0(CIO2_DMA_CHAN));
+
+ writel(1 << CIO2_CDMAC1_LINENUMUPDATE_SHIFT,
+ base + CIO2_REG_CDMAC1(CIO2_DMA_CHAN));
+
+ writel(0, base + CIO2_REG_PBM_FOPN_ABORT);
+
+ writel(CIO2_PXM_FRF_CFG_CRC_TH << CIO2_PXM_FRF_CFG_CRC_TH_SHIFT |
+ CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NR |
+ CIO2_PXM_FRF_CFG_MSK_ECC_RE |
+ CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NE,
+ base + CIO2_REG_PXM_FRF_CFG(q->csi2.port));
+
+ /* Clear interrupts */
+ writel(CIO2_IRQCTRL_MASK, q->csi_rx_base + CIO2_REG_IRQCTRL_CLEAR);
+ writel(~0, base + CIO2_REG_INT_STS_EXT_OE);
+ writel(~0, base + CIO2_REG_INT_STS_EXT_IE);
+ writel(~0, base + CIO2_REG_INT_STS);
+
+ /* Enable devices, starting from the last device in the pipe */
+ writel(1, q->csi_rx_base + CIO2_REG_MIPIBE_ENABLE);
+ writel(1, q->csi_rx_base + CIO2_REG_CSIRX_ENABLE);
+
+ return 0;
+}
+
+static void cio2_hw_exit(struct cio2_device *cio2, struct cio2_queue *q)
+{
+ void __iomem *base = cio2->base;
+ unsigned int i, maxloops = 1000;
+
+ /* Disable CSI receiver and MIPI backend devices */
+ writel(0, q->csi_rx_base + CIO2_REG_CSIRX_ENABLE);
+ writel(0, q->csi_rx_base + CIO2_REG_MIPIBE_ENABLE);
+
+ /* Halt DMA */
+ writel(0, base + CIO2_REG_CDMAC0(CIO2_DMA_CHAN));
+ do {
+ if (readl(base + CIO2_REG_CDMAC0(CIO2_DMA_CHAN)) &
+ CIO2_CDMAC0_DMA_HALTED)
+ break;
+ usleep_range(1000, 2000);
+ } while (--maxloops);
+ if (!maxloops)
+ dev_err(&cio2->pci_dev->dev,
+ "DMA %i can not be halted\n", CIO2_DMA_CHAN);
+
+ for (i = 0; i < CIO2_NUM_PORTS; i++) {
+ writel(readl(base + CIO2_REG_PXM_FRF_CFG(i)) |
+ CIO2_PXM_FRF_CFG_ABORT, base + CIO2_REG_PXM_FRF_CFG(i));
+ writel(readl(base + CIO2_REG_PBM_FOPN_ABORT) |
+ CIO2_PBM_FOPN_ABORT(i), base + CIO2_REG_PBM_FOPN_ABORT);
+ }
+}
+
+static void cio2_buffer_done(struct cio2_device *cio2, unsigned int dma_chan)
+{
+ struct device *dev = &cio2->pci_dev->dev;
+ struct cio2_queue *q = cio2->cur_queue;
+ int buffers_found = 0;
+ u64 ns = ktime_get_ns();
+
+ if (dma_chan >= CIO2_QUEUES) {
+ dev_err(dev, "bad DMA channel %i\n", dma_chan);
+ return;
+ }
+
+ /* Find out which buffer(s) are ready */
+ do {
+ struct cio2_fbpt_entry *const entry =
+ &q->fbpt[q->bufs_first * CIO2_MAX_LOPS];
+ struct cio2_buffer *b;
+
+ if (entry->first_entry.ctrl & CIO2_FBPT_CTRL_VALID)
+ break;
+
+ b = q->bufs[q->bufs_first];
+ if (b) {
+ unsigned int bytes = entry[1].second_entry.num_of_bytes;
+
+ q->bufs[q->bufs_first] = NULL;
+ atomic_dec(&q->bufs_queued);
+ dev_dbg(&cio2->pci_dev->dev,
+ "buffer %i done\n", b->vbb.vb2_buf.index);
+
+ b->vbb.vb2_buf.timestamp = ns;
+ b->vbb.field = V4L2_FIELD_NONE;
+ b->vbb.sequence = atomic_read(&q->frame_sequence);
+ if (b->vbb.vb2_buf.planes[0].length != bytes)
+ dev_warn(dev, "buffer length is %d received %d\n",
+ b->vbb.vb2_buf.planes[0].length,
+ bytes);
+ vb2_buffer_done(&b->vbb.vb2_buf, VB2_BUF_STATE_DONE);
+ }
+ atomic_inc(&q->frame_sequence);
+ cio2_fbpt_entry_init_dummy(cio2, entry);
+ q->bufs_first = (q->bufs_first + 1) % CIO2_MAX_BUFFERS;
+ buffers_found++;
+ } while (1);
+
+ if (buffers_found == 0)
+ dev_warn(&cio2->pci_dev->dev,
+ "no ready buffers found on DMA channel %u\n",
+ dma_chan);
+}
+
+static void cio2_queue_event_sof(struct cio2_device *cio2, struct cio2_queue *q)
+{
+ /*
+ * For the user space camera control algorithms it is essential
+ * to know when the reception of a frame has begun. That's often
+ * the best timing information to get from the hardware.
+ */
+ struct v4l2_event event = {
+ .type = V4L2_EVENT_FRAME_SYNC,
+ .u.frame_sync.frame_sequence = atomic_read(&q->frame_sequence),
+ };
+
+ v4l2_event_queue(q->subdev.devnode, &event);
+}
+
+static const char *const cio2_irq_errs[] = {
+ "single packet header error corrected",
+ "multiple packet header errors detected",
+ "payload checksum (CRC) error",
+ "fifo overflow",
+ "reserved short packet data type detected",
+ "reserved long packet data type detected",
+ "incomplete long packet detected",
+ "frame sync error",
+ "line sync error",
+ "DPHY start of transmission error",
+ "DPHY synchronization error",
+ "escape mode error",
+ "escape mode trigger event",
+ "escape mode ultra-low power state for data lane(s)",
+ "escape mode ultra-low power state exit for clock lane",
+ "inter-frame short packet discarded",
+ "inter-frame long packet discarded",
+ "non-matching Long Packet stalled",
+};
+
+static const char *const cio2_port_errs[] = {
+ "ECC recoverable",
+ "DPHY not recoverable",
+ "ECC not recoverable",
+ "CRC error",
+ "INTERFRAMEDATA",
+ "PKT2SHORT",
+ "PKT2LONG",
+};
+
+static irqreturn_t cio2_irq(int irq, void *cio2_ptr)
+{
+ struct cio2_device *cio2 = cio2_ptr;
+ void __iomem *const base = cio2->base;
+ struct device *dev = &cio2->pci_dev->dev;
+ u32 int_status, int_clear;
+
+ int_status = readl(base + CIO2_REG_INT_STS);
+ int_clear = int_status;
+
+ if (!int_status)
+ return IRQ_NONE;
+
+ if (int_status & CIO2_INT_IOOE) {
+ /*
+ * Interrupt on Output Error:
+ * 1) SRAM is full and FS received, or
+ * 2) An invalid bit detected by DMA.
+ */
+ u32 oe_status, oe_clear;
+
+ oe_clear = readl(base + CIO2_REG_INT_STS_EXT_OE);
+ oe_status = oe_clear;
+
+ if (oe_status & CIO2_INT_EXT_OE_DMAOE_MASK) {
+ dev_err(dev, "DMA output error: 0x%x\n",
+ (oe_status & CIO2_INT_EXT_OE_DMAOE_MASK)
+ >> CIO2_INT_EXT_OE_DMAOE_SHIFT);
+ oe_status &= ~CIO2_INT_EXT_OE_DMAOE_MASK;
+ }
+ if (oe_status & CIO2_INT_EXT_OE_OES_MASK) {
+ dev_err(dev, "DMA output error on CSI2 buses: 0x%x\n",
+ (oe_status & CIO2_INT_EXT_OE_OES_MASK)
+ >> CIO2_INT_EXT_OE_OES_SHIFT);
+ oe_status &= ~CIO2_INT_EXT_OE_OES_MASK;
+ }
+ writel(oe_clear, base + CIO2_REG_INT_STS_EXT_OE);
+ if (oe_status)
+ dev_warn(dev, "unknown interrupt 0x%x on OE\n",
+ oe_status);
+ int_status &= ~CIO2_INT_IOOE;
+ }
+
+ if (int_status & CIO2_INT_IOC_MASK) {
+ /* DMA IO done -- frame ready */
+ u32 clr = 0;
+ unsigned int d;
+
+ for (d = 0; d < CIO2_NUM_DMA_CHAN; d++)
+ if (int_status & CIO2_INT_IOC(d)) {
+ clr |= CIO2_INT_IOC(d);
+ cio2_buffer_done(cio2, d);
+ }
+ int_status &= ~clr;
+ }
+
+ if (int_status & CIO2_INT_IOS_IOLN_MASK) {
+ /* DMA IO starts or reached specified line */
+ u32 clr = 0;
+ unsigned int d;
+
+ for (d = 0; d < CIO2_NUM_DMA_CHAN; d++)
+ if (int_status & CIO2_INT_IOS_IOLN(d)) {
+ clr |= CIO2_INT_IOS_IOLN(d);
+ if (d == CIO2_DMA_CHAN)
+ cio2_queue_event_sof(cio2,
+ cio2->cur_queue);
+ }
+ int_status &= ~clr;
+ }
+
+ if (int_status & (CIO2_INT_IOIE | CIO2_INT_IOIRQ)) {
+ /* CSI2 receiver (error) interrupt */
+ u32 ie_status, ie_clear;
+ unsigned int port;
+
+ ie_clear = readl(base + CIO2_REG_INT_STS_EXT_IE);
+ ie_status = ie_clear;
+
+ for (port = 0; port < CIO2_NUM_PORTS; port++) {
+ u32 port_status = (ie_status >> (port * 8)) & 0xff;
+ u32 err_mask = BIT_MASK(ARRAY_SIZE(cio2_port_errs)) - 1;
+ void __iomem *const csi_rx_base =
+ base + CIO2_REG_PIPE_BASE(port);
+ unsigned int i;
+
+ while (port_status & err_mask) {
+ i = ffs(port_status) - 1;
+ dev_err(dev, "port %i error %s\n",
+ port, cio2_port_errs[i]);
+ ie_status &= ~BIT(port * 8 + i);
+ port_status &= ~BIT(i);
+ }
+
+ if (ie_status & CIO2_INT_EXT_IE_IRQ(port)) {
+ u32 csi2_status, csi2_clear;
+
+ csi2_status = readl(csi_rx_base +
+ CIO2_REG_IRQCTRL_STATUS);
+ csi2_clear = csi2_status;
+ err_mask =
+ BIT_MASK(ARRAY_SIZE(cio2_irq_errs)) - 1;
+
+ while (csi2_status & err_mask) {
+ i = ffs(csi2_status) - 1;
+ dev_err(dev,
+ "CSI-2 receiver port %i: %s\n",
+ port, cio2_irq_errs[i]);
+ csi2_status &= ~BIT(i);
+ }
+
+ writel(csi2_clear,
+ csi_rx_base + CIO2_REG_IRQCTRL_CLEAR);
+ if (csi2_status)
+ dev_warn(dev,
+ "unknown CSI2 error 0x%x on port %i\n",
+ csi2_status, port);
+
+ ie_status &= ~CIO2_INT_EXT_IE_IRQ(port);
+ }
+ }
+
+ writel(ie_clear, base + CIO2_REG_INT_STS_EXT_IE);
+ if (ie_status)
+ dev_warn(dev, "unknown interrupt 0x%x on IE\n",
+ ie_status);
+
+ int_status &= ~(CIO2_INT_IOIE | CIO2_INT_IOIRQ);
+ }
+
+ writel(int_clear, base + CIO2_REG_INT_STS);
+ if (int_status)
+ dev_warn(dev, "unknown interrupt 0x%x on INT\n", int_status);
+
+ return IRQ_HANDLED;
+}
+
+/**************** Videobuf2 interface ****************/
+
+static void cio2_vb2_return_all_buffers(struct cio2_queue *q,
+ enum vb2_buffer_state state)
+{
+ unsigned int i;
+
+ for (i = 0; i < CIO2_MAX_BUFFERS; i++) {
+ if (q->bufs[i]) {
+ atomic_dec(&q->bufs_queued);
+ vb2_buffer_done(&q->bufs[i]->vbb.vb2_buf,
+ state);
+ }
+ }
+}
+
+static int cio2_vb2_queue_setup(struct vb2_queue *vq,
+ unsigned int *num_buffers,
+ unsigned int *num_planes,
+ unsigned int sizes[],
+ struct device *alloc_devs[])
+{
+ struct cio2_device *cio2 = vb2_get_drv_priv(vq);
+ struct cio2_queue *q = vb2q_to_cio2_queue(vq);
+ unsigned int i;
+
+ *num_planes = q->format.num_planes;
+
+ for (i = 0; i < *num_planes; ++i) {
+ sizes[i] = q->format.plane_fmt[i].sizeimage;
+ alloc_devs[i] = &cio2->pci_dev->dev;
+ }
+
+ *num_buffers = clamp_val(*num_buffers, 1, CIO2_MAX_BUFFERS);
+
+ /* Initialize buffer queue */
+ for (i = 0; i < CIO2_MAX_BUFFERS; i++) {
+ q->bufs[i] = NULL;
+ cio2_fbpt_entry_init_dummy(cio2, &q->fbpt[i * CIO2_MAX_LOPS]);
+ }
+ atomic_set(&q->bufs_queued, 0);
+ q->bufs_first = 0;
+ q->bufs_next = 0;
+
+ return 0;
+}
+
+/* Called after each buffer is allocated */
+static int cio2_vb2_buf_init(struct vb2_buffer *vb)
+{
+ struct cio2_device *cio2 = vb2_get_drv_priv(vb->vb2_queue);
+ struct device *dev = &cio2->pci_dev->dev;
+ struct cio2_buffer *b =
+ container_of(vb, struct cio2_buffer, vbb.vb2_buf);
+ static const unsigned int entries_per_page =
+ CIO2_PAGE_SIZE / sizeof(u32);
+ unsigned int pages = DIV_ROUND_UP(vb->planes[0].length, CIO2_PAGE_SIZE);
+ unsigned int lops = DIV_ROUND_UP(pages + 1, entries_per_page);
+ struct sg_table *sg;
+ struct sg_page_iter sg_iter;
+ int i, j;
+
+ if (lops <= 0 || lops > CIO2_MAX_LOPS) {
+ dev_err(dev, "%s: bad buffer size (%i)\n", __func__,
+ vb->planes[0].length);
+ return -ENOSPC; /* Should never happen */
+ }
+
+ memset(b->lop, 0, sizeof(b->lop));
+ /* Allocate LOP table */
+ for (i = 0; i < lops; i++) {
+ b->lop[i] = dma_alloc_coherent(dev, CIO2_PAGE_SIZE,
+ &b->lop_bus_addr[i], GFP_KERNEL);
+ if (!b->lop[i])
+ goto fail;
+ }
+
+ /* Fill LOP */
+ sg = vb2_dma_sg_plane_desc(vb, 0);
+ if (!sg)
+ return -ENOMEM;
+
+ if (sg->nents && sg->sgl)
+ b->offset = sg->sgl->offset;
+
+ i = j = 0;
+ for_each_sg_page(sg->sgl, &sg_iter, sg->nents, 0) {
+ if (!pages--)
+ break;
+ b->lop[i][j] = sg_page_iter_dma_address(&sg_iter) >> PAGE_SHIFT;
+ j++;
+ if (j == entries_per_page) {
+ i++;
+ j = 0;
+ }
+ }
+
+ b->lop[i][j] = cio2->dummy_page_bus_addr >> PAGE_SHIFT;
+ return 0;
+fail:
+ for (i--; i >= 0; i--)
+ dma_free_coherent(dev, CIO2_PAGE_SIZE,
+ b->lop[i], b->lop_bus_addr[i]);
+ return -ENOMEM;
+}
+
+/* Transfer buffer ownership to cio2 */
+static void cio2_vb2_buf_queue(struct vb2_buffer *vb)
+{
+ struct cio2_device *cio2 = vb2_get_drv_priv(vb->vb2_queue);
+ struct cio2_queue *q =
+ container_of(vb->vb2_queue, struct cio2_queue, vbq);
+ struct cio2_buffer *b =
+ container_of(vb, struct cio2_buffer, vbb.vb2_buf);
+ struct cio2_fbpt_entry *entry;
+ unsigned long flags;
+ unsigned int i, j, next = q->bufs_next;
+ int bufs_queued = atomic_inc_return(&q->bufs_queued);
+ u32 fbpt_rp;
+
+ dev_dbg(&cio2->pci_dev->dev, "queue buffer %d\n", vb->index);
+
+ /*
+ * This code queues the buffer to the CIO2 DMA engine, which starts
+ * running once streaming has started. It is possible that this code
+ * gets pre-empted due to increased CPU load. Upon this, the driver
+ * does not get an opportunity to queue new buffers to the CIO2 DMA
+ * engine. When the DMA engine encounters an FBPT entry without the
+ * VALID bit set, the DMA engine halts, which requires a restart of
+ * the DMA engine and sensor, to continue streaming.
+ * This is not desired and is highly unlikely given that there are
+ * 32 FBPT entries that the DMA engine needs to process, to run into
+ * an FBPT entry, without the VALID bit set. We try to mitigate this
+ * by disabling interrupts for the duration of this queueing.
+ */
+ local_irq_save(flags);
+
+ fbpt_rp = (readl(cio2->base + CIO2_REG_CDMARI(CIO2_DMA_CHAN))
+ >> CIO2_CDMARI_FBPT_RP_SHIFT)
+ & CIO2_CDMARI_FBPT_RP_MASK;
+
+ /*
+ * fbpt_rp is the fbpt entry that the dma is currently working
+ * on, but since it could jump to next entry at any time,
+ * assume that we might already be there.
+ */
+ fbpt_rp = (fbpt_rp + 1) % CIO2_MAX_BUFFERS;
+
+ if (bufs_queued <= 1 || fbpt_rp == next)
+ /* Buffers were drained */
+ next = (fbpt_rp + 1) % CIO2_MAX_BUFFERS;
+
+ for (i = 0; i < CIO2_MAX_BUFFERS; i++) {
+ /*
+ * We have allocated CIO2_MAX_BUFFERS circularly for the
+ * hw, the user has requested N buffer queue. The driver
+ * ensures N <= CIO2_MAX_BUFFERS and guarantees that whenever
+ * user queues a buffer, there necessarily is a free buffer.
+ */
+ if (!q->bufs[next]) {
+ q->bufs[next] = b;
+ entry = &q->fbpt[next * CIO2_MAX_LOPS];
+ cio2_fbpt_entry_init_buf(cio2, b, entry);
+ local_irq_restore(flags);
+ q->bufs_next = (next + 1) % CIO2_MAX_BUFFERS;
+ for (j = 0; j < vb->num_planes; j++)
+ vb2_set_plane_payload(vb, j,
+ q->format.plane_fmt[j].sizeimage);
+ return;
+ }
+
+ dev_dbg(&cio2->pci_dev->dev, "entry %i was full!\n", next);
+ next = (next + 1) % CIO2_MAX_BUFFERS;
+ }
+
+ local_irq_restore(flags);
+ dev_err(&cio2->pci_dev->dev, "error: all cio2 entries were full!\n");
+ atomic_dec(&q->bufs_queued);
+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+}
+
+/* Called when each buffer is freed */
+static void cio2_vb2_buf_cleanup(struct vb2_buffer *vb)
+{
+ struct cio2_device *cio2 = vb2_get_drv_priv(vb->vb2_queue);
+ struct cio2_buffer *b =
+ container_of(vb, struct cio2_buffer, vbb.vb2_buf);
+ unsigned int i;
+
+ /* Free LOP table */
+ for (i = 0; i < CIO2_MAX_LOPS; i++) {
+ if (b->lop[i])
+ dma_free_coherent(&cio2->pci_dev->dev, CIO2_PAGE_SIZE,
+ b->lop[i], b->lop_bus_addr[i]);
+ }
+}
+
+static int cio2_vb2_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+ struct cio2_queue *q = vb2q_to_cio2_queue(vq);
+ struct cio2_device *cio2 = vb2_get_drv_priv(vq);
+ int r;
+
+ cio2->cur_queue = q;
+ atomic_set(&q->frame_sequence, 0);
+
+ r = pm_runtime_get_sync(&cio2->pci_dev->dev);
+ if (r < 0) {
+ dev_info(&cio2->pci_dev->dev, "failed to set power %d\n", r);
+ pm_runtime_put_noidle(&cio2->pci_dev->dev);
+ return r;
+ }
+
+ r = media_pipeline_start(&q->vdev.entity, &q->pipe);
+ if (r)
+ goto fail_pipeline;
+
+ r = cio2_hw_init(cio2, q);
+ if (r)
+ goto fail_hw;
+
+ /* Start streaming on sensor */
+ r = v4l2_subdev_call(q->sensor, video, s_stream, 1);
+ if (r)
+ goto fail_csi2_subdev;
+
+ cio2->streaming = true;
+
+ return 0;
+
+fail_csi2_subdev:
+ cio2_hw_exit(cio2, q);
+fail_hw:
+ media_pipeline_stop(&q->vdev.entity);
+fail_pipeline:
+ dev_dbg(&cio2->pci_dev->dev, "failed to start streaming (%d)\n", r);
+ cio2_vb2_return_all_buffers(q, VB2_BUF_STATE_QUEUED);
+ pm_runtime_put(&cio2->pci_dev->dev);
+
+ return r;
+}
+
+static void cio2_vb2_stop_streaming(struct vb2_queue *vq)
+{
+ struct cio2_queue *q = vb2q_to_cio2_queue(vq);
+ struct cio2_device *cio2 = vb2_get_drv_priv(vq);
+
+ if (v4l2_subdev_call(q->sensor, video, s_stream, 0))
+ dev_err(&cio2->pci_dev->dev,
+ "failed to stop sensor streaming\n");
+
+ cio2_hw_exit(cio2, q);
+ cio2_vb2_return_all_buffers(q, VB2_BUF_STATE_ERROR);
+ media_pipeline_stop(&q->vdev.entity);
+ pm_runtime_put(&cio2->pci_dev->dev);
+ cio2->streaming = false;
+}
+
+static const struct vb2_ops cio2_vb2_ops = {
+ .buf_init = cio2_vb2_buf_init,
+ .buf_queue = cio2_vb2_buf_queue,
+ .buf_cleanup = cio2_vb2_buf_cleanup,
+ .queue_setup = cio2_vb2_queue_setup,
+ .start_streaming = cio2_vb2_start_streaming,
+ .stop_streaming = cio2_vb2_stop_streaming,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+};
+
+/**************** V4L2 interface ****************/
+
+static int cio2_v4l2_querycap(struct file *file, void *fh,
+ struct v4l2_capability *cap)
+{
+ struct cio2_device *cio2 = video_drvdata(file);
+
+ strlcpy(cap->driver, CIO2_NAME, sizeof(cap->driver));
+ strlcpy(cap->card, CIO2_DEVICE_NAME, sizeof(cap->card));
+ snprintf(cap->bus_info, sizeof(cap->bus_info),
+ "PCI:%s", pci_name(cio2->pci_dev));
+
+ return 0;
+}
+
+static int cio2_v4l2_enum_fmt(struct file *file, void *fh,
+ struct v4l2_fmtdesc *f)
+{
+ if (f->index >= ARRAY_SIZE(formats))
+ return -EINVAL;
+
+ f->pixelformat = formats[f->index].fourcc;
+
+ return 0;
+}
+
+/* The format is validated in cio2_video_link_validate() */
+static int cio2_v4l2_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct cio2_queue *q = file_to_cio2_queue(file);
+
+ f->fmt.pix_mp = q->format;
+
+ return 0;
+}
+
+static int cio2_v4l2_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+ const struct ipu3_cio2_fmt *fmt;
+ struct v4l2_pix_format_mplane *mpix = &f->fmt.pix_mp;
+
+ fmt = cio2_find_format(&mpix->pixelformat, NULL);
+ if (!fmt)
+ fmt = &formats[0];
+
+ /* Only supports up to 4224x3136 */
+ if (mpix->width > CIO2_IMAGE_MAX_WIDTH)
+ mpix->width = CIO2_IMAGE_MAX_WIDTH;
+ if (mpix->height > CIO2_IMAGE_MAX_LENGTH)
+ mpix->height = CIO2_IMAGE_MAX_LENGTH;
+
+ mpix->num_planes = 1;
+ mpix->pixelformat = fmt->fourcc;
+ mpix->colorspace = V4L2_COLORSPACE_RAW;
+ mpix->field = V4L2_FIELD_NONE;
+ memset(mpix->reserved, 0, sizeof(mpix->reserved));
+ mpix->plane_fmt[0].bytesperline = cio2_bytesperline(mpix->width);
+ mpix->plane_fmt[0].sizeimage = mpix->plane_fmt[0].bytesperline *
+ mpix->height;
+ memset(mpix->plane_fmt[0].reserved, 0,
+ sizeof(mpix->plane_fmt[0].reserved));
+
+ /* use default */
+ mpix->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+ mpix->quantization = V4L2_QUANTIZATION_DEFAULT;
+ mpix->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+
+ return 0;
+}
+
+static int cio2_v4l2_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct cio2_queue *q = file_to_cio2_queue(file);
+
+ cio2_v4l2_try_fmt(file, fh, f);
+ q->format = f->fmt.pix_mp;
+
+ return 0;
+}
+
+static int
+cio2_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
+{
+ if (input->index > 0)
+ return -EINVAL;
+
+ strlcpy(input->name, "camera", sizeof(input->name));
+ input->type = V4L2_INPUT_TYPE_CAMERA;
+
+ return 0;
+}
+
+static int
+cio2_video_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ *input = 0;
+
+ return 0;
+}
+
+static int
+cio2_video_s_input(struct file *file, void *fh, unsigned int input)
+{
+ return input == 0 ? 0 : -EINVAL;
+}
+
+static const struct v4l2_file_operations cio2_v4l2_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = video_ioctl2,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .poll = vb2_fop_poll,
+ .mmap = vb2_fop_mmap,
+};
+
+static const struct v4l2_ioctl_ops cio2_v4l2_ioctl_ops = {
+ .vidioc_querycap = cio2_v4l2_querycap,
+ .vidioc_enum_fmt_vid_cap_mplane = cio2_v4l2_enum_fmt,
+ .vidioc_g_fmt_vid_cap_mplane = cio2_v4l2_g_fmt,
+ .vidioc_s_fmt_vid_cap_mplane = cio2_v4l2_s_fmt,
+ .vidioc_try_fmt_vid_cap_mplane = cio2_v4l2_try_fmt,
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+ .vidioc_expbuf = vb2_ioctl_expbuf,
+ .vidioc_enum_input = cio2_video_enum_input,
+ .vidioc_g_input = cio2_video_g_input,
+ .vidioc_s_input = cio2_video_s_input,
+};
+
+static int cio2_subdev_subscribe_event(struct v4l2_subdev *sd,
+ struct v4l2_fh *fh,
+ struct v4l2_event_subscription *sub)
+{
+ if (sub->type != V4L2_EVENT_FRAME_SYNC)
+ return -EINVAL;
+
+ /* Line number. For now only zero accepted. */
+ if (sub->id != 0)
+ return -EINVAL;
+
+ return v4l2_event_subscribe(fh, sub, 0, NULL);
+}
+
+static int cio2_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+ struct v4l2_mbus_framefmt *format;
+ const struct v4l2_mbus_framefmt fmt_default = {
+ .width = 1936,
+ .height = 1096,
+ .code = formats[0].mbus_code,
+ .field = V4L2_FIELD_NONE,
+ .colorspace = V4L2_COLORSPACE_RAW,
+ .ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT,
+ .quantization = V4L2_QUANTIZATION_DEFAULT,
+ .xfer_func = V4L2_XFER_FUNC_DEFAULT,
+ };
+
+ /* Initialize try_fmt */
+ format = v4l2_subdev_get_try_format(sd, fh->pad, CIO2_PAD_SINK);
+ *format = fmt_default;
+
+ /* same as sink */
+ format = v4l2_subdev_get_try_format(sd, fh->pad, CIO2_PAD_SOURCE);
+ *format = fmt_default;
+
+ return 0;
+}
+
+/*
+ * cio2_subdev_get_fmt - Handle get format by pads subdev method
+ * @sd : pointer to v4l2 subdev structure
+ * @cfg: V4L2 subdev pad config
+ * @fmt: pointer to v4l2 subdev format structure
+ * return -EINVAL or zero on success
+ */
+static int cio2_subdev_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev);
+ struct v4l2_subdev_format format;
+ int ret;
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+ fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
+ return 0;
+ }
+
+ if (fmt->pad == CIO2_PAD_SINK) {
+ format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ ret = v4l2_subdev_call(sd, pad, get_fmt, NULL,
+ &format);
+
+ if (ret)
+ return ret;
+ /* update colorspace etc */
+ q->subdev_fmt.colorspace = format.format.colorspace;
+ q->subdev_fmt.ycbcr_enc = format.format.ycbcr_enc;
+ q->subdev_fmt.quantization = format.format.quantization;
+ q->subdev_fmt.xfer_func = format.format.xfer_func;
+ }
+
+ fmt->format = q->subdev_fmt;
+
+ return 0;
+}
+
+/*
+ * cio2_subdev_set_fmt - Handle set format by pads subdev method
+ * @sd : pointer to v4l2 subdev structure
+ * @cfg: V4L2 subdev pad config
+ * @fmt: pointer to v4l2 subdev format structure
+ * return -EINVAL or zero on success
+ */
+static int cio2_subdev_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct cio2_queue *q = container_of(sd, struct cio2_queue, subdev);
+
+ /*
+ * Only allow setting sink pad format;
+ * source always propagates from sink
+ */
+ if (fmt->pad == CIO2_PAD_SOURCE)
+ return cio2_subdev_get_fmt(sd, cfg, fmt);
+
+ if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+ *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
+ } else {
+ /* It's the sink, allow changing frame size */
+ q->subdev_fmt.width = fmt->format.width;
+ q->subdev_fmt.height = fmt->format.height;
+ q->subdev_fmt.code = fmt->format.code;
+ fmt->format = q->subdev_fmt;
+ }
+
+ return 0;
+}
+
+static int cio2_subdev_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->index >= ARRAY_SIZE(formats))
+ return -EINVAL;
+
+ code->code = formats[code->index].mbus_code;
+ return 0;
+}
+
+static int cio2_subdev_link_validate_get_format(struct media_pad *pad,
+ struct v4l2_subdev_format *fmt)
+{
+ if (is_media_entity_v4l2_subdev(pad->entity)) {
+ struct v4l2_subdev *sd =
+ media_entity_to_v4l2_subdev(pad->entity);
+
+ fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
+ fmt->pad = pad->index;
+ return v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
+ }
+
+ return -EINVAL;
+}
+
+static int cio2_video_link_validate(struct media_link *link)
+{
+ struct video_device *vd = container_of(link->sink->entity,
+ struct video_device, entity);
+ struct cio2_queue *q = container_of(vd, struct cio2_queue, vdev);
+ struct cio2_device *cio2 = video_get_drvdata(vd);
+ struct v4l2_subdev_format source_fmt;
+ int ret;
+
+ if (!media_entity_remote_pad(link->sink->entity->pads)) {
+ dev_info(&cio2->pci_dev->dev,
+ "video node %s pad not connected\n", vd->name);
+ return -ENOTCONN;
+ }
+
+ ret = cio2_subdev_link_validate_get_format(link->source, &source_fmt);
+ if (ret < 0)
+ return 0;
+
+ if (source_fmt.format.width != q->format.width ||
+ source_fmt.format.height != q->format.height) {
+ dev_err(&cio2->pci_dev->dev,
+ "Wrong width or height %ux%u (%ux%u expected)\n",
+ q->format.width, q->format.height,
+ source_fmt.format.width, source_fmt.format.height);
+ return -EINVAL;
+ }
+
+ if (!cio2_find_format(&q->format.pixelformat, &source_fmt.format.code))
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops cio2_subdev_core_ops = {
+ .subscribe_event = cio2_subdev_subscribe_event,
+ .unsubscribe_event = v4l2_event_subdev_unsubscribe,
+};
+
+static const struct v4l2_subdev_internal_ops cio2_subdev_internal_ops = {
+ .open = cio2_subdev_open,
+};
+
+static const struct v4l2_subdev_pad_ops cio2_subdev_pad_ops = {
+ .link_validate = v4l2_subdev_link_validate_default,
+ .get_fmt = cio2_subdev_get_fmt,
+ .set_fmt = cio2_subdev_set_fmt,
+ .enum_mbus_code = cio2_subdev_enum_mbus_code,
+};
+
+static const struct v4l2_subdev_ops cio2_subdev_ops = {
+ .core = &cio2_subdev_core_ops,
+ .pad = &cio2_subdev_pad_ops,
+};
+
+/******* V4L2 sub-device asynchronous registration callbacks***********/
+
+struct sensor_async_subdev {
+ struct v4l2_async_subdev asd;
+ struct csi2_bus_info csi2;
+};
+
+/* The .bound() notifier callback when a match is found */
+static int cio2_notifier_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct cio2_device *cio2 = container_of(notifier,
+ struct cio2_device, notifier);
+ struct sensor_async_subdev *s_asd = container_of(asd,
+ struct sensor_async_subdev, asd);
+ struct cio2_queue *q;
+
+ if (cio2->queue[s_asd->csi2.port].sensor)
+ return -EBUSY;
+
+ q = &cio2->queue[s_asd->csi2.port];
+
+ q->csi2 = s_asd->csi2;
+ q->sensor = sd;
+ q->csi_rx_base = cio2->base + CIO2_REG_PIPE_BASE(q->csi2.port);
+
+ return 0;
+}
+
+/* The .unbind callback */
+static void cio2_notifier_unbind(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_subdev *asd)
+{
+ struct cio2_device *cio2 = container_of(notifier,
+ struct cio2_device, notifier);
+ struct sensor_async_subdev *s_asd = container_of(asd,
+ struct sensor_async_subdev, asd);
+
+ cio2->queue[s_asd->csi2.port].sensor = NULL;
+}
+
+/* .complete() is called after all subdevices have been located */
+static int cio2_notifier_complete(struct v4l2_async_notifier *notifier)
+{
+ struct cio2_device *cio2 = container_of(notifier, struct cio2_device,
+ notifier);
+ struct sensor_async_subdev *s_asd;
+ struct cio2_queue *q;
+ unsigned int i, pad;
+ int ret;
+
+ for (i = 0; i < notifier->num_subdevs; i++) {
+ s_asd = container_of(cio2->notifier.subdevs[i],
+ struct sensor_async_subdev, asd);
+ q = &cio2->queue[s_asd->csi2.port];
+
+ for (pad = 0; pad < q->sensor->entity.num_pads; pad++)
+ if (q->sensor->entity.pads[pad].flags &
+ MEDIA_PAD_FL_SOURCE)
+ break;
+
+ if (pad == q->sensor->entity.num_pads) {
+ dev_err(&cio2->pci_dev->dev,
+ "failed to find src pad for %s\n",
+ q->sensor->name);
+ return -ENXIO;
+ }
+
+ ret = media_create_pad_link(
+ &q->sensor->entity, pad,
+ &q->subdev.entity, CIO2_PAD_SINK,
+ 0);
+ if (ret) {
+ dev_err(&cio2->pci_dev->dev,
+ "failed to create link for %s\n",
+ cio2->queue[i].sensor->name);
+ return ret;
+ }
+ }
+
+ return v4l2_device_register_subdev_nodes(&cio2->v4l2_dev);
+}
+
+static const struct v4l2_async_notifier_operations cio2_async_ops = {
+ .bound = cio2_notifier_bound,
+ .unbind = cio2_notifier_unbind,
+ .complete = cio2_notifier_complete,
+};
+
+static int cio2_fwnode_parse(struct device *dev,
+ struct v4l2_fwnode_endpoint *vep,
+ struct v4l2_async_subdev *asd)
+{
+ struct sensor_async_subdev *s_asd =
+ container_of(asd, struct sensor_async_subdev, asd);
+
+ if (vep->bus_type != V4L2_MBUS_CSI2) {
+ dev_err(dev, "Only CSI2 bus type is currently supported\n");
+ return -EINVAL;
+ }
+
+ s_asd->csi2.port = vep->base.port;
+ s_asd->csi2.lanes = vep->bus.mipi_csi2.num_data_lanes;
+
+ return 0;
+}
+
+static int cio2_notifier_init(struct cio2_device *cio2)
+{
+ int ret;
+
+ ret = v4l2_async_notifier_parse_fwnode_endpoints(
+ &cio2->pci_dev->dev, &cio2->notifier,
+ sizeof(struct sensor_async_subdev),
+ cio2_fwnode_parse);
+ if (ret < 0)
+ return ret;
+
+ if (!cio2->notifier.num_subdevs)
+ return -ENODEV; /* no endpoint */
+
+ cio2->notifier.ops = &cio2_async_ops;
+ ret = v4l2_async_notifier_register(&cio2->v4l2_dev, &cio2->notifier);
+ if (ret) {
+ dev_err(&cio2->pci_dev->dev,
+ "failed to register async notifier : %d\n", ret);
+ v4l2_async_notifier_cleanup(&cio2->notifier);
+ }
+
+ return ret;
+}
+
+static void cio2_notifier_exit(struct cio2_device *cio2)
+{
+ v4l2_async_notifier_unregister(&cio2->notifier);
+ v4l2_async_notifier_cleanup(&cio2->notifier);
+}
+
+/**************** Queue initialization ****************/
+static const struct media_entity_operations cio2_media_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+static const struct media_entity_operations cio2_video_entity_ops = {
+ .link_validate = cio2_video_link_validate,
+};
+
+static int cio2_queue_init(struct cio2_device *cio2, struct cio2_queue *q)
+{
+ static const u32 default_width = 1936;
+ static const u32 default_height = 1096;
+ const struct ipu3_cio2_fmt dflt_fmt = formats[0];
+
+ struct video_device *vdev = &q->vdev;
+ struct vb2_queue *vbq = &q->vbq;
+ struct v4l2_subdev *subdev = &q->subdev;
+ struct v4l2_mbus_framefmt *fmt;
+ int r;
+
+ /* Initialize miscellaneous variables */
+ mutex_init(&q->lock);
+
+ /* Initialize formats to default values */
+ fmt = &q->subdev_fmt;
+ fmt->width = default_width;
+ fmt->height = default_height;
+ fmt->code = dflt_fmt.mbus_code;
+ fmt->field = V4L2_FIELD_NONE;
+
+ q->format.width = default_width;
+ q->format.height = default_height;
+ q->format.pixelformat = dflt_fmt.fourcc;
+ q->format.colorspace = V4L2_COLORSPACE_RAW;
+ q->format.field = V4L2_FIELD_NONE;
+ q->format.num_planes = 1;
+ q->format.plane_fmt[0].bytesperline =
+ cio2_bytesperline(q->format.width);
+ q->format.plane_fmt[0].sizeimage = q->format.plane_fmt[0].bytesperline *
+ q->format.height;
+
+ /* Initialize fbpt */
+ r = cio2_fbpt_init(cio2, q);
+ if (r)
+ goto fail_fbpt;
+
+ /* Initialize media entities */
+ q->subdev_pads[CIO2_PAD_SINK].flags = MEDIA_PAD_FL_SINK |
+ MEDIA_PAD_FL_MUST_CONNECT;
+ q->subdev_pads[CIO2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+ subdev->entity.ops = &cio2_media_ops;
+ subdev->internal_ops = &cio2_subdev_internal_ops;
+ r = media_entity_pads_init(&subdev->entity, CIO2_PADS, q->subdev_pads);
+ if (r) {
+ dev_err(&cio2->pci_dev->dev,
+ "failed initialize subdev media entity (%d)\n", r);
+ goto fail_subdev_media_entity;
+ }
+
+ q->vdev_pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
+ vdev->entity.ops = &cio2_video_entity_ops;
+ r = media_entity_pads_init(&vdev->entity, 1, &q->vdev_pad);
+ if (r) {
+ dev_err(&cio2->pci_dev->dev,
+ "failed initialize videodev media entity (%d)\n", r);
+ goto fail_vdev_media_entity;
+ }
+
+ /* Initialize subdev */
+ v4l2_subdev_init(subdev, &cio2_subdev_ops);
+ subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
+ subdev->owner = THIS_MODULE;
+ snprintf(subdev->name, sizeof(subdev->name),
+ CIO2_ENTITY_NAME " %td", q - cio2->queue);
+ v4l2_set_subdevdata(subdev, cio2);
+ r = v4l2_device_register_subdev(&cio2->v4l2_dev, subdev);
+ if (r) {
+ dev_err(&cio2->pci_dev->dev,
+ "failed initialize subdev (%d)\n", r);
+ goto fail_subdev;
+ }
+
+ /* Initialize vbq */
+ vbq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ vbq->io_modes = VB2_USERPTR | VB2_MMAP | VB2_DMABUF;
+ vbq->ops = &cio2_vb2_ops;
+ vbq->mem_ops = &vb2_dma_sg_memops;
+ vbq->buf_struct_size = sizeof(struct cio2_buffer);
+ vbq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+ vbq->min_buffers_needed = 1;
+ vbq->drv_priv = cio2;
+ vbq->lock = &q->lock;
+ r = vb2_queue_init(vbq);
+ if (r) {
+ dev_err(&cio2->pci_dev->dev,
+ "failed to initialize videobuf2 queue (%d)\n", r);
+ goto fail_vbq;
+ }
+
+ /* Initialize vdev */
+ snprintf(vdev->name, sizeof(vdev->name),
+ "%s %td", CIO2_NAME, q - cio2->queue);
+ vdev->release = video_device_release_empty;
+ vdev->fops = &cio2_v4l2_fops;
+ vdev->ioctl_ops = &cio2_v4l2_ioctl_ops;
+ vdev->lock = &cio2->lock;
+ vdev->v4l2_dev = &cio2->v4l2_dev;
+ vdev->queue = &q->vbq;
+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING;
+ video_set_drvdata(vdev, cio2);
+ r = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+ if (r) {
+ dev_err(&cio2->pci_dev->dev,
+ "failed to register video device (%d)\n", r);
+ goto fail_vdev;
+ }
+
+ /* Create link from CIO2 subdev to output node */
+ r = media_create_pad_link(
+ &subdev->entity, CIO2_PAD_SOURCE, &vdev->entity, 0,
+ MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
+ if (r)
+ goto fail_link;
+
+ return 0;
+
+fail_link:
+ video_unregister_device(&q->vdev);
+fail_vdev:
+ vb2_queue_release(vbq);
+fail_vbq:
+ v4l2_device_unregister_subdev(subdev);
+fail_subdev:
+ media_entity_cleanup(&vdev->entity);
+fail_vdev_media_entity:
+ media_entity_cleanup(&subdev->entity);
+fail_subdev_media_entity:
+ cio2_fbpt_exit(q, &cio2->pci_dev->dev);
+fail_fbpt:
+ mutex_destroy(&q->lock);
+
+ return r;
+}
+
+static void cio2_queue_exit(struct cio2_device *cio2, struct cio2_queue *q)
+{
+ video_unregister_device(&q->vdev);
+ media_entity_cleanup(&q->vdev.entity);
+ vb2_queue_release(&q->vbq);
+ v4l2_device_unregister_subdev(&q->subdev);
+ media_entity_cleanup(&q->subdev.entity);
+ cio2_fbpt_exit(q, &cio2->pci_dev->dev);
+ mutex_destroy(&q->lock);
+}
+
+static int cio2_queues_init(struct cio2_device *cio2)
+{
+ int i, r;
+
+ for (i = 0; i < CIO2_QUEUES; i++) {
+ r = cio2_queue_init(cio2, &cio2->queue[i]);
+ if (r)
+ break;
+ }
+
+ if (i == CIO2_QUEUES)
+ return 0;
+
+ for (i--; i >= 0; i--)
+ cio2_queue_exit(cio2, &cio2->queue[i]);
+
+ return r;
+}
+
+static void cio2_queues_exit(struct cio2_device *cio2)
+{
+ unsigned int i;
+
+ for (i = 0; i < CIO2_QUEUES; i++)
+ cio2_queue_exit(cio2, &cio2->queue[i]);
+}
+
+/**************** PCI interface ****************/
+
+static int cio2_pci_config_setup(struct pci_dev *dev)
+{
+ u16 pci_command;
+ int r = pci_enable_msi(dev);
+
+ if (r) {
+ dev_err(&dev->dev, "failed to enable MSI (%d)\n", r);
+ return r;
+ }
+
+ pci_read_config_word(dev, PCI_COMMAND, &pci_command);
+ pci_command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_INTX_DISABLE;
+ pci_write_config_word(dev, PCI_COMMAND, pci_command);
+
+ return 0;
+}
+
+static int cio2_pci_probe(struct pci_dev *pci_dev,
+ const struct pci_device_id *id)
+{
+ struct cio2_device *cio2;
+ void __iomem *const *iomap;
+ int r;
+
+ cio2 = devm_kzalloc(&pci_dev->dev, sizeof(*cio2), GFP_KERNEL);
+ if (!cio2)
+ return -ENOMEM;
+ cio2->pci_dev = pci_dev;
+
+ r = pcim_enable_device(pci_dev);
+ if (r) {
+ dev_err(&pci_dev->dev, "failed to enable device (%d)\n", r);
+ return r;
+ }
+
+ dev_info(&pci_dev->dev, "device 0x%x (rev: 0x%x)\n",
+ pci_dev->device, pci_dev->revision);
+
+ r = pcim_iomap_regions(pci_dev, 1 << CIO2_PCI_BAR, pci_name(pci_dev));
+ if (r) {
+ dev_err(&pci_dev->dev, "failed to remap I/O memory (%d)\n", r);
+ return -ENODEV;
+ }
+
+ iomap = pcim_iomap_table(pci_dev);
+ if (!iomap) {
+ dev_err(&pci_dev->dev, "failed to iomap table\n");
+ return -ENODEV;
+ }
+
+ cio2->base = iomap[CIO2_PCI_BAR];
+
+ pci_set_drvdata(pci_dev, cio2);
+
+ pci_set_master(pci_dev);
+
+ r = pci_set_dma_mask(pci_dev, CIO2_DMA_MASK);
+ if (r) {
+ dev_err(&pci_dev->dev, "failed to set DMA mask (%d)\n", r);
+ return -ENODEV;
+ }
+
+ r = cio2_pci_config_setup(pci_dev);
+ if (r)
+ return -ENODEV;
+
+ r = cio2_fbpt_init_dummy(cio2);
+ if (r)
+ return r;
+
+ mutex_init(&cio2->lock);
+
+ cio2->media_dev.dev = &cio2->pci_dev->dev;
+ strlcpy(cio2->media_dev.model, CIO2_DEVICE_NAME,
+ sizeof(cio2->media_dev.model));
+ snprintf(cio2->media_dev.bus_info, sizeof(cio2->media_dev.bus_info),
+ "PCI:%s", pci_name(cio2->pci_dev));
+ cio2->media_dev.hw_revision = 0;
+
+ media_device_init(&cio2->media_dev);
+ r = media_device_register(&cio2->media_dev);
+ if (r < 0)
+ goto fail_mutex_destroy;
+
+ cio2->v4l2_dev.mdev = &cio2->media_dev;
+ r = v4l2_device_register(&pci_dev->dev, &cio2->v4l2_dev);
+ if (r) {
+ dev_err(&pci_dev->dev,
+ "failed to register V4L2 device (%d)\n", r);
+ goto fail_media_device_unregister;
+ }
+
+ r = cio2_queues_init(cio2);
+ if (r)
+ goto fail_v4l2_device_unregister;
+
+ /* Register notifier for subdevices we care */
+ r = cio2_notifier_init(cio2);
+ if (r)
+ goto fail_cio2_queue_exit;
+
+ r = devm_request_irq(&pci_dev->dev, pci_dev->irq, cio2_irq,
+ IRQF_SHARED, CIO2_NAME, cio2);
+ if (r) {
+ dev_err(&pci_dev->dev, "failed to request IRQ (%d)\n", r);
+ goto fail;
+ }
+
+ pm_runtime_put_noidle(&pci_dev->dev);
+ pm_runtime_allow(&pci_dev->dev);
+
+ return 0;
+
+fail:
+ cio2_notifier_exit(cio2);
+fail_cio2_queue_exit:
+ cio2_queues_exit(cio2);
+fail_v4l2_device_unregister:
+ v4l2_device_unregister(&cio2->v4l2_dev);
+fail_media_device_unregister:
+ media_device_unregister(&cio2->media_dev);
+ media_device_cleanup(&cio2->media_dev);
+fail_mutex_destroy:
+ mutex_destroy(&cio2->lock);
+ cio2_fbpt_exit_dummy(cio2);
+
+ return r;
+}
+
+static void cio2_pci_remove(struct pci_dev *pci_dev)
+{
+ struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+ unsigned int i;
+
+ cio2_notifier_exit(cio2);
+ cio2_fbpt_exit_dummy(cio2);
+ for (i = 0; i < CIO2_QUEUES; i++)
+ cio2_queue_exit(cio2, &cio2->queue[i]);
+ v4l2_device_unregister(&cio2->v4l2_dev);
+ media_device_unregister(&cio2->media_dev);
+ media_device_cleanup(&cio2->media_dev);
+ mutex_destroy(&cio2->lock);
+}
+
+static int __maybe_unused cio2_runtime_suspend(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+ void __iomem *const base = cio2->base;
+ u16 pm;
+
+ writel(CIO2_D0I3C_I3, base + CIO2_REG_D0I3C);
+ dev_dbg(dev, "cio2 runtime suspend.\n");
+
+ pci_read_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, &pm);
+ pm = (pm >> CIO2_PMCSR_D0D3_SHIFT) << CIO2_PMCSR_D0D3_SHIFT;
+ pm |= CIO2_PMCSR_D3;
+ pci_write_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, pm);
+
+ return 0;
+}
+
+static int __maybe_unused cio2_runtime_resume(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+ void __iomem *const base = cio2->base;
+ u16 pm;
+
+ writel(CIO2_D0I3C_RR, base + CIO2_REG_D0I3C);
+ dev_dbg(dev, "cio2 runtime resume.\n");
+
+ pci_read_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, &pm);
+ pm = (pm >> CIO2_PMCSR_D0D3_SHIFT) << CIO2_PMCSR_D0D3_SHIFT;
+ pci_write_config_word(pci_dev, pci_dev->pm_cap + CIO2_PMCSR_OFFSET, pm);
+
+ return 0;
+}
+
+/*
+ * Helper function to advance all the elements of a circular buffer by "start"
+ * positions
+ */
+static void arrange(void *ptr, size_t elem_size, size_t elems, size_t start)
+{
+ struct {
+ size_t begin, end;
+ } arr[2] = {
+ { 0, start - 1 },
+ { start, elems - 1 },
+ };
+
+#define CHUNK_SIZE(a) ((a)->end - (a)->begin + 1)
+
+ /* Loop as long as we have out-of-place entries */
+ while (CHUNK_SIZE(&arr[0]) && CHUNK_SIZE(&arr[1])) {
+ size_t size0, i;
+
+ /*
+ * Find the number of entries that can be arranged on this
+ * iteration.
+ */
+ size0 = min(CHUNK_SIZE(&arr[0]), CHUNK_SIZE(&arr[1]));
+
+ /* Swap the entries in two parts of the array. */
+ for (i = 0; i < size0; i++) {
+ u8 *d = ptr + elem_size * (arr[1].begin + i);
+ u8 *s = ptr + elem_size * (arr[0].begin + i);
+ size_t j;
+
+ for (j = 0; j < elem_size; j++)
+ swap(d[j], s[j]);
+ }
+
+ if (CHUNK_SIZE(&arr[0]) > CHUNK_SIZE(&arr[1])) {
+ /* The end of the first array remains unarranged. */
+ arr[0].begin += size0;
+ } else {
+ /*
+ * The first array is fully arranged so we proceed
+ * handling the next one.
+ */
+ arr[0].begin = arr[1].begin;
+ arr[0].end = arr[1].begin + size0 - 1;
+ arr[1].begin += size0;
+ }
+ }
+}
+
+static void cio2_fbpt_rearrange(struct cio2_device *cio2, struct cio2_queue *q)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = q->bufs_first; i < CIO2_MAX_BUFFERS;
+ i++, j = (j + 1) % CIO2_MAX_BUFFERS)
+ if (q->bufs[j])
+ break;
+
+ if (i == CIO2_MAX_BUFFERS)
+ return;
+
+ if (j) {
+ arrange(q->fbpt, sizeof(struct cio2_fbpt_entry) * CIO2_MAX_LOPS,
+ CIO2_MAX_BUFFERS, j);
+ arrange(q->bufs, sizeof(struct cio2_buffer *),
+ CIO2_MAX_BUFFERS, j);
+ }
+
+ /*
+ * DMA clears the valid bit when accessing the buffer.
+ * When stopping stream in suspend callback, some of the buffers
+ * may be in invalid state. After resume, when DMA meets the invalid
+ * buffer, it will halt and stop receiving new data.
+ * To avoid DMA halting, set the valid bit for all buffers in FBPT.
+ */
+ for (i = 0; i < CIO2_MAX_BUFFERS; i++)
+ cio2_fbpt_entry_enable(cio2, q->fbpt + i * CIO2_MAX_LOPS);
+}
+
+static int __maybe_unused cio2_suspend(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+ struct cio2_queue *q = cio2->cur_queue;
+
+ dev_dbg(dev, "cio2 suspend\n");
+ if (!cio2->streaming)
+ return 0;
+
+ /* Stop stream */
+ cio2_hw_exit(cio2, q);
+
+ pm_runtime_force_suspend(dev);
+
+ /*
+ * Upon resume, hw starts to process the fbpt entries from beginning,
+ * so relocate the queued buffs to the fbpt head before suspend.
+ */
+ cio2_fbpt_rearrange(cio2, q);
+ q->bufs_first = 0;
+ q->bufs_next = 0;
+
+ return 0;
+}
+
+static int __maybe_unused cio2_resume(struct device *dev)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+ struct cio2_device *cio2 = pci_get_drvdata(pci_dev);
+ int r = 0;
+ struct cio2_queue *q = cio2->cur_queue;
+
+ dev_dbg(dev, "cio2 resume\n");
+ if (!cio2->streaming)
+ return 0;
+ /* Start stream */
+ r = pm_runtime_force_resume(&cio2->pci_dev->dev);
+ if (r < 0) {
+ dev_err(&cio2->pci_dev->dev,
+ "failed to set power %d\n", r);
+ return r;
+ }
+
+ r = cio2_hw_init(cio2, q);
+ if (r)
+ dev_err(dev, "fail to init cio2 hw\n");
+
+ return r;
+}
+
+static const struct dev_pm_ops cio2_pm_ops = {
+ SET_RUNTIME_PM_OPS(&cio2_runtime_suspend, &cio2_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(&cio2_suspend, &cio2_resume)
+};
+
+static const struct pci_device_id cio2_pci_id_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, CIO2_PCI_ID) },
+ { 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, cio2_pci_id_table);
+
+static struct pci_driver cio2_pci_driver = {
+ .name = CIO2_NAME,
+ .id_table = cio2_pci_id_table,
+ .probe = cio2_pci_probe,
+ .remove = cio2_pci_remove,
+ .driver = {
+ .pm = &cio2_pm_ops,
+ },
+};
+
+module_pci_driver(cio2_pci_driver);
+
+MODULE_AUTHOR("Tuukka Toivonen <tuukka.toivonen@intel.com>");
+MODULE_AUTHOR("Tianshu Qiu <tian.shu.qiu@intel.com>");
+MODULE_AUTHOR("Jian Xu Zheng <jian.xu.zheng@intel.com>");
+MODULE_AUTHOR("Yuning Pu <yuning.pu@intel.com>");
+MODULE_AUTHOR("Yong Zhi <yong.zhi@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("IPU3 CIO2 driver");
diff --git a/drivers/media/pci/intel/ipu3/ipu3-cio2.h b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
new file mode 100644
index 000000000000..78a5799f08e7
--- /dev/null
+++ b/drivers/media/pci/intel/ipu3/ipu3-cio2.h
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2017 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT 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 __IPU3_CIO2_H
+#define __IPU3_CIO2_H
+
+#define CIO2_NAME "ipu3-cio2"
+#define CIO2_DEVICE_NAME "Intel IPU3 CIO2"
+#define CIO2_ENTITY_NAME "ipu3-csi2"
+#define CIO2_PCI_ID 0x9d32
+#define CIO2_PCI_BAR 0
+#define CIO2_DMA_MASK DMA_BIT_MASK(39)
+#define CIO2_IMAGE_MAX_WIDTH 4224
+#define CIO2_IMAGE_MAX_LENGTH 3136
+
+#define CIO2_IMAGE_MAX_WIDTH 4224
+#define CIO2_IMAGE_MAX_LENGTH 3136
+
+/* 32MB = 8xFBPT_entry */
+#define CIO2_MAX_LOPS 8
+#define CIO2_MAX_BUFFERS (PAGE_SIZE / 16 / CIO2_MAX_LOPS)
+
+#define CIO2_PAD_SINK 0
+#define CIO2_PAD_SOURCE 1
+#define CIO2_PADS 2
+
+#define CIO2_NUM_DMA_CHAN 20
+#define CIO2_NUM_PORTS 4 /* DPHYs */
+
+/* 1 for each sensor */
+#define CIO2_QUEUES CIO2_NUM_PORTS
+
+/* Register and bit field definitions */
+#define CIO2_REG_PIPE_BASE(n) ((n) * 0x0400) /* n = 0..3 */
+#define CIO2_REG_CSIRX_BASE 0x000
+#define CIO2_REG_MIPIBE_BASE 0x100
+#define CIO2_REG_PIXELGEN_BAS 0x200
+#define CIO2_REG_IRQCTRL_BASE 0x300
+#define CIO2_REG_GPREG_BASE 0x1000
+
+/* base register: CIO2_REG_PIPE_BASE(pipe) * CIO2_REG_CSIRX_BASE */
+#define CIO2_REG_CSIRX_ENABLE (CIO2_REG_CSIRX_BASE + 0x0)
+#define CIO2_REG_CSIRX_NOF_ENABLED_LANES (CIO2_REG_CSIRX_BASE + 0x4)
+#define CIO2_REG_CSIRX_SP_IF_CONFIG (CIO2_REG_CSIRX_BASE + 0x10)
+#define CIO2_REG_CSIRX_LP_IF_CONFIG (CIO2_REG_CSIRX_BASE + 0x14)
+#define CIO2_CSIRX_IF_CONFIG_FILTEROUT 0x00
+#define CIO2_CSIRX_IF_CONFIG_FILTEROUT_VC_INACTIVE 0x01
+#define CIO2_CSIRX_IF_CONFIG_PASS 0x02
+#define CIO2_CSIRX_IF_CONFIG_FLAG_ERROR BIT(2)
+#define CIO2_REG_CSIRX_STATUS (CIO2_REG_CSIRX_BASE + 0x18)
+#define CIO2_REG_CSIRX_STATUS_DLANE_HS (CIO2_REG_CSIRX_BASE + 0x1c)
+#define CIO2_CSIRX_STATUS_DLANE_HS_MASK 0xff
+#define CIO2_REG_CSIRX_STATUS_DLANE_LP (CIO2_REG_CSIRX_BASE + 0x20)
+#define CIO2_CSIRX_STATUS_DLANE_LP_MASK 0xffffff
+/* Termination enable and settle in 0.0625ns units, lane=0..3 or -1 for clock */
+#define CIO2_REG_CSIRX_DLY_CNT_TERMEN(lane) \
+ (CIO2_REG_CSIRX_BASE + 0x2c + 8 * (lane))
+#define CIO2_REG_CSIRX_DLY_CNT_SETTLE(lane) \
+ (CIO2_REG_CSIRX_BASE + 0x30 + 8 * (lane))
+/* base register: CIO2_REG_PIPE_BASE(pipe) * CIO2_REG_MIPIBE_BASE */
+#define CIO2_REG_MIPIBE_ENABLE (CIO2_REG_MIPIBE_BASE + 0x0)
+#define CIO2_REG_MIPIBE_STATUS (CIO2_REG_MIPIBE_BASE + 0x4)
+#define CIO2_REG_MIPIBE_COMP_FORMAT(vc) \
+ (CIO2_REG_MIPIBE_BASE + 0x8 + 0x4 * (vc))
+#define CIO2_REG_MIPIBE_FORCE_RAW8 (CIO2_REG_MIPIBE_BASE + 0x20)
+#define CIO2_REG_MIPIBE_FORCE_RAW8_ENABLE BIT(0)
+#define CIO2_REG_MIPIBE_FORCE_RAW8_USE_TYPEID BIT(1)
+#define CIO2_REG_MIPIBE_FORCE_RAW8_TYPEID_SHIFT 2
+
+#define CIO2_REG_MIPIBE_IRQ_STATUS (CIO2_REG_MIPIBE_BASE + 0x24)
+#define CIO2_REG_MIPIBE_IRQ_CLEAR (CIO2_REG_MIPIBE_BASE + 0x28)
+#define CIO2_REG_MIPIBE_GLOBAL_LUT_DISREGARD (CIO2_REG_MIPIBE_BASE + 0x68)
+#define CIO2_MIPIBE_GLOBAL_LUT_DISREGARD 1
+#define CIO2_REG_MIPIBE_PKT_STALL_STATUS (CIO2_REG_MIPIBE_BASE + 0x6c)
+#define CIO2_REG_MIPIBE_PARSE_GSP_THROUGH_LP_LUT_REG_IDX \
+ (CIO2_REG_MIPIBE_BASE + 0x70)
+#define CIO2_REG_MIPIBE_SP_LUT_ENTRY(vc) \
+ (CIO2_REG_MIPIBE_BASE + 0x74 + 4 * (vc))
+#define CIO2_REG_MIPIBE_LP_LUT_ENTRY(m) /* m = 0..15 */ \
+ (CIO2_REG_MIPIBE_BASE + 0x84 + 4 * (m))
+#define CIO2_MIPIBE_LP_LUT_ENTRY_DISREGARD 1
+#define CIO2_MIPIBE_LP_LUT_ENTRY_SID_SHIFT 1
+#define CIO2_MIPIBE_LP_LUT_ENTRY_VC_SHIFT 5
+#define CIO2_MIPIBE_LP_LUT_ENTRY_FORMAT_TYPE_SHIFT 7
+
+/* base register: CIO2_REG_PIPE_BASE(pipe) * CIO2_REG_IRQCTRL_BASE */
+/* IRQ registers are 18-bit wide, see cio2_irq_error for bit definitions */
+#define CIO2_REG_IRQCTRL_EDGE (CIO2_REG_IRQCTRL_BASE + 0x00)
+#define CIO2_REG_IRQCTRL_MASK (CIO2_REG_IRQCTRL_BASE + 0x04)
+#define CIO2_REG_IRQCTRL_STATUS (CIO2_REG_IRQCTRL_BASE + 0x08)
+#define CIO2_REG_IRQCTRL_CLEAR (CIO2_REG_IRQCTRL_BASE + 0x0c)
+#define CIO2_REG_IRQCTRL_ENABLE (CIO2_REG_IRQCTRL_BASE + 0x10)
+#define CIO2_REG_IRQCTRL_LEVEL_NOT_PULSE (CIO2_REG_IRQCTRL_BASE + 0x14)
+
+#define CIO2_REG_GPREG_SRST (CIO2_REG_GPREG_BASE + 0x0)
+#define CIO2_GPREG_SRST_ALL 0xffff /* Reset all */
+#define CIO2_REG_FB_HPLL_FREQ (CIO2_REG_GPREG_BASE + 0x08)
+#define CIO2_REG_ISCLK_RATIO (CIO2_REG_GPREG_BASE + 0xc)
+
+#define CIO2_REG_CGC 0x1400
+#define CIO2_CGC_CSI2_TGE BIT(0)
+#define CIO2_CGC_PRIM_TGE BIT(1)
+#define CIO2_CGC_SIDE_TGE BIT(2)
+#define CIO2_CGC_XOSC_TGE BIT(3)
+#define CIO2_CGC_MPLL_SHUTDOWN_EN BIT(4)
+#define CIO2_CGC_D3I3_TGE BIT(5)
+#define CIO2_CGC_CSI2_INTERFRAME_TGE BIT(6)
+#define CIO2_CGC_CSI2_PORT_DCGE BIT(8)
+#define CIO2_CGC_CSI2_DCGE BIT(9)
+#define CIO2_CGC_SIDE_DCGE BIT(10)
+#define CIO2_CGC_PRIM_DCGE BIT(11)
+#define CIO2_CGC_ROSC_DCGE BIT(12)
+#define CIO2_CGC_XOSC_DCGE BIT(13)
+#define CIO2_CGC_FLIS_DCGE BIT(14)
+#define CIO2_CGC_CLKGATE_HOLDOFF_SHIFT 20
+#define CIO2_CGC_CSI_CLKGATE_HOLDOFF_SHIFT 24
+#define CIO2_REG_D0I3C 0x1408
+#define CIO2_D0I3C_I3 BIT(2) /* Set D0I3 */
+#define CIO2_D0I3C_RR BIT(3) /* Restore? */
+#define CIO2_REG_SWRESET 0x140c
+#define CIO2_SWRESET_SWRESET 1
+#define CIO2_REG_SENSOR_ACTIVE 0x1410
+#define CIO2_REG_INT_STS 0x1414
+#define CIO2_REG_INT_STS_EXT_OE 0x1418
+#define CIO2_INT_EXT_OE_DMAOE_SHIFT 0
+#define CIO2_INT_EXT_OE_DMAOE_MASK 0x7ffff
+#define CIO2_INT_EXT_OE_OES_SHIFT 24
+#define CIO2_INT_EXT_OE_OES_MASK (0xf << CIO2_INT_EXT_OE_OES_SHIFT)
+#define CIO2_REG_INT_EN 0x1420
+#define CIO2_REG_INT_EN_IRQ (1 << 24)
+#define CIO2_REG_INT_EN_IOS(dma) (1 << (((dma) >> 1) + 12))
+/*
+ * Interrupt on completion bit, Eg. DMA 0-3 maps to bit 0-3,
+ * DMA4 & DMA5 map to bit 4 ... DMA18 & DMA19 map to bit 11 Et cetera
+ */
+#define CIO2_INT_IOC(dma) (1 << ((dma) < 4 ? (dma) : ((dma) >> 1) + 2))
+#define CIO2_INT_IOC_SHIFT 0
+#define CIO2_INT_IOC_MASK (0x7ff << CIO2_INT_IOC_SHIFT)
+#define CIO2_INT_IOS_IOLN(dma) (1 << (((dma) >> 1) + 12))
+#define CIO2_INT_IOS_IOLN_SHIFT 12
+#define CIO2_INT_IOS_IOLN_MASK (0x3ff << CIO2_INT_IOS_IOLN_SHIFT)
+#define CIO2_INT_IOIE BIT(22)
+#define CIO2_INT_IOOE BIT(23)
+#define CIO2_INT_IOIRQ BIT(24)
+#define CIO2_REG_INT_EN_EXT_OE 0x1424
+#define CIO2_REG_DMA_DBG 0x1448
+#define CIO2_REG_DMA_DBG_DMA_INDEX_SHIFT 0
+#define CIO2_REG_PBM_ARB_CTRL 0x1460
+#define CIO2_PBM_ARB_CTRL_LANES_DIV 0 /* 4-4-2-2 lanes */
+#define CIO2_PBM_ARB_CTRL_LANES_DIV_SHIFT 0
+#define CIO2_PBM_ARB_CTRL_LE_EN BIT(7)
+#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN 2
+#define CIO2_PBM_ARB_CTRL_PLL_POST_SHTDN_SHIFT 8
+#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP 480
+#define CIO2_PBM_ARB_CTRL_PLL_AHD_WK_UP_SHIFT 16
+#define CIO2_REG_PBM_WMCTRL1 0x1464
+#define CIO2_PBM_WMCTRL1_MIN_2CK_SHIFT 0
+#define CIO2_PBM_WMCTRL1_MID1_2CK_SHIFT 8
+#define CIO2_PBM_WMCTRL1_MID2_2CK_SHIFT 16
+#define CIO2_PBM_WMCTRL1_TS_COUNT_DISABLE BIT(31)
+#define CIO2_PBM_WMCTRL1_MIN_2CK (4 << CIO2_PBM_WMCTRL1_MIN_2CK_SHIFT)
+#define CIO2_PBM_WMCTRL1_MID1_2CK (16 << CIO2_PBM_WMCTRL1_MID1_2CK_SHIFT)
+#define CIO2_PBM_WMCTRL1_MID2_2CK (21 << CIO2_PBM_WMCTRL1_MID2_2CK_SHIFT)
+#define CIO2_REG_PBM_WMCTRL2 0x1468
+#define CIO2_PBM_WMCTRL2_HWM_2CK 40
+#define CIO2_PBM_WMCTRL2_HWM_2CK_SHIFT 0
+#define CIO2_PBM_WMCTRL2_LWM_2CK 22
+#define CIO2_PBM_WMCTRL2_LWM_2CK_SHIFT 8
+#define CIO2_PBM_WMCTRL2_OBFFWM_2CK 2
+#define CIO2_PBM_WMCTRL2_OBFFWM_2CK_SHIFT 16
+#define CIO2_PBM_WMCTRL2_TRANSDYN 1
+#define CIO2_PBM_WMCTRL2_TRANSDYN_SHIFT 24
+#define CIO2_PBM_WMCTRL2_DYNWMEN BIT(28)
+#define CIO2_PBM_WMCTRL2_OBFF_MEM_EN BIT(29)
+#define CIO2_PBM_WMCTRL2_OBFF_CPU_EN BIT(30)
+#define CIO2_PBM_WMCTRL2_DRAINNOW BIT(31)
+#define CIO2_REG_PBM_TS_COUNT 0x146c
+#define CIO2_REG_PBM_FOPN_ABORT 0x1474
+/* below n = 0..3 */
+#define CIO2_PBM_FOPN_ABORT(n) (0x1 << 8 * (n))
+#define CIO2_PBM_FOPN_FORCE_ABORT(n) (0x2 << 8 * (n))
+#define CIO2_PBM_FOPN_FRAMEOPEN(n) (0x8 << 8 * (n))
+#define CIO2_REG_LTRCTRL 0x1480
+#define CIO2_LTRCTRL_LTRDYNEN BIT(16)
+#define CIO2_LTRCTRL_LTRSTABLETIME_SHIFT 8
+#define CIO2_LTRCTRL_LTRSTABLETIME_MASK 0xff
+#define CIO2_LTRCTRL_LTRSEL1S3 BIT(7)
+#define CIO2_LTRCTRL_LTRSEL1S2 BIT(6)
+#define CIO2_LTRCTRL_LTRSEL1S1 BIT(5)
+#define CIO2_LTRCTRL_LTRSEL1S0 BIT(4)
+#define CIO2_LTRCTRL_LTRSEL2S3 BIT(3)
+#define CIO2_LTRCTRL_LTRSEL2S2 BIT(2)
+#define CIO2_LTRCTRL_LTRSEL2S1 BIT(1)
+#define CIO2_LTRCTRL_LTRSEL2S0 BIT(0)
+#define CIO2_REG_LTRVAL23 0x1484
+#define CIO2_REG_LTRVAL01 0x1488
+#define CIO2_LTRVAL02_VAL_SHIFT 0
+#define CIO2_LTRVAL02_SCALE_SHIFT 10
+#define CIO2_LTRVAL13_VAL_SHIFT 16
+#define CIO2_LTRVAL13_SCALE_SHIFT 26
+
+#define CIO2_LTRVAL0_VAL 175
+/* Value times 1024 ns */
+#define CIO2_LTRVAL0_SCALE 2
+#define CIO2_LTRVAL1_VAL 90
+#define CIO2_LTRVAL1_SCALE 2
+#define CIO2_LTRVAL2_VAL 90
+#define CIO2_LTRVAL2_SCALE 2
+#define CIO2_LTRVAL3_VAL 90
+#define CIO2_LTRVAL3_SCALE 2
+
+#define CIO2_REG_CDMABA(n) (0x1500 + 0x10 * (n)) /* n = 0..19 */
+#define CIO2_REG_CDMARI(n) (0x1504 + 0x10 * (n))
+#define CIO2_CDMARI_FBPT_RP_SHIFT 0
+#define CIO2_CDMARI_FBPT_RP_MASK 0xff
+#define CIO2_REG_CDMAC0(n) (0x1508 + 0x10 * (n))
+#define CIO2_CDMAC0_FBPT_LEN_SHIFT 0
+#define CIO2_CDMAC0_FBPT_WIDTH_SHIFT 8
+#define CIO2_CDMAC0_FBPT_NS BIT(25)
+#define CIO2_CDMAC0_DMA_INTR_ON_FS BIT(26)
+#define CIO2_CDMAC0_DMA_INTR_ON_FE BIT(27)
+#define CIO2_CDMAC0_FBPT_UPDATE_FIFO_FULL BIT(28)
+#define CIO2_CDMAC0_FBPT_FIFO_FULL_FIX_DIS BIT(29)
+#define CIO2_CDMAC0_DMA_EN BIT(30)
+#define CIO2_CDMAC0_DMA_HALTED BIT(31)
+#define CIO2_REG_CDMAC1(n) (0x150c + 0x10 * (n))
+#define CIO2_CDMAC1_LINENUMINT_SHIFT 0
+#define CIO2_CDMAC1_LINENUMUPDATE_SHIFT 16
+/* n = 0..3 */
+#define CIO2_REG_PXM_PXF_FMT_CFG0(n) (0x1700 + 0x30 * (n))
+#define CIO2_PXM_PXF_FMT_CFG_SID0_SHIFT 0
+#define CIO2_PXM_PXF_FMT_CFG_SID1_SHIFT 16
+#define CIO2_PXM_PXF_FMT_CFG_PCK_64B (0 << 0)
+#define CIO2_PXM_PXF_FMT_CFG_PCK_32B (1 << 0)
+#define CIO2_PXM_PXF_FMT_CFG_BPP_08 (0 << 2)
+#define CIO2_PXM_PXF_FMT_CFG_BPP_10 (1 << 2)
+#define CIO2_PXM_PXF_FMT_CFG_BPP_12 (2 << 2)
+#define CIO2_PXM_PXF_FMT_CFG_BPP_14 (3 << 2)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_4PPC (0 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_3PPC_RGBA (1 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_3PPC_ARGB (2 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_PLANAR2 (3 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_PLANAR3 (4 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_SPEC_NV16 (5 << 4)
+#define CIO2_PXM_PXF_FMT_CFG_PSWAP4_1ST_AB (1 << 7)
+#define CIO2_PXM_PXF_FMT_CFG_PSWAP4_1ST_CD (1 << 8)
+#define CIO2_PXM_PXF_FMT_CFG_PSWAP4_2ND_AC (1 << 9)
+#define CIO2_PXM_PXF_FMT_CFG_PSWAP4_2ND_BD (1 << 10)
+#define CIO2_REG_INT_STS_EXT_IE 0x17e4
+#define CIO2_REG_INT_EN_EXT_IE 0x17e8
+#define CIO2_INT_EXT_IE_ECC_RE(n) (0x01 << (8 * (n)))
+#define CIO2_INT_EXT_IE_DPHY_NR(n) (0x02 << (8 * (n)))
+#define CIO2_INT_EXT_IE_ECC_NR(n) (0x04 << (8 * (n)))
+#define CIO2_INT_EXT_IE_CRCERR(n) (0x08 << (8 * (n)))
+#define CIO2_INT_EXT_IE_INTERFRAMEDATA(n) (0x10 << (8 * (n)))
+#define CIO2_INT_EXT_IE_PKT2SHORT(n) (0x20 << (8 * (n)))
+#define CIO2_INT_EXT_IE_PKT2LONG(n) (0x40 << (8 * (n)))
+#define CIO2_INT_EXT_IE_IRQ(n) (0x80 << (8 * (n)))
+#define CIO2_REG_PXM_FRF_CFG(n) (0x1720 + 0x30 * (n))
+#define CIO2_PXM_FRF_CFG_FNSEL BIT(0)
+#define CIO2_PXM_FRF_CFG_FN_RST BIT(1)
+#define CIO2_PXM_FRF_CFG_ABORT BIT(2)
+#define CIO2_PXM_FRF_CFG_CRC_TH_SHIFT 3
+#define CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NR BIT(8)
+#define CIO2_PXM_FRF_CFG_MSK_ECC_RE BIT(9)
+#define CIO2_PXM_FRF_CFG_MSK_ECC_DPHY_NE BIT(10)
+#define CIO2_PXM_FRF_CFG_EVEN_ODD_MODE_SHIFT 11
+#define CIO2_PXM_FRF_CFG_MASK_CRC_THRES BIT(13)
+#define CIO2_PXM_FRF_CFG_MASK_CSI_ACCEPT BIT(14)
+#define CIO2_PXM_FRF_CFG_CIOHC_FS_MODE BIT(15)
+#define CIO2_PXM_FRF_CFG_CIOHC_FRST_FRM_SHIFT 16
+#define CIO2_REG_PXM_SID2BID0(n) (0x1724 + 0x30 * (n))
+#define CIO2_FB_HPLL_FREQ 0x2
+#define CIO2_ISCLK_RATIO 0xc
+
+#define CIO2_IRQCTRL_MASK 0x3ffff
+
+#define CIO2_INT_EN_EXT_OE_MASK 0x8f0fffff
+
+#define CIO2_CGC_CLKGATE_HOLDOFF 3
+#define CIO2_CGC_CSI_CLKGATE_HOLDOFF 5
+
+#define CIO2_PXM_FRF_CFG_CRC_TH 16
+
+#define CIO2_INT_EN_EXT_IE_MASK 0xffffffff
+
+#define CIO2_DMA_CHAN 0
+
+#define CIO2_CSIRX_DLY_CNT_CLANE_IDX -1
+
+#define CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_A 0
+#define CIO2_CSIRX_DLY_CNT_TERMEN_CLANE_B 0
+#define CIO2_CSIRX_DLY_CNT_SETTLE_CLANE_A 95
+#define CIO2_CSIRX_DLY_CNT_SETTLE_CLANE_B -8
+
+#define CIO2_CSIRX_DLY_CNT_TERMEN_DLANE_A 0
+#define CIO2_CSIRX_DLY_CNT_TERMEN_DLANE_B 0
+#define CIO2_CSIRX_DLY_CNT_SETTLE_DLANE_A 85
+#define CIO2_CSIRX_DLY_CNT_SETTLE_DLANE_B -2
+
+#define CIO2_CSIRX_DLY_CNT_TERMEN_DEFAULT 0x4
+#define CIO2_CSIRX_DLY_CNT_SETTLE_DEFAULT 0x570
+
+#define CIO2_PMCSR_OFFSET 4
+#define CIO2_PMCSR_D0D3_SHIFT 2
+#define CIO2_PMCSR_D3 0x3
+
+struct cio2_csi2_timing {
+ s32 clk_termen;
+ s32 clk_settle;
+ s32 dat_termen;
+ s32 dat_settle;
+};
+
+struct cio2_buffer {
+ struct vb2_v4l2_buffer vbb;
+ u32 *lop[CIO2_MAX_LOPS];
+ dma_addr_t lop_bus_addr[CIO2_MAX_LOPS];
+ unsigned int offset;
+};
+
+struct csi2_bus_info {
+ u32 port;
+ u32 lanes;
+};
+
+struct cio2_queue {
+ /* mutex to be used by vb2_queue */
+ struct mutex lock;
+ struct media_pipeline pipe;
+ struct csi2_bus_info csi2;
+ struct v4l2_subdev *sensor;
+ void __iomem *csi_rx_base;
+
+ /* Subdev, /dev/v4l-subdevX */
+ struct v4l2_subdev subdev;
+ struct media_pad subdev_pads[CIO2_PADS];
+ struct v4l2_mbus_framefmt subdev_fmt;
+ atomic_t frame_sequence;
+
+ /* Video device, /dev/videoX */
+ struct video_device vdev;
+ struct media_pad vdev_pad;
+ struct v4l2_pix_format_mplane format;
+ struct vb2_queue vbq;
+
+ /* Buffer queue handling */
+ struct cio2_fbpt_entry *fbpt; /* Frame buffer pointer table */
+ dma_addr_t fbpt_bus_addr;
+ struct cio2_buffer *bufs[CIO2_MAX_BUFFERS];
+ unsigned int bufs_first; /* Index of the first used entry */
+ unsigned int bufs_next; /* Index of the first unused entry */
+ atomic_t bufs_queued;
+};
+
+struct cio2_device {
+ struct pci_dev *pci_dev;
+ void __iomem *base;
+ struct v4l2_device v4l2_dev;
+ struct cio2_queue queue[CIO2_QUEUES];
+ struct cio2_queue *cur_queue;
+ /* mutex to be used by video_device */
+ struct mutex lock;
+
+ bool streaming;
+ struct v4l2_async_notifier notifier;
+ struct media_device media_dev;
+
+ /*
+ * Safety net to catch DMA fetch ahead
+ * when reaching the end of LOP
+ */
+ void *dummy_page;
+ /* DMA handle of dummy_page */
+ dma_addr_t dummy_page_bus_addr;
+ /* single List of Pointers (LOP) page */
+ u32 *dummy_lop;
+ /* DMA handle of dummy_lop */
+ dma_addr_t dummy_lop_bus_addr;
+};
+
+/**************** Virtual channel ****************/
+/*
+ * This should come from sensor driver. No
+ * driver interface nor requirement yet.
+ */
+#define SENSOR_VIR_CH_DFLT 0
+
+/**************** FBPT operations ****************/
+#define CIO2_FBPT_SIZE (CIO2_MAX_BUFFERS * CIO2_MAX_LOPS * \
+ sizeof(struct cio2_fbpt_entry))
+
+#define CIO2_FBPT_SUBENTRY_UNIT 4
+#define CIO2_PAGE_SIZE 4096
+
+/* cio2 fbpt first_entry ctrl status */
+#define CIO2_FBPT_CTRL_VALID BIT(0)
+#define CIO2_FBPT_CTRL_IOC BIT(1)
+#define CIO2_FBPT_CTRL_IOS BIT(2)
+#define CIO2_FBPT_CTRL_SUCCXFAIL BIT(3)
+#define CIO2_FBPT_CTRL_CMPLCODE_SHIFT 4
+
+/*
+ * Frame Buffer Pointer Table(FBPT) entry
+ * each entry describe an output buffer and consists of
+ * several sub-entries
+ */
+struct __packed cio2_fbpt_entry {
+ union {
+ struct __packed {
+ u32 ctrl; /* status ctrl */
+ u16 cur_line_num; /* current line # written to DDR */
+ u16 frame_num; /* updated by DMA upon FE */
+ u32 first_page_offset; /* offset for 1st page in LOP */
+ } first_entry;
+ /* Second entry per buffer */
+ struct __packed {
+ u32 timestamp;
+ u32 num_of_bytes;
+ /* the number of bytes for write on last page */
+ u16 last_page_available_bytes;
+ /* the number of pages allocated for this buf */
+ u16 num_of_pages;
+ } second_entry;
+ };
+ u32 lop_page_addr; /* Points to list of pointers (LOP) table */
+};
+
+static inline struct cio2_queue *file_to_cio2_queue(struct file *file)
+{
+ return container_of(video_devdata(file), struct cio2_queue, vdev);
+}
+
+static inline struct cio2_queue *vb2q_to_cio2_queue(struct vb2_queue *vq)
+{
+ return container_of(vq, struct cio2_queue, vbq);
+}
+
+#endif
diff --git a/drivers/media/pci/ivtv/Makefile b/drivers/media/pci/ivtv/Makefile
index 48f8a23f9a0f..5de95dbe3256 100644
--- a/drivers/media/pci/ivtv/Makefile
+++ b/drivers/media/pci/ivtv/Makefile
@@ -10,8 +10,6 @@ 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/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-cards.c b/drivers/media/pci/ivtv/ivtv-cards.c
index 410d97bdf541..c63792964a03 100644
--- a/drivers/media/pci/ivtv/ivtv-cards.c
+++ b/drivers/media/pci/ivtv/ivtv-cards.c
@@ -65,7 +65,7 @@ static struct ivtv_card_tuner_i2c ivtv_i2c_tda8290 = {
/********************** card configuration *******************************/
-/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
+/* Please add new PCI IDs to: http://pci-ids.ucw.cz/
This keeps the PCI ID database up to date. Note that the entries
must be added under vendor 0x4444 (Conexant) as subsystem IDs.
New vendor IDs should still be added to the vendor ID list. */
diff --git a/drivers/media/pci/ivtv/ivtv-cards.h b/drivers/media/pci/ivtv/ivtv-cards.h
index e6f5c02981f1..1557a6ea4dd9 100644
--- a/drivers/media/pci/ivtv/ivtv-cards.h
+++ b/drivers/media/pci/ivtv/ivtv-cards.h
@@ -22,26 +22,26 @@
#define IVTV_CARDS_H
/* Supported cards */
-#define IVTV_CARD_PVR_250 0 /* WinTV PVR 250 */
-#define IVTV_CARD_PVR_350 1 /* encoder, decoder, tv-out */
-#define IVTV_CARD_PVR_150 2 /* WinTV PVR 150 and PVR 500 (really just two
+#define IVTV_CARD_PVR_250 0 /* WinTV PVR 250 */
+#define IVTV_CARD_PVR_350 1 /* encoder, decoder, tv-out */
+#define IVTV_CARD_PVR_150 2 /* WinTV PVR 150 and PVR 500 (really just two
PVR150s on one PCI board) */
-#define IVTV_CARD_M179 3 /* AVerMedia M179 (encoder only) */
-#define IVTV_CARD_MPG600 4 /* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */
-#define IVTV_CARD_MPG160 5 /* Kuroutoshikou ITVC15-STVLP/YUAN MPG160
+#define IVTV_CARD_M179 3 /* AVerMedia M179 (encoder only) */
+#define IVTV_CARD_MPG600 4 /* Kuroutoshikou ITVC16-STVLP/YUAN MPG600, encoder only */
+#define IVTV_CARD_MPG160 5 /* Kuroutoshikou ITVC15-STVLP/YUAN MPG160
cx23415 based, but does not have tv-out */
-#define IVTV_CARD_PG600 6 /* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */
-#define IVTV_CARD_AVC2410 7 /* Adaptec AVC-2410 */
-#define IVTV_CARD_AVC2010 8 /* Adaptec AVD-2010 (No Tuner) */
-#define IVTV_CARD_TG5000TV 9 /* NAGASE TRANSGEAR 5000TV, encoder only */
+#define IVTV_CARD_PG600 6 /* YUAN PG600/DIAMONDMM PVR-550 based on the CX Falcon 2 */
+#define IVTV_CARD_AVC2410 7 /* Adaptec AVC-2410 */
+#define IVTV_CARD_AVC2010 8 /* Adaptec AVD-2010 (No Tuner) */
+#define IVTV_CARD_TG5000TV 9 /* NAGASE TRANSGEAR 5000TV, encoder only */
#define IVTV_CARD_VA2000MAX_SNT6 10 /* VA2000MAX-STN6 */
-#define IVTV_CARD_CX23416GYC 11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
-#define IVTV_CARD_GV_MVPRX 12 /* I/O Data GV-MVP/RX, RX2, RX2W */
-#define IVTV_CARD_GV_MVPRX2E 13 /* I/O Data GV-MVP/RX2E */
+#define IVTV_CARD_CX23416GYC 11 /* Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
+#define IVTV_CARD_GV_MVPRX 12 /* I/O Data GV-MVP/RX, RX2, RX2W */
+#define IVTV_CARD_GV_MVPRX2E 13 /* I/O Data GV-MVP/RX2E */
#define IVTV_CARD_GOTVIEW_PCI_DVD 14 /* GotView PCI DVD */
#define IVTV_CARD_GOTVIEW_PCI_DVD2 15 /* GotView PCI DVD2 */
#define IVTV_CARD_YUAN_MPC622 16 /* Yuan MPC622 miniPCI */
-#define IVTV_CARD_DCTMTVP1 17 /* DIGITAL COWBOY DCT-MTVP1 */
+#define IVTV_CARD_DCTMTVP1 17 /* DIGITAL COWBOY DCT-MTVP1 */
#define IVTV_CARD_PG600V2 18 /* Yuan PG600V2/GotView PCI DVD Lite */
#define IVTV_CARD_CLUB3D 19 /* Club3D ZAP-TV1x01 */
#define IVTV_CARD_AVERTV_MCE116 20 /* AVerTV MCE 116 Plus */
@@ -52,7 +52,7 @@
#define IVTV_CARD_BUFFALO_MV5L 25 /* Buffalo PC-MV5L/PCI card */
#define IVTV_CARD_AVER_ULTRA1500MCE 26 /* AVerMedia UltraTV 1500 MCE */
#define IVTV_CARD_KIKYOU 27 /* Sony VAIO Giga Pocket (ENX Kikyou) */
-#define IVTV_CARD_LAST 27
+#define IVTV_CARD_LAST 27
/* Variants of existing cards but with the same PCI IDs. The driver
detects these based on other device information.
@@ -61,7 +61,7 @@
must be adjusted accordingly. */
/* PVR-350 V1 (uses saa7114) */
-#define IVTV_CARD_PVR_350_V1 (IVTV_CARD_LAST+1)
+#define IVTV_CARD_PVR_350_V1 (IVTV_CARD_LAST+1)
/* 2 variants of Kuroutoshikou CX23416GYC-STVLP (Yuan MPG600GR OEM) */
#define IVTV_CARD_CX23416GYC_NOGR (IVTV_CARD_LAST+2)
#define IVTV_CARD_CX23416GYC_NOGRYCS (IVTV_CARD_LAST+3)
@@ -72,22 +72,22 @@
#define PCI_DEVICE_ID_IVTV16 0x0016
/* subsystem vendor ID */
-#define IVTV_PCI_ID_HAUPPAUGE 0x0070
-#define IVTV_PCI_ID_HAUPPAUGE_ALT1 0x0270
-#define IVTV_PCI_ID_HAUPPAUGE_ALT2 0x4070
-#define IVTV_PCI_ID_ADAPTEC 0x9005
-#define IVTV_PCI_ID_ASUSTEK 0x1043
-#define IVTV_PCI_ID_AVERMEDIA 0x1461
+#define IVTV_PCI_ID_HAUPPAUGE 0x0070
+#define IVTV_PCI_ID_HAUPPAUGE_ALT1 0x0270
+#define IVTV_PCI_ID_HAUPPAUGE_ALT2 0x4070
+#define IVTV_PCI_ID_ADAPTEC 0x9005
+#define IVTV_PCI_ID_ASUSTEK 0x1043
+#define IVTV_PCI_ID_AVERMEDIA 0x1461
#define IVTV_PCI_ID_YUAN1 0x12ab
-#define IVTV_PCI_ID_YUAN2 0xff01
-#define IVTV_PCI_ID_YUAN3 0xffab
-#define IVTV_PCI_ID_YUAN4 0xfbab
-#define IVTV_PCI_ID_DIAMONDMM 0xff92
-#define IVTV_PCI_ID_IODATA 0x10fc
-#define IVTV_PCI_ID_MELCO 0x1154
+#define IVTV_PCI_ID_YUAN2 0xff01
+#define IVTV_PCI_ID_YUAN3 0xffab
+#define IVTV_PCI_ID_YUAN4 0xfbab
+#define IVTV_PCI_ID_DIAMONDMM 0xff92
+#define IVTV_PCI_ID_IODATA 0x10fc
+#define IVTV_PCI_ID_MELCO 0x1154
#define IVTV_PCI_ID_GOTVIEW1 0xffac
-#define IVTV_PCI_ID_GOTVIEW2 0xffad
-#define IVTV_PCI_ID_SONY 0x104d
+#define IVTV_PCI_ID_GOTVIEW2 0xffad
+#define IVTV_PCI_ID_SONY 0x104d
/* hardware flags, no gaps allowed */
#define IVTV_HW_CX25840 (1 << 0)
@@ -109,41 +109,33 @@
#define IVTV_HW_I2C_IR_RX_AVER (1 << 16)
#define IVTV_HW_I2C_IR_RX_HAUP_EXT (1 << 17) /* External before internal */
#define IVTV_HW_I2C_IR_RX_HAUP_INT (1 << 18)
-#define IVTV_HW_Z8F0811_IR_TX_HAUP (1 << 19)
-#define IVTV_HW_Z8F0811_IR_RX_HAUP (1 << 20)
-#define IVTV_HW_I2C_IR_RX_ADAPTEC (1 << 21)
-
-#define IVTV_HW_Z8F0811_IR_HAUP (IVTV_HW_Z8F0811_IR_RX_HAUP | \
- IVTV_HW_Z8F0811_IR_TX_HAUP)
+#define IVTV_HW_Z8F0811_IR_HAUP (1 << 19)
+#define IVTV_HW_I2C_IR_RX_ADAPTEC (1 << 20)
#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
-#define IVTV_HW_IR_RX_ANY (IVTV_HW_I2C_IR_RX_AVER | \
- IVTV_HW_I2C_IR_RX_HAUP_EXT | \
- IVTV_HW_I2C_IR_RX_HAUP_INT | \
- IVTV_HW_Z8F0811_IR_RX_HAUP | \
- IVTV_HW_I2C_IR_RX_ADAPTEC)
-
-#define IVTV_HW_IR_TX_ANY (IVTV_HW_Z8F0811_IR_TX_HAUP)
-
-#define IVTV_HW_IR_ANY (IVTV_HW_IR_RX_ANY | IVTV_HW_IR_TX_ANY)
+#define IVTV_HW_IR_ANY (IVTV_HW_I2C_IR_RX_AVER | \
+ IVTV_HW_I2C_IR_RX_HAUP_EXT | \
+ IVTV_HW_I2C_IR_RX_HAUP_INT | \
+ IVTV_HW_Z8F0811_IR_HAUP | \
+ IVTV_HW_I2C_IR_RX_ADAPTEC)
/* video inputs */
#define IVTV_CARD_INPUT_VID_TUNER 1
-#define IVTV_CARD_INPUT_SVIDEO1 2
-#define IVTV_CARD_INPUT_SVIDEO2 3
-#define IVTV_CARD_INPUT_COMPOSITE1 4
-#define IVTV_CARD_INPUT_COMPOSITE2 5
-#define IVTV_CARD_INPUT_COMPOSITE3 6
+#define IVTV_CARD_INPUT_SVIDEO1 2
+#define IVTV_CARD_INPUT_SVIDEO2 3
+#define IVTV_CARD_INPUT_COMPOSITE1 4
+#define IVTV_CARD_INPUT_COMPOSITE2 5
+#define IVTV_CARD_INPUT_COMPOSITE3 6
/* audio inputs */
#define IVTV_CARD_INPUT_AUD_TUNER 1
-#define IVTV_CARD_INPUT_LINE_IN1 2
-#define IVTV_CARD_INPUT_LINE_IN2 3
+#define IVTV_CARD_INPUT_LINE_IN1 2
+#define IVTV_CARD_INPUT_LINE_IN2 3
#define IVTV_CARD_MAX_VIDEO_INPUTS 6
#define IVTV_CARD_MAX_AUDIO_INPUTS 3
-#define IVTV_CARD_MAX_TUNERS 3
+#define IVTV_CARD_MAX_TUNERS 3
/* SAA71XX HW inputs */
#define IVTV_SAA71XX_COMPOSITE0 0
@@ -180,7 +172,7 @@
V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY)
struct ivtv_card_video_input {
- u8 video_type; /* video input type */
+ u8 video_type; /* video input type */
u8 audio_index; /* index in ivtv_card_audio_input array */
u16 video_input; /* hardware video input */
};
@@ -207,55 +199,55 @@ struct ivtv_card_pci_info {
/* The mask is the set of bits used by the operation */
-struct ivtv_gpio_init { /* set initial GPIO DIR and OUT values */
- u16 direction; /* DIR setting. Leave to 0 if no init is needed */
+struct ivtv_gpio_init { /* set initial GPIO DIR and OUT values */
+ u16 direction; /* DIR setting. Leave to 0 if no init is needed */
u16 initial_value;
};
-struct ivtv_gpio_video_input { /* select tuner/line in input */
- u16 mask; /* leave to 0 if not supported */
+struct ivtv_gpio_video_input { /* select tuner/line in input */
+ u16 mask; /* leave to 0 if not supported */
u16 tuner;
u16 composite;
u16 svideo;
};
-struct ivtv_gpio_audio_input { /* select tuner/line in input */
- u16 mask; /* leave to 0 if not supported */
+struct ivtv_gpio_audio_input { /* select tuner/line in input */
+ u16 mask; /* leave to 0 if not supported */
u16 tuner;
u16 linein;
u16 radio;
};
struct ivtv_gpio_audio_mute {
- u16 mask; /* leave to 0 if not supported */
+ u16 mask; /* leave to 0 if not supported */
u16 mute; /* set this value to mute, 0 to unmute */
};
struct ivtv_gpio_audio_mode {
- u16 mask; /* leave to 0 if not supported */
- u16 mono; /* set audio to mono */
- u16 stereo; /* set audio to stereo */
+ u16 mask; /* leave to 0 if not supported */
+ u16 mono; /* set audio to mono */
+ u16 stereo; /* set audio to stereo */
u16 lang1; /* set audio to the first language */
u16 lang2; /* set audio to the second language */
- u16 both; /* both languages are output */
+ u16 both; /* both languages are output */
};
struct ivtv_gpio_audio_freq {
- u16 mask; /* leave to 0 if not supported */
+ u16 mask; /* leave to 0 if not supported */
u16 f32000;
u16 f44100;
u16 f48000;
};
struct ivtv_gpio_audio_detect {
- u16 mask; /* leave to 0 if not supported */
- u16 stereo; /* if the input matches this value then
+ u16 mask; /* leave to 0 if not supported */
+ u16 stereo; /* if the input matches this value then
stereo is detected */
};
struct ivtv_card_tuner {
- v4l2_std_id std; /* standard for which the tuner is suitable */
- int tuner; /* tuner ID (from tuner.h) */
+ v4l2_std_id std; /* standard for which the tuner is suitable */
+ int tuner; /* tuner ID (from tuner.h) */
};
struct ivtv_card_tuner_i2c {
@@ -280,17 +272,17 @@ struct ivtv_card {
struct ivtv_card_audio_input radio_input;
int nof_outputs;
const struct ivtv_card_output *video_outputs;
- u8 gr_config; /* config byte for the ghost reduction device */
- u8 xceive_pin; /* XCeive tuner GPIO reset pin */
+ u8 gr_config; /* config byte for the ghost reduction device */
+ u8 xceive_pin; /* XCeive tuner GPIO reset pin */
/* GPIO card-specific settings */
- struct ivtv_gpio_init gpio_init;
+ struct ivtv_gpio_init gpio_init;
struct ivtv_gpio_video_input gpio_video_input;
- struct ivtv_gpio_audio_input gpio_audio_input;
- struct ivtv_gpio_audio_mute gpio_audio_mute;
- struct ivtv_gpio_audio_mode gpio_audio_mode;
- struct ivtv_gpio_audio_freq gpio_audio_freq;
- struct ivtv_gpio_audio_detect gpio_audio_detect;
+ struct ivtv_gpio_audio_input gpio_audio_input;
+ struct ivtv_gpio_audio_mute gpio_audio_mute;
+ struct ivtv_gpio_audio_mode gpio_audio_mode;
+ struct ivtv_gpio_audio_freq gpio_audio_freq;
+ struct ivtv_gpio_audio_detect gpio_audio_detect;
struct ivtv_card_tuner tuners[IVTV_CARD_MAX_TUNERS];
struct ivtv_card_tuner_i2c *i2c;
diff --git a/drivers/media/pci/ivtv/ivtv-driver.h b/drivers/media/pci/ivtv/ivtv-driver.h
index d27c5c2c07ea..cafba6b1055d 100644
--- a/drivers/media/pci/ivtv/ivtv-driver.h
+++ b/drivers/media/pci/ivtv/ivtv-driver.h
@@ -76,7 +76,7 @@
#define IVTV_ENCODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */
#define IVTV_DECODER_OFFSET 0x01000000
#define IVTV_DECODER_SIZE 0x00800000 /* Total size is 0x01000000, but only first half is used */
-#define IVTV_REG_OFFSET 0x02000000
+#define IVTV_REG_OFFSET 0x02000000
#define IVTV_REG_SIZE 0x00010000
/* Maximum ivtv driver instances. Some people have a huge number of
@@ -97,26 +97,26 @@
#define IVTV_DMA_SG_OSD_ENT (2883584/PAGE_SIZE) /* sg entities */
/* DMA Registers */
-#define IVTV_REG_DMAXFER (0x0000)
-#define IVTV_REG_DMASTATUS (0x0004)
-#define IVTV_REG_DECDMAADDR (0x0008)
-#define IVTV_REG_ENCDMAADDR (0x000c)
-#define IVTV_REG_DMACONTROL (0x0010)
-#define IVTV_REG_IRQSTATUS (0x0040)
-#define IVTV_REG_IRQMASK (0x0048)
+#define IVTV_REG_DMAXFER (0x0000)
+#define IVTV_REG_DMASTATUS (0x0004)
+#define IVTV_REG_DECDMAADDR (0x0008)
+#define IVTV_REG_ENCDMAADDR (0x000c)
+#define IVTV_REG_DMACONTROL (0x0010)
+#define IVTV_REG_IRQSTATUS (0x0040)
+#define IVTV_REG_IRQMASK (0x0048)
/* Setup Registers */
-#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8)
-#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC)
-#define IVTV_REG_DEC_SDRAM_REFRESH (0x08F8)
-#define IVTV_REG_DEC_SDRAM_PRECHARGE (0x08FC)
-#define IVTV_REG_VDM (0x2800)
-#define IVTV_REG_AO (0x2D00)
-#define IVTV_REG_BYTEFLUSH (0x2D24)
-#define IVTV_REG_SPU (0x9050)
-#define IVTV_REG_HW_BLOCKS (0x9054)
-#define IVTV_REG_VPU (0x9058)
-#define IVTV_REG_APU (0xA064)
+#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8)
+#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC)
+#define IVTV_REG_DEC_SDRAM_REFRESH (0x08F8)
+#define IVTV_REG_DEC_SDRAM_PRECHARGE (0x08FC)
+#define IVTV_REG_VDM (0x2800)
+#define IVTV_REG_AO (0x2D00)
+#define IVTV_REG_BYTEFLUSH (0x2D24)
+#define IVTV_REG_SPU (0x9050)
+#define IVTV_REG_HW_BLOCKS (0x9054)
+#define IVTV_REG_VPU (0x9058)
+#define IVTV_REG_APU (0xA064)
/* Other registers */
#define IVTV_REG_DEC_LINE_FIELD (0x28C0)
@@ -158,7 +158,7 @@ extern int ivtv_fw_debug;
#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
do { \
- if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \
+ if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \
v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
} while (0)
#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
@@ -226,9 +226,9 @@ struct ivtv_mailbox_data {
/* per-stream, s_flags */
#define IVTV_F_S_DMA_PENDING 0 /* this stream has pending DMA */
#define IVTV_F_S_DMA_HAS_VBI 1 /* the current DMA request also requests VBI data */
-#define IVTV_F_S_NEEDS_DATA 2 /* this decoding stream needs more data */
+#define IVTV_F_S_NEEDS_DATA 2 /* this decoding stream needs more data */
-#define IVTV_F_S_CLAIMED 3 /* this stream is claimed */
+#define IVTV_F_S_CLAIMED 3 /* this stream is claimed */
#define IVTV_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */
#define IVTV_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */
#define IVTV_F_S_PASSTHROUGH 6 /* this stream is in passthrough mode */
@@ -239,35 +239,35 @@ struct ivtv_mailbox_data {
#define IVTV_F_S_PIO_HAS_VBI 1 /* the current PIO request also requests VBI data */
/* per-ivtv, i_flags */
-#define IVTV_F_I_DMA 0 /* DMA in progress */
-#define IVTV_F_I_UDMA 1 /* UDMA in progress */
-#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */
-#define IVTV_F_I_SPEED_CHANGE 3 /* a speed change is in progress */
-#define IVTV_F_I_EOS 4 /* end of encoder stream reached */
-#define IVTV_F_I_RADIO_USER 5 /* the radio tuner is selected */
-#define IVTV_F_I_DIG_RST 6 /* reset digitizer */
-#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */
-#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */
-#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */
-#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */
-#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */
-#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
-#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */
-#define IVTV_F_I_HAVE_WORK 15 /* used in the interrupt handler: there is work to be done */
+#define IVTV_F_I_DMA 0 /* DMA in progress */
+#define IVTV_F_I_UDMA 1 /* UDMA in progress */
+#define IVTV_F_I_UDMA_PENDING 2 /* UDMA pending */
+#define IVTV_F_I_SPEED_CHANGE 3 /* a speed change is in progress */
+#define IVTV_F_I_EOS 4 /* end of encoder stream reached */
+#define IVTV_F_I_RADIO_USER 5 /* the radio tuner is selected */
+#define IVTV_F_I_DIG_RST 6 /* reset digitizer */
+#define IVTV_F_I_DEC_YUV 7 /* YUV instead of MPG is being decoded */
+#define IVTV_F_I_UPDATE_CC 9 /* CC should be updated */
+#define IVTV_F_I_UPDATE_WSS 10 /* WSS should be updated */
+#define IVTV_F_I_UPDATE_VPS 11 /* VPS should be updated */
+#define IVTV_F_I_DECODING_YUV 12 /* this stream is YUV frame decoding */
+#define IVTV_F_I_ENC_PAUSED 13 /* the encoder is paused */
+#define IVTV_F_I_VALID_DEC_TIMINGS 14 /* last_dec_timing is valid */
+#define IVTV_F_I_HAVE_WORK 15 /* used in the interrupt handler: there is work to be done */
#define IVTV_F_I_WORK_HANDLER_VBI 16 /* there is work to be done for VBI */
#define IVTV_F_I_WORK_HANDLER_YUV 17 /* there is work to be done for YUV */
#define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */
#define IVTV_F_I_PIO 19 /* PIO in progress */
-#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_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 */
-#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */
-#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */
-#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */
+#define IVTV_F_I_EV_VSYNC 29 /* VSYNC event */
+#define IVTV_F_I_EV_VSYNC_FIELD 30 /* VSYNC event field (0 = first, 1 = second field) */
+#define IVTV_F_I_EV_VSYNC_ENABLED 31 /* VSYNC event enabled */
/* Scatter-Gather array element, used in DMA transfers */
struct ivtv_sg_element {
@@ -330,13 +330,13 @@ struct ivtv_stream {
/* These first four fields are always set, even if the stream
is not actually created. */
struct video_device vdev; /* vdev.v4l2_dev is NULL if there is no device */
- struct ivtv *itv; /* for ease of use */
+ struct ivtv *itv; /* for ease of use */
const char *name; /* name of the stream */
int type; /* stream type */
u32 caps; /* V4L2 capabilities */
struct v4l2_fh *fh; /* pointer to the streaming filehandle */
- spinlock_t qlock; /* locks access to the queues */
+ spinlock_t qlock; /* locks access to the queues */
unsigned long s_flags; /* status flags, see above */
int dma; /* can be PCI_DMA_TODEVICE, PCI_DMA_FROMDEVICE or PCI_DMA_NONE */
u32 pending_offset;
@@ -564,7 +564,7 @@ struct vbi_info {
/* Raw VBI compatibility hack */
- u32 frame; /* frame counter hack needed for backwards compatibility
+ u32 frame; /* frame counter hack needed for backwards compatibility
of old VBI software */
/* Sliced VBI output data */
@@ -620,7 +620,7 @@ struct ivtv {
u8 nof_inputs; /* number of video inputs */
u8 nof_audio_inputs; /* number of audio inputs */
u32 v4l2_cap; /* V4L2 capabilities of card */
- u32 hw_flags; /* hardware description of the board */
+ u32 hw_flags; /* hardware description of the board */
v4l2_std_id tuner_std; /* the norm of the card's tuner (fixed) */
struct v4l2_subdev *sd_video; /* controlling video decoder subdev */
struct v4l2_subdev *sd_audio; /* controlling audio subdev */
@@ -629,7 +629,7 @@ struct ivtv {
volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */
volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */
volatile void __iomem *reg_mem; /* pointer to mapped registers */
- struct ivtv_options options; /* user options */
+ struct ivtv_options options; /* user options */
struct v4l2_device v4l2_dev;
struct cx2341x_handler cxhdl;
@@ -668,7 +668,7 @@ struct ivtv {
/* Streams */
int stream_buf_size[IVTV_MAX_STREAMS]; /* stream buffer size */
- struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */
+ struct ivtv_stream streams[IVTV_MAX_STREAMS]; /* stream data */
atomic_t capturing; /* count number of active capture streams */
atomic_t decoding; /* count number of active decoding streams */
@@ -704,7 +704,7 @@ struct ivtv {
/* Mailbox */
struct ivtv_mailbox_data enc_mbox; /* encoder mailboxes */
struct ivtv_mailbox_data dec_mbox; /* decoder mailboxes */
- struct ivtv_api_cache api_cache[256]; /* cached API commands */
+ struct ivtv_api_cache api_cache[256]; /* cached API commands */
/* I2C */
@@ -828,7 +828,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv)
/* Call the specified callback for all subdevs matching hw (if 0, then
match them all). Ignore any errors. */
-#define ivtv_call_hw(itv, hw, o, f, args...) \
+#define ivtv_call_hw(itv, hw, o, f, args...) \
v4l2_device_mask_call_all(&(itv)->v4l2_dev, hw, o, f, ##args)
#define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args)
diff --git a/drivers/media/pci/ivtv/ivtv-firmware.c b/drivers/media/pci/ivtv/ivtv-firmware.c
index ba279fdb3df8..9f05472fca20 100644
--- a/drivers/media/pci/ivtv/ivtv-firmware.c
+++ b/drivers/media/pci/ivtv/ivtv-firmware.c
@@ -28,26 +28,26 @@
#include <linux/firmware.h>
#include <media/i2c/saa7127.h>
-#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE
-#define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6
-#define IVTV_MASK_VPU_ENABLE16 0xFFFFFFFB
-#define IVTV_CMD_VDM_STOP 0x00000000
-#define IVTV_CMD_AO_STOP 0x00000005
-#define IVTV_CMD_APU_PING 0x00000000
-#define IVTV_CMD_VPU_STOP15 0xFFFFFFFE
-#define IVTV_CMD_VPU_STOP16 0xFFFFFFEE
-#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
-#define IVTV_CMD_SPU_STOP 0x00000001
-#define IVTV_CMD_SDRAM_PRECHARGE_INIT 0x0000001A
-#define IVTV_CMD_SDRAM_REFRESH_INIT 0x80000640
-#define IVTV_SDRAM_SLEEPTIME 600
-
-#define IVTV_DECODE_INIT_MPEG_FILENAME "v4l-cx2341x-init.mpg"
-#define IVTV_DECODE_INIT_MPEG_SIZE (152*1024)
+#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE
+#define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6
+#define IVTV_MASK_VPU_ENABLE16 0xFFFFFFFB
+#define IVTV_CMD_VDM_STOP 0x00000000
+#define IVTV_CMD_AO_STOP 0x00000005
+#define IVTV_CMD_APU_PING 0x00000000
+#define IVTV_CMD_VPU_STOP15 0xFFFFFFFE
+#define IVTV_CMD_VPU_STOP16 0xFFFFFFEE
+#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
+#define IVTV_CMD_SPU_STOP 0x00000001
+#define IVTV_CMD_SDRAM_PRECHARGE_INIT 0x0000001A
+#define IVTV_CMD_SDRAM_REFRESH_INIT 0x80000640
+#define IVTV_SDRAM_SLEEPTIME 600
+
+#define IVTV_DECODE_INIT_MPEG_FILENAME "v4l-cx2341x-init.mpg"
+#define IVTV_DECODE_INIT_MPEG_SIZE (152*1024)
/* Encoder/decoder firmware sizes */
-#define IVTV_FW_ENC_SIZE (376836)
-#define IVTV_FW_DEC_SIZE (256*1024)
+#define IVTV_FW_ENC_SIZE (376836)
+#define IVTV_FW_DEC_SIZE (256*1024)
static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv *itv, long size)
{
diff --git a/drivers/media/pci/ivtv/ivtv-i2c.c b/drivers/media/pci/ivtv/ivtv-i2c.c
index 893962ac85de..522cd111e399 100644
--- a/drivers/media/pci/ivtv/ivtv-i2c.c
+++ b/drivers/media/pci/ivtv/ivtv-i2c.c
@@ -76,22 +76,22 @@
#define IVTV_CS53L32A_I2C_ADDR 0x11
#define IVTV_M52790_I2C_ADDR 0x48
-#define IVTV_CX25840_I2C_ADDR 0x44
-#define IVTV_SAA7115_I2C_ADDR 0x21
-#define IVTV_SAA7127_I2C_ADDR 0x44
-#define IVTV_SAA717x_I2C_ADDR 0x21
-#define IVTV_MSP3400_I2C_ADDR 0x40
-#define IVTV_HAUPPAUGE_I2C_ADDR 0x50
-#define IVTV_WM8739_I2C_ADDR 0x1a
+#define IVTV_CX25840_I2C_ADDR 0x44
+#define IVTV_SAA7115_I2C_ADDR 0x21
+#define IVTV_SAA7127_I2C_ADDR 0x44
+#define IVTV_SAA717x_I2C_ADDR 0x21
+#define IVTV_MSP3400_I2C_ADDR 0x40
+#define IVTV_HAUPPAUGE_I2C_ADDR 0x50
+#define IVTV_WM8739_I2C_ADDR 0x1a
#define IVTV_WM8775_I2C_ADDR 0x1b
#define IVTV_TEA5767_I2C_ADDR 0x60
-#define IVTV_UPD64031A_I2C_ADDR 0x12
-#define IVTV_UPD64083_I2C_ADDR 0x5c
-#define IVTV_VP27SMPX_I2C_ADDR 0x5b
-#define IVTV_M52790_I2C_ADDR 0x48
+#define IVTV_UPD64031A_I2C_ADDR 0x12
+#define IVTV_UPD64083_I2C_ADDR 0x5c
+#define IVTV_VP27SMPX_I2C_ADDR 0x5b
+#define IVTV_M52790_I2C_ADDR 0x48
#define IVTV_AVERMEDIA_IR_RX_I2C_ADDR 0x40
-#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a
-#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18
+#define IVTV_HAUP_EXT_IR_RX_I2C_ADDR 0x1a
+#define IVTV_HAUP_INT_IR_RX_I2C_ADDR 0x18
#define IVTV_Z8F0811_IR_TX_I2C_ADDR 0x70
#define IVTV_Z8F0811_IR_RX_I2C_ADDR 0x71
#define IVTV_ADAPTEC_IR_ADDR 0x6b
@@ -117,8 +117,7 @@ static const u8 hw_addrs[] = {
IVTV_AVERMEDIA_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_AVER */
IVTV_HAUP_EXT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
IVTV_HAUP_INT_IR_RX_I2C_ADDR, /* IVTV_HW_I2C_IR_RX_HAUP_INT */
- IVTV_Z8F0811_IR_TX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_TX_HAUP */
- IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_RX_HAUP */
+ IVTV_Z8F0811_IR_RX_I2C_ADDR, /* IVTV_HW_Z8F0811_IR_HAUP */
IVTV_ADAPTEC_IR_ADDR, /* IVTV_HW_I2C_IR_RX_ADAPTEC */
};
@@ -143,8 +142,7 @@ static const char * const hw_devicenames[] = {
"ir_video", /* IVTV_HW_I2C_IR_RX_AVER */
"ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_EXT */
"ir_video", /* IVTV_HW_I2C_IR_RX_HAUP_INT */
- "ir_tx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_TX_HAUP */
- "ir_rx_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_RX_HAUP */
+ "ir_z8f0811_haup", /* IVTV_HW_Z8F0811_IR_HAUP */
"ir_video", /* IVTV_HW_I2C_IR_RX_ADAPTEC */
};
@@ -181,18 +179,8 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
struct IR_i2c_init_data *init_data = &itv->ir_i2c_init_data;
unsigned short addr_list[2] = { addr, I2C_CLIENT_END };
- /* Only allow one IR transmitter to be registered per board */
- if (hw & IVTV_HW_IR_TX_ANY) {
- if (itv->hw_flags & IVTV_HW_IR_TX_ANY)
- return -1;
- memset(&info, 0, sizeof(struct i2c_board_info));
- strlcpy(info.type, type, I2C_NAME_SIZE);
- return i2c_new_probed_device(adap, &info, addr_list, NULL)
- == NULL ? -1 : 0;
- }
-
/* Only allow one IR receiver to be registered per board */
- if (itv->hw_flags & IVTV_HW_IR_RX_ANY)
+ if (itv->hw_flags & IVTV_HW_IR_ANY)
return -1;
/* Our default information for ir-kbd-i2c.c to use */
@@ -211,7 +199,7 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
init_data->type = RC_PROTO_BIT_RC5;
init_data->name = itv->card_name;
break;
- case IVTV_HW_Z8F0811_IR_RX_HAUP:
+ case IVTV_HW_Z8F0811_IR_HAUP:
/* Default to grey remote */
init_data->ir_codes = RC_MAP_HAUPPAUGE;
init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
diff --git a/drivers/media/pci/ivtv/ivtv-ioctl.c b/drivers/media/pci/ivtv/ivtv-ioctl.c
index 670462d195b5..4cdc6d2be85d 100644
--- a/drivers/media/pci/ivtv/ivtv-ioctl.c
+++ b/drivers/media/pci/ivtv/ivtv-ioctl.c
@@ -1884,65 +1884,65 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
}
static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
- .vidioc_querycap = ivtv_querycap,
- .vidioc_s_audio = ivtv_s_audio,
- .vidioc_g_audio = ivtv_g_audio,
- .vidioc_enumaudio = ivtv_enumaudio,
- .vidioc_s_audout = ivtv_s_audout,
- .vidioc_g_audout = ivtv_g_audout,
- .vidioc_enum_input = ivtv_enum_input,
- .vidioc_enum_output = ivtv_enum_output,
- .vidioc_enumaudout = ivtv_enumaudout,
- .vidioc_cropcap = ivtv_cropcap,
+ .vidioc_querycap = ivtv_querycap,
+ .vidioc_s_audio = ivtv_s_audio,
+ .vidioc_g_audio = ivtv_g_audio,
+ .vidioc_enumaudio = ivtv_enumaudio,
+ .vidioc_s_audout = ivtv_s_audout,
+ .vidioc_g_audout = ivtv_g_audout,
+ .vidioc_enum_input = ivtv_enum_input,
+ .vidioc_enum_output = ivtv_enum_output,
+ .vidioc_enumaudout = ivtv_enumaudout,
+ .vidioc_cropcap = ivtv_cropcap,
.vidioc_s_selection = ivtv_s_selection,
.vidioc_g_selection = ivtv_g_selection,
- .vidioc_g_input = ivtv_g_input,
- .vidioc_s_input = ivtv_s_input,
- .vidioc_g_output = ivtv_g_output,
- .vidioc_s_output = ivtv_s_output,
- .vidioc_g_frequency = ivtv_g_frequency,
- .vidioc_s_frequency = ivtv_s_frequency,
- .vidioc_s_tuner = ivtv_s_tuner,
- .vidioc_g_tuner = ivtv_g_tuner,
- .vidioc_g_enc_index = ivtv_g_enc_index,
+ .vidioc_g_input = ivtv_g_input,
+ .vidioc_s_input = ivtv_s_input,
+ .vidioc_g_output = ivtv_g_output,
+ .vidioc_s_output = ivtv_s_output,
+ .vidioc_g_frequency = ivtv_g_frequency,
+ .vidioc_s_frequency = ivtv_s_frequency,
+ .vidioc_s_tuner = ivtv_s_tuner,
+ .vidioc_g_tuner = ivtv_g_tuner,
+ .vidioc_g_enc_index = ivtv_g_enc_index,
.vidioc_g_fbuf = ivtv_g_fbuf,
.vidioc_s_fbuf = ivtv_s_fbuf,
- .vidioc_g_std = ivtv_g_std,
- .vidioc_s_std = ivtv_s_std,
+ .vidioc_g_std = ivtv_g_std,
+ .vidioc_s_std = ivtv_s_std,
.vidioc_overlay = ivtv_overlay,
.vidioc_log_status = ivtv_log_status,
- .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
- .vidioc_encoder_cmd = ivtv_encoder_cmd,
- .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
+ .vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap,
+ .vidioc_encoder_cmd = ivtv_encoder_cmd,
+ .vidioc_try_encoder_cmd = ivtv_try_encoder_cmd,
.vidioc_decoder_cmd = ivtv_decoder_cmd,
.vidioc_try_decoder_cmd = ivtv_try_decoder_cmd,
- .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
- .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out,
+ .vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap,
.vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap,
.vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap,
.vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out,
.vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay,
.vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out,
- .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
- .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
+ .vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap,
+ .vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap,
.vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap,
.vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out,
.vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay,
.vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out,
- .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap,
.vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap,
.vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap,
- .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
+ .vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out,
.vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay,
- .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
- .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
+ .vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out,
+ .vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap,
#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = ivtv_g_register,
- .vidioc_s_register = ivtv_s_register,
+ .vidioc_g_register = ivtv_g_register,
+ .vidioc_s_register = ivtv_s_register,
#endif
- .vidioc_default = ivtv_default,
- .vidioc_subscribe_event = ivtv_subscribe_event,
- .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+ .vidioc_default = ivtv_default,
+ .vidioc_subscribe_event = ivtv_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
void ivtv_set_funcs(struct video_device *vdev)
diff --git a/drivers/media/pci/ivtv/ivtv-mailbox.c b/drivers/media/pci/ivtv/ivtv-mailbox.c
index 9a2506a5edbe..f317c8f0938d 100644
--- a/drivers/media/pci/ivtv/ivtv-mailbox.c
+++ b/drivers/media/pci/ivtv/ivtv-mailbox.c
@@ -28,118 +28,118 @@
#define IVTV_MBOX_FIRMWARE_DONE 0x00000004
#define IVTV_MBOX_DRIVER_DONE 0x00000002
#define IVTV_MBOX_DRIVER_BUSY 0x00000001
-#define IVTV_MBOX_FREE 0x00000000
+#define IVTV_MBOX_FREE 0x00000000
/* Firmware mailbox standard timeout */
-#define IVTV_API_STD_TIMEOUT 0x02000000
+#define IVTV_API_STD_TIMEOUT 0x02000000
-#define API_CACHE (1 << 0) /* Allow the command to be stored in the cache */
-#define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */
+#define API_CACHE (1 << 0) /* Allow the command to be stored in the cache */
+#define API_RESULT (1 << 1) /* Allow 1 second for this cmd to end */
#define API_FAST_RESULT (3 << 1) /* Allow 0.1 second for this cmd to end */
-#define API_DMA (1 << 3) /* DMA mailbox, has special handling */
-#define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */
-#define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */
+#define API_DMA (1 << 3) /* DMA mailbox, has special handling */
+#define API_HIGH_VOL (1 << 5) /* High volume command (i.e. called during encoding or decoding) */
+#define API_NO_WAIT_MB (1 << 4) /* Command may not wait for a free mailbox */
#define API_NO_WAIT_RES (1 << 5) /* Command may not wait for the result */
#define API_NO_POLL (1 << 6) /* Avoid pointless polling */
struct ivtv_api_info {
int flags; /* Flags, see above */
- const char *name; /* The name of the command */
+ const char *name; /* The name of the command */
};
#define API_ENTRY(x, f) [x] = { (f), #x }
static const struct ivtv_api_info api_info[256] = {
/* MPEG encoder API */
- API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT | API_NO_POLL),
- API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_PCR_ID, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_FRAME_RATE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_BIT_RATE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_VBI_LINE, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES, API_CACHE),
- API_ENTRY(CX2341X_ENC_HALT_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_GET_VERSION, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE, API_CACHE),
- API_ENTRY(CX2341X_ENC_GET_SEQ_END, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, API_CACHE),
- API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA | API_HIGH_VOL),
- API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, API_CACHE),
- API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, API_RESULT),
- API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB | API_HIGH_VOL),
- API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, API_RESULT),
- API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, API_CACHE),
- API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER, API_CACHE),
- API_ENTRY(CX2341X_ENC_MUTE_VIDEO, API_RESULT),
- API_ENTRY(CX2341X_ENC_MUTE_AUDIO, API_RESULT),
+ API_ENTRY(CX2341X_ENC_PING_FW, API_FAST_RESULT),
+ API_ENTRY(CX2341X_ENC_START_CAPTURE, API_RESULT | API_NO_POLL),
+ API_ENTRY(CX2341X_ENC_STOP_CAPTURE, API_RESULT),
+ API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_PCR_ID, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_FRAME_RATE, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_BIT_RATE, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_VBI_LINE, API_RESULT),
+ API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES, API_CACHE),
+ API_ENTRY(CX2341X_ENC_HALT_FW, API_FAST_RESULT),
+ API_ENTRY(CX2341X_ENC_GET_VERSION, API_FAST_RESULT),
+ API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE, API_CACHE),
+ API_ENTRY(CX2341X_ENC_GET_SEQ_END, API_RESULT),
+ API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO, API_FAST_RESULT),
+ API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG, API_RESULT),
+ API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, API_CACHE),
+ API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, API_FAST_RESULT),
+ API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, API_FAST_RESULT),
+ API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, API_DMA | API_HIGH_VOL),
+ API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, API_RESULT),
+ API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, API_CACHE),
+ API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, API_RESULT),
+ API_ENTRY(CX2341X_ENC_REFRESH_INPUT, API_NO_WAIT_MB | API_HIGH_VOL),
+ API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, API_RESULT),
+ API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, API_CACHE),
+ API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER, API_CACHE),
+ API_ENTRY(CX2341X_ENC_MUTE_VIDEO, API_RESULT),
+ API_ENTRY(CX2341X_ENC_MUTE_AUDIO, API_RESULT),
API_ENTRY(CX2341X_ENC_SET_VERT_CROP_LINE, API_FAST_RESULT),
- API_ENTRY(CX2341X_ENC_MISC, API_FAST_RESULT),
+ API_ENTRY(CX2341X_ENC_MISC, API_FAST_RESULT),
/* Obsolete PULLDOWN API command */
- API_ENTRY(0xb1, API_CACHE),
+ API_ENTRY(0xb1, API_CACHE),
/* MPEG decoder API */
- API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT | API_NO_POLL),
- API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT),
- API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, API_CACHE),
- API_ENTRY(CX2341X_DEC_GET_XFER_INFO, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA | API_HIGH_VOL),
- API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, API_RESULT),
- API_ENTRY(CX2341X_DEC_HALT_FW, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SET_STANDARD, API_CACHE),
- API_ENTRY(CX2341X_DEC_GET_VERSION, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT, API_CACHE),
- API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, API_RESULT /*| API_NO_WAIT_RES*/),
- API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE, API_CACHE),
- API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS, API_CACHE),
- API_ENTRY(CX2341X_DEC_EXTRACT_VBI, API_RESULT),
- API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE, API_FAST_RESULT),
- API_ENTRY(CX2341X_DEC_SET_PREBUFFERING, API_CACHE),
+ API_ENTRY(CX2341X_DEC_PING_FW, API_FAST_RESULT),
+ API_ENTRY(CX2341X_DEC_START_PLAYBACK, API_RESULT | API_NO_POLL),
+ API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, API_RESULT),
+ API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, API_RESULT),
+ API_ENTRY(CX2341X_DEC_STEP_VIDEO, API_RESULT),
+ API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, API_CACHE),
+ API_ENTRY(CX2341X_DEC_GET_XFER_INFO, API_FAST_RESULT),
+ API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, API_FAST_RESULT),
+ API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, API_DMA | API_HIGH_VOL),
+ API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, API_RESULT),
+ API_ENTRY(CX2341X_DEC_HALT_FW, API_FAST_RESULT),
+ API_ENTRY(CX2341X_DEC_SET_STANDARD, API_CACHE),
+ API_ENTRY(CX2341X_DEC_GET_VERSION, API_FAST_RESULT),
+ API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT, API_CACHE),
+ API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, API_RESULT /*| API_NO_WAIT_RES*/),
+ API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE, API_CACHE),
+ API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION, API_RESULT),
+ API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS, API_CACHE),
+ API_ENTRY(CX2341X_DEC_EXTRACT_VBI, API_RESULT),
+ API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE, API_FAST_RESULT),
+ API_ENTRY(CX2341X_DEC_SET_PREBUFFERING, API_CACHE),
/* OSD API */
- API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_STATE, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_STATE, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_OSD_COORDS, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_OSD_COORDS, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA, API_CACHE),
- API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE, API_CACHE),
- API_ENTRY(CX2341X_OSD_BLT_COPY, API_RESULT),
- API_ENTRY(CX2341X_OSD_BLT_FILL, API_RESULT),
- API_ENTRY(CX2341X_OSD_BLT_TEXT, API_RESULT),
- API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, API_CACHE),
- API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY, API_CACHE),
- API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX, API_FAST_RESULT),
- API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX, API_CACHE)
+ API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER, API_FAST_RESULT),
+ API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT, API_FAST_RESULT),
+ API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT, API_CACHE),
+ API_ENTRY(CX2341X_OSD_GET_STATE, API_FAST_RESULT),
+ API_ENTRY(CX2341X_OSD_SET_STATE, API_CACHE),
+ API_ENTRY(CX2341X_OSD_GET_OSD_COORDS, API_FAST_RESULT),
+ API_ENTRY(CX2341X_OSD_SET_OSD_COORDS, API_CACHE),
+ API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS, API_FAST_RESULT),
+ API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS, API_CACHE),
+ API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA, API_FAST_RESULT),
+ API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA, API_CACHE),
+ API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS, API_CACHE),
+ API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE, API_FAST_RESULT),
+ API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE, API_CACHE),
+ API_ENTRY(CX2341X_OSD_BLT_COPY, API_RESULT),
+ API_ENTRY(CX2341X_OSD_BLT_FILL, API_RESULT),
+ API_ENTRY(CX2341X_OSD_BLT_TEXT, API_RESULT),
+ API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, API_CACHE),
+ API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY, API_CACHE),
+ API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX, API_FAST_RESULT),
+ API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX, API_CACHE)
};
static int try_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int mb)
diff --git a/drivers/media/pci/mantis/Makefile b/drivers/media/pci/mantis/Makefile
index a684dc2ec79e..b5ef39692cb0 100644
--- a/drivers/media/pci/mantis/Makefile
+++ b/drivers/media/pci/mantis/Makefile
@@ -26,4 +26,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-core/ -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/dvb-frontends/
diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c
index ed855e3df558..89759cb80ecb 100644
--- a/drivers/media/pci/mantis/hopper_cards.c
+++ b/drivers/media/pci/mantis/hopper_cards.c
@@ -26,11 +26,11 @@
#include <asm/irq.h>
#include <linux/interrupt.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "hopper_vp3028.h"
diff --git a/drivers/media/pci/mantis/hopper_vp3028.c b/drivers/media/pci/mantis/hopper_vp3028.c
index 1032db6bb789..d58ae0097fea 100644
--- a/drivers/media/pci/mantis/hopper_vp3028.c
+++ b/drivers/media/pci/mantis/hopper_vp3028.c
@@ -22,11 +22,11 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "zl10353.h"
#include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_ca.c b/drivers/media/pci/mantis/mantis_ca.c
index 60c6c2f24066..4f0ba457c7e5 100644
--- a/drivers/media/pci/mantis/mantis_ca.c
+++ b/drivers/media/pci/mantis/mantis_ca.c
@@ -24,11 +24,11 @@
#include <linux/interrupt.h>
#include <asm/io.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_link.h"
diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c
index 4ce8a90d69dc..7eb75cb7d75a 100644
--- a/drivers/media/pci/mantis/mantis_cards.c
+++ b/drivers/media/pci/mantis/mantis_cards.c
@@ -27,11 +27,11 @@
#include <linux/interrupt.h>
#include <media/rc-map.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_dma.c b/drivers/media/pci/mantis/mantis_dma.c
index 2ce310b0a022..84406a428330 100644
--- a/drivers/media/pci/mantis/mantis_dma.c
+++ b/drivers/media/pci/mantis/mantis_dma.c
@@ -28,11 +28,11 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_reg.h"
diff --git a/drivers/media/pci/mantis/mantis_dvb.c b/drivers/media/pci/mantis/mantis_dvb.c
index 0db4de3a2285..54dbaa700fa3 100644
--- a/drivers/media/pci/mantis/mantis_dvb.c
+++ b/drivers/media/pci/mantis/mantis_dvb.c
@@ -26,11 +26,11 @@
#include <linux/pci.h>
#include <linux/i2c.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_dma.h"
diff --git a/drivers/media/pci/mantis/mantis_evm.c b/drivers/media/pci/mantis/mantis_evm.c
index 909ff54868a3..443ac5ab4902 100644
--- a/drivers/media/pci/mantis/mantis_evm.c
+++ b/drivers/media/pci/mantis/mantis_evm.c
@@ -25,11 +25,11 @@
#include <linux/interrupt.h>
#include <asm/io.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_link.h"
diff --git a/drivers/media/pci/mantis/mantis_hif.c b/drivers/media/pci/mantis/mantis_hif.c
index 10c68df7e16f..bf61f8c5a59f 100644
--- a/drivers/media/pci/mantis/mantis_hif.c
+++ b/drivers/media/pci/mantis/mantis_hif.c
@@ -25,11 +25,11 @@
#include <linux/interrupt.h>
#include <asm/io.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_i2c.c b/drivers/media/pci/mantis/mantis_i2c.c
index 496c10dfc4df..6528a2180119 100644
--- a/drivers/media/pci/mantis/mantis_i2c.c
+++ b/drivers/media/pci/mantis/mantis_i2c.c
@@ -23,11 +23,11 @@
#include <linux/pci.h>
#include <linux/i2c.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_reg.h"
diff --git a/drivers/media/pci/mantis/mantis_input.c b/drivers/media/pci/mantis/mantis_input.c
index 7519dcc934dd..5b472e9b9542 100644
--- a/drivers/media/pci/mantis/mantis_input.c
+++ b/drivers/media/pci/mantis/mantis_input.c
@@ -17,11 +17,11 @@
#include <media/rc-core.h>
#include <linux/pci.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_input.h"
diff --git a/drivers/media/pci/mantis/mantis_ioc.c b/drivers/media/pci/mantis/mantis_ioc.c
index 24fcdc63d6d5..f45c2340a493 100644
--- a/drivers/media/pci/mantis/mantis_ioc.c
+++ b/drivers/media/pci/mantis/mantis_ioc.c
@@ -26,11 +26,11 @@
#include <linux/interrupt.h>
#include <asm/io.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_reg.h"
diff --git a/drivers/media/pci/mantis/mantis_link.h b/drivers/media/pci/mantis/mantis_link.h
index 2a814774a001..c6698976fc2f 100644
--- a/drivers/media/pci/mantis/mantis_link.h
+++ b/drivers/media/pci/mantis/mantis_link.h
@@ -23,7 +23,7 @@
#include <linux/mutex.h>
#include <linux/workqueue.h>
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
enum mantis_sbuf_status {
MANTIS_SBUF_DATA_AVAIL = 1,
diff --git a/drivers/media/pci/mantis/mantis_pci.c b/drivers/media/pci/mantis/mantis_pci.c
index 9e89e045213a..d590524b4171 100644
--- a/drivers/media/pci/mantis/mantis_pci.c
+++ b/drivers/media/pci/mantis/mantis_pci.c
@@ -34,11 +34,11 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_reg.h"
diff --git a/drivers/media/pci/mantis/mantis_pcmcia.c b/drivers/media/pci/mantis/mantis_pcmcia.c
index b2dbc7b2e0f6..2a316b988c07 100644
--- a/drivers/media/pci/mantis/mantis_pcmcia.c
+++ b/drivers/media/pci/mantis/mantis_pcmcia.c
@@ -25,11 +25,11 @@
#include <linux/interrupt.h>
#include <asm/io.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_link.h" /* temporary due to physical layer stuff */
diff --git a/drivers/media/pci/mantis/mantis_reg.h b/drivers/media/pci/mantis/mantis_reg.h
index 7761f9dc7fe0..762ed9f7a08e 100644
--- a/drivers/media/pci/mantis/mantis_reg.h
+++ b/drivers/media/pci/mantis/mantis_reg.h
@@ -166,12 +166,12 @@
#define MANTIS_CARD_PLUGOUT (0x01 << 0)
#define MANTIS_GPIF_BRADDR 0xa0
-#define MANTIS_GPIF_PCMCIAREG (0x01 << 27)
-#define MANTIS_GPIF_PCMCIAIOM (0x01 << 26)
+#define MANTIS_GPIF_PCMCIAREG (0x01 << 27)
+#define MANTIS_GPIF_PCMCIAIOM (0x01 << 26)
#define MANTIS_GPIF_BR_ADDR (0xfffffff << 0)
#define MANTIS_GPIF_BRBYTES 0xa4
-#define MANTIS_GPIF_BRCNT (0xfff << 0)
+#define MANTIS_GPIF_BRCNT (0xfff << 0)
#define MANTIS_PCMCIA_RESET 0xa8
#define MANTIS_PCMCIA_RSTVAL (0xff << 0)
diff --git a/drivers/media/pci/mantis/mantis_uart.c b/drivers/media/pci/mantis/mantis_uart.c
index f1c96aec8c7b..18f81c135996 100644
--- a/drivers/media/pci/mantis/mantis_uart.c
+++ b/drivers/media/pci/mantis/mantis_uart.c
@@ -27,11 +27,11 @@
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_reg.h"
diff --git a/drivers/media/pci/mantis/mantis_vp1033.c b/drivers/media/pci/mantis/mantis_vp1033.c
index 12a6adb2bd7e..54d2ab409cc5 100644
--- a/drivers/media/pci/mantis/mantis_vp1033.c
+++ b/drivers/media/pci/mantis/mantis_vp1033.c
@@ -22,11 +22,11 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "stv0299.h"
#include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_vp1034.c b/drivers/media/pci/mantis/mantis_vp1034.c
index e4972ff823c2..26672a49b86f 100644
--- a/drivers/media/pci/mantis/mantis_vp1034.c
+++ b/drivers/media/pci/mantis/mantis_vp1034.c
@@ -23,11 +23,11 @@
#include <linux/interrupt.h>
#include <asm/io.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mb86a16.h"
#include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_vp1034.h b/drivers/media/pci/mantis/mantis_vp1034.h
index 764b1c66ea1b..35af4e5dcc8c 100644
--- a/drivers/media/pci/mantis/mantis_vp1034.h
+++ b/drivers/media/pci/mantis/mantis_vp1034.h
@@ -21,7 +21,7 @@
#ifndef __MANTIS_VP1034_H
#define __MANTIS_VP1034_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_vp1041.c b/drivers/media/pci/mantis/mantis_vp1041.c
index 7082fcbc94a1..0eeccc2d19a5 100644
--- a/drivers/media/pci/mantis/mantis_vp1041.c
+++ b/drivers/media/pci/mantis/mantis_vp1041.c
@@ -22,11 +22,11 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "mantis_common.h"
#include "mantis_ioc.h"
@@ -47,70 +47,70 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = {
/* 0x0000000b, *//* SYSREG */
{ STB0899_DEV_ID , 0x30 },
{ STB0899_DISCNTRL1 , 0x32 },
- { STB0899_DISCNTRL2 , 0x80 },
- { STB0899_DISRX_ST0 , 0x04 },
- { STB0899_DISRX_ST1 , 0x00 },
- { STB0899_DISPARITY , 0x00 },
+ { STB0899_DISCNTRL2 , 0x80 },
+ { STB0899_DISRX_ST0 , 0x04 },
+ { STB0899_DISRX_ST1 , 0x00 },
+ { STB0899_DISPARITY , 0x00 },
{ STB0899_DISSTATUS , 0x20 },
- { STB0899_DISF22 , 0x99 },
- { STB0899_DISF22RX , 0xa8 },
+ { STB0899_DISF22 , 0x99 },
+ { STB0899_DISF22RX , 0xa8 },
/* SYSREG ? */
- { STB0899_ACRPRESC , 0x11 },
- { STB0899_ACRDIV1 , 0x0a },
- { STB0899_ACRDIV2 , 0x05 },
- { STB0899_DACR1 , 0x00 },
- { STB0899_DACR2 , 0x00 },
- { STB0899_OUTCFG , 0x00 },
- { STB0899_MODECFG , 0x00 },
+ { STB0899_ACRPRESC , 0x11 },
+ { STB0899_ACRDIV1 , 0x0a },
+ { STB0899_ACRDIV2 , 0x05 },
+ { STB0899_DACR1 , 0x00 },
+ { STB0899_DACR2 , 0x00 },
+ { STB0899_OUTCFG , 0x00 },
+ { STB0899_MODECFG , 0x00 },
{ STB0899_IRQSTATUS_3 , 0xfe },
{ STB0899_IRQSTATUS_2 , 0x03 },
{ STB0899_IRQSTATUS_1 , 0x7c },
{ STB0899_IRQSTATUS_0 , 0xf4 },
- { STB0899_IRQMSK_3 , 0xf3 },
- { STB0899_IRQMSK_2 , 0xfc },
- { STB0899_IRQMSK_1 , 0xff },
+ { STB0899_IRQMSK_3 , 0xf3 },
+ { STB0899_IRQMSK_2 , 0xfc },
+ { STB0899_IRQMSK_1 , 0xff },
{ STB0899_IRQMSK_0 , 0xff },
{ STB0899_IRQCFG , 0x00 },
- { STB0899_I2CCFG , 0x88 },
- { STB0899_I2CRPT , 0x58 },
+ { STB0899_I2CCFG , 0x88 },
+ { STB0899_I2CRPT , 0x58 },
{ STB0899_IOPVALUE5 , 0x00 },
{ STB0899_IOPVALUE4 , 0x33 },
{ STB0899_IOPVALUE3 , 0x6d },
{ STB0899_IOPVALUE2 , 0x90 },
{ STB0899_IOPVALUE1 , 0x60 },
{ STB0899_IOPVALUE0 , 0x00 },
- { STB0899_GPIO00CFG , 0x82 },
- { STB0899_GPIO01CFG , 0x82 },
- { STB0899_GPIO02CFG , 0x82 },
- { STB0899_GPIO03CFG , 0x82 },
- { STB0899_GPIO04CFG , 0x82 },
- { STB0899_GPIO05CFG , 0x82 },
- { STB0899_GPIO06CFG , 0x82 },
- { STB0899_GPIO07CFG , 0x82 },
- { STB0899_GPIO08CFG , 0x82 },
- { STB0899_GPIO09CFG , 0x82 },
- { STB0899_GPIO10CFG , 0x82 },
- { STB0899_GPIO11CFG , 0x82 },
- { STB0899_GPIO12CFG , 0x82 },
- { STB0899_GPIO13CFG , 0x82 },
- { STB0899_GPIO14CFG , 0x82 },
- { STB0899_GPIO15CFG , 0x82 },
- { STB0899_GPIO16CFG , 0x82 },
- { STB0899_GPIO17CFG , 0x82 },
- { STB0899_GPIO18CFG , 0x82 },
- { STB0899_GPIO19CFG , 0x82 },
- { STB0899_GPIO20CFG , 0x82 },
- { STB0899_SDATCFG , 0xb8 },
- { STB0899_SCLTCFG , 0xba },
- { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
- { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
- { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
- { STB0899_DIRCLKCFG , 0x82 },
- { STB0899_CLKOUT27CFG , 0x7e },
- { STB0899_STDBYCFG , 0x82 },
- { STB0899_CS0CFG , 0x82 },
- { STB0899_CS1CFG , 0x82 },
- { STB0899_DISEQCOCFG , 0x20 },
+ { STB0899_GPIO00CFG , 0x82 },
+ { STB0899_GPIO01CFG , 0x82 },
+ { STB0899_GPIO02CFG , 0x82 },
+ { STB0899_GPIO03CFG , 0x82 },
+ { STB0899_GPIO04CFG , 0x82 },
+ { STB0899_GPIO05CFG , 0x82 },
+ { STB0899_GPIO06CFG , 0x82 },
+ { STB0899_GPIO07CFG , 0x82 },
+ { STB0899_GPIO08CFG , 0x82 },
+ { STB0899_GPIO09CFG , 0x82 },
+ { STB0899_GPIO10CFG , 0x82 },
+ { STB0899_GPIO11CFG , 0x82 },
+ { STB0899_GPIO12CFG , 0x82 },
+ { STB0899_GPIO13CFG , 0x82 },
+ { STB0899_GPIO14CFG , 0x82 },
+ { STB0899_GPIO15CFG , 0x82 },
+ { STB0899_GPIO16CFG , 0x82 },
+ { STB0899_GPIO17CFG , 0x82 },
+ { STB0899_GPIO18CFG , 0x82 },
+ { STB0899_GPIO19CFG , 0x82 },
+ { STB0899_GPIO20CFG , 0x82 },
+ { STB0899_SDATCFG , 0xb8 },
+ { STB0899_SCLTCFG , 0xba },
+ { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
+ { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
+ { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
+ { STB0899_DIRCLKCFG , 0x82 },
+ { STB0899_CLKOUT27CFG , 0x7e },
+ { STB0899_STDBYCFG , 0x82 },
+ { STB0899_CS0CFG , 0x82 },
+ { STB0899_CS1CFG , 0x82 },
+ { STB0899_DISEQCOCFG , 0x20 },
{ STB0899_GPIO32CFG , 0x82 },
{ STB0899_GPIO33CFG , 0x82 },
{ STB0899_GPIO34CFG , 0x82 },
@@ -119,35 +119,35 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = {
{ STB0899_GPIO37CFG , 0x82 },
{ STB0899_GPIO38CFG , 0x82 },
{ STB0899_GPIO39CFG , 0x82 },
- { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
- { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
- { STB0899_FILTCTRL , 0x00 },
- { STB0899_SYSCTRL , 0x01 },
- { STB0899_STOPCLK1 , 0x20 },
- { STB0899_STOPCLK2 , 0x00 },
+ { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+ { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+ { STB0899_FILTCTRL , 0x00 },
+ { STB0899_SYSCTRL , 0x01 },
+ { STB0899_STOPCLK1 , 0x20 },
+ { STB0899_STOPCLK2 , 0x00 },
{ STB0899_INTBUFSTATUS , 0x00 },
- { STB0899_INTBUFCTRL , 0x0a },
+ { STB0899_INTBUFCTRL , 0x0a },
{ 0xffff , 0xff },
};
static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
- { STB0899_DEMOD , 0x00 },
- { STB0899_RCOMPC , 0xc9 },
- { STB0899_AGC1CN , 0x01 },
- { STB0899_AGC1REF , 0x10 },
+ { STB0899_DEMOD , 0x00 },
+ { STB0899_RCOMPC , 0xc9 },
+ { STB0899_AGC1CN , 0x01 },
+ { STB0899_AGC1REF , 0x10 },
{ STB0899_RTC , 0x23 },
- { STB0899_TMGCFG , 0x4e },
- { STB0899_AGC2REF , 0x34 },
- { STB0899_TLSR , 0x84 },
- { STB0899_CFD , 0xf7 },
+ { STB0899_TMGCFG , 0x4e },
+ { STB0899_AGC2REF , 0x34 },
+ { STB0899_TLSR , 0x84 },
+ { STB0899_CFD , 0xf7 },
{ STB0899_ACLC , 0x87 },
- { STB0899_BCLC , 0x94 },
- { STB0899_EQON , 0x41 },
- { STB0899_LDT , 0xf1 },
- { STB0899_LDT2 , 0xe3 },
- { STB0899_EQUALREF , 0xb4 },
- { STB0899_TMGRAMP , 0x10 },
- { STB0899_TMGTHD , 0x30 },
+ { STB0899_BCLC , 0x94 },
+ { STB0899_EQON , 0x41 },
+ { STB0899_LDT , 0xf1 },
+ { STB0899_LDT2 , 0xe3 },
+ { STB0899_EQUALREF , 0xb4 },
+ { STB0899_TMGRAMP , 0x10 },
+ { STB0899_TMGTHD , 0x30 },
{ STB0899_IDCCOMP , 0xfd },
{ STB0899_QDCCOMP , 0xff },
{ STB0899_POWERI , 0x0c },
@@ -166,12 +166,12 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
{ STB0899_NIRL , 0x80 },
{ STB0899_ISYMB , 0x1d },
{ STB0899_QSYMB , 0xa6 },
- { STB0899_SFRH , 0x2f },
- { STB0899_SFRM , 0x68 },
- { STB0899_SFRL , 0x40 },
- { STB0899_SFRUPH , 0x2f },
- { STB0899_SFRUPM , 0x68 },
- { STB0899_SFRUPL , 0x40 },
+ { STB0899_SFRH , 0x2f },
+ { STB0899_SFRM , 0x68 },
+ { STB0899_SFRL , 0x40 },
+ { STB0899_SFRUPH , 0x2f },
+ { STB0899_SFRUPM , 0x68 },
+ { STB0899_SFRUPL , 0x40 },
{ STB0899_EQUAI1 , 0x02 },
{ STB0899_EQUAQ1 , 0xff },
{ STB0899_EQUAI2 , 0x04 },
@@ -183,7 +183,7 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
{ STB0899_EQUAI5 , 0x08 },
{ STB0899_EQUAQ5 , 0xf5 },
{ STB0899_DSTATUS2 , 0x00 },
- { STB0899_VSTATUS , 0x00 },
+ { STB0899_VSTATUS , 0x00 },
{ STB0899_VERROR , 0x86 },
{ STB0899_IQSWAP , 0x2a },
{ STB0899_ECNT1M , 0x00 },
@@ -192,26 +192,26 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
{ STB0899_ECNT2L , 0x00 },
{ STB0899_ECNT3M , 0x0a },
{ STB0899_ECNT3L , 0xad },
- { STB0899_FECAUTO1 , 0x06 },
+ { STB0899_FECAUTO1 , 0x06 },
{ STB0899_FECM , 0x01 },
- { STB0899_VTH12 , 0xb0 },
- { STB0899_VTH23 , 0x7a },
+ { STB0899_VTH12 , 0xb0 },
+ { STB0899_VTH23 , 0x7a },
{ STB0899_VTH34 , 0x58 },
- { STB0899_VTH56 , 0x38 },
- { STB0899_VTH67 , 0x34 },
- { STB0899_VTH78 , 0x24 },
- { STB0899_PRVIT , 0xff },
- { STB0899_VITSYNC , 0x19 },
- { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
- { STB0899_TSULC , 0x42 },
- { STB0899_RSLLC , 0x41 },
+ { STB0899_VTH56 , 0x38 },
+ { STB0899_VTH67 , 0x34 },
+ { STB0899_VTH78 , 0x24 },
+ { STB0899_PRVIT , 0xff },
+ { STB0899_VITSYNC , 0x19 },
+ { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+ { STB0899_TSULC , 0x42 },
+ { STB0899_RSLLC , 0x41 },
{ STB0899_TSLPL , 0x12 },
- { STB0899_TSCFGH , 0x0c },
- { STB0899_TSCFGM , 0x00 },
- { STB0899_TSCFGL , 0x00 },
+ { STB0899_TSCFGH , 0x0c },
+ { STB0899_TSCFGM , 0x00 },
+ { STB0899_TSCFGL , 0x00 },
{ STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */
- { STB0899_RSSYNCDEL , 0x00 },
- { STB0899_TSINHDELH , 0x02 },
+ { STB0899_RSSYNCDEL , 0x00 },
+ { STB0899_TSINHDELH , 0x02 },
{ STB0899_TSINHDELM , 0x00 },
{ STB0899_TSINHDELL , 0x00 },
{ STB0899_TSLLSTKM , 0x1b },
@@ -222,18 +222,18 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
{ STB0899_PCKLENLL , 0xcc },
{ STB0899_RSPCKLEN , 0xbd },
{ STB0899_TSSTATUS , 0x90 },
- { STB0899_ERRCTRL1 , 0xb6 },
- { STB0899_ERRCTRL2 , 0x95 },
- { STB0899_ERRCTRL3 , 0x8d },
+ { STB0899_ERRCTRL1 , 0xb6 },
+ { STB0899_ERRCTRL2 , 0x95 },
+ { STB0899_ERRCTRL3 , 0x8d },
{ STB0899_DMONMSK1 , 0x27 },
{ STB0899_DMONMSK0 , 0x03 },
- { STB0899_DEMAPVIT , 0x5c },
+ { STB0899_DEMAPVIT , 0x5c },
{ STB0899_PLPARM , 0x19 },
- { STB0899_PDELCTRL , 0x48 },
- { STB0899_PDELCTRL2 , 0x00 },
- { STB0899_BBHCTRL1 , 0x00 },
- { STB0899_BBHCTRL2 , 0x00 },
- { STB0899_HYSTTHRESH , 0x77 },
+ { STB0899_PDELCTRL , 0x48 },
+ { STB0899_PDELCTRL2 , 0x00 },
+ { STB0899_BBHCTRL1 , 0x00 },
+ { STB0899_BBHCTRL2 , 0x00 },
+ { STB0899_HYSTTHRESH , 0x77 },
{ STB0899_MATCSTM , 0x00 },
{ STB0899_MATCSTL , 0x00 },
{ STB0899_UPLCSTM , 0x00 },
@@ -270,7 +270,7 @@ static struct stb0899_config vp1041_stb0899_config = {
.init_s2_fec = stb0899_s2_init_4,
.init_tst = stb0899_s1_init_5,
- .demod_address = 0x68, /* 0xd0 >> 1 */
+ .demod_address = 0x68, /* 0xd0 >> 1 */
.xtal_freq = 27000000,
.inversion = IQ_SWAP_ON,
diff --git a/drivers/media/pci/mantis/mantis_vp2033.c b/drivers/media/pci/mantis/mantis_vp2033.c
index 8d48b5abe04a..d98e0a3edaab 100644
--- a/drivers/media/pci/mantis/mantis_vp2033.c
+++ b/drivers/media/pci/mantis/mantis_vp2033.c
@@ -22,11 +22,11 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "tda1002x.h"
#include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_vp2040.c b/drivers/media/pci/mantis/mantis_vp2040.c
index 8dd17d7c0881..2c52f3d4e2bc 100644
--- a/drivers/media/pci/mantis/mantis_vp2040.c
+++ b/drivers/media/pci/mantis/mantis_vp2040.c
@@ -22,11 +22,11 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "tda1002x.h"
#include "mantis_common.h"
diff --git a/drivers/media/pci/mantis/mantis_vp3028.h b/drivers/media/pci/mantis/mantis_vp3028.h
index b07be6adc522..34130d29e0aa 100644
--- a/drivers/media/pci/mantis/mantis_vp3028.h
+++ b/drivers/media/pci/mantis/mantis_vp3028.h
@@ -21,7 +21,7 @@
#ifndef __MANTIS_VP3028_H
#define __MANTIS_VP3028_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mantis_common.h"
#include "zl10353.h"
diff --git a/drivers/media/pci/mantis/mantis_vp3030.c b/drivers/media/pci/mantis/mantis_vp3030.c
index 5c1dd925bdd5..14f6e153000c 100644
--- a/drivers/media/pci/mantis/mantis_vp3030.c
+++ b/drivers/media/pci/mantis/mantis_vp3030.c
@@ -22,11 +22,11 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "zl10353.h"
#include "tda665x.h"
diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c
index f74b08635082..ae83293723ba 100644
--- a/drivers/media/pci/meye/meye.c
+++ b/drivers/media/pci/meye/meye.c
@@ -1536,7 +1536,7 @@ static const struct v4l2_ioctl_ops meye_ioctl_ops = {
static const struct video_device meye_template = {
.name = "meye",
.fops = &meye_fops,
- .ioctl_ops = &meye_ioctl_ops,
+ .ioctl_ops = &meye_ioctl_ops,
.release = video_device_release_empty,
};
diff --git a/drivers/media/pci/netup_unidvb/Makefile b/drivers/media/pci/netup_unidvb/Makefile
index 07d3f1eb728b..944c3e164157 100644
--- a/drivers/media/pci/netup_unidvb/Makefile
+++ b/drivers/media/pci/netup_unidvb/Makefile
@@ -6,5 +6,4 @@ netup-unidvb-objs += netup_unidvb_spi.o
obj-$(CONFIG_DVB_NETUP_UNIDVB) += netup-unidvb.o
-ccflags-y += -Idrivers/media/dvb-core
ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb.h b/drivers/media/pci/netup_unidvb/netup_unidvb.h
index 39b08ecda1fc..3253ac324841 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb.h
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb.h
@@ -24,7 +24,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/videobuf2-dvb.h>
-#include <dvb_ca_en50221.h>
+#include <media/dvb_ca_en50221.h>
#define NETUP_UNIDVB_NAME "netup_unidvb"
#define NETUP_UNIDVB_VERSION "0.0.1"
diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
index 509d69e6ca4a..ead59fabd15f 100644
--- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
+++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c
@@ -862,7 +862,7 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev,
PCI_EXP_DEVCTL_NOSNOOP_EN, 0);
/* Adjust PCIe completion timeout. */
pcie_capability_clear_and_set_word(pci_dev,
- PCI_EXP_DEVCTL2, 0xf, 0x2);
+ PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_COMP_TIMEOUT, 0x2);
if (netup_unidvb_request_mmio(pci_dev)) {
dev_err(&pci_dev->dev,
diff --git a/drivers/media/pci/ngene/Makefile b/drivers/media/pci/ngene/Makefile
index dbdf284970f8..e4208f5ed215 100644
--- a/drivers/media/pci/ngene/Makefile
+++ b/drivers/media/pci/ngene/Makefile
@@ -7,7 +7,6 @@ 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-core/
ccflags-y += -Idrivers/media/dvb-frontends/
ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/media/pci/ngene/ngene.h b/drivers/media/pci/ngene/ngene.h
index 7c7cd217333d..02dbd18f92d0 100644
--- a/drivers/media/pci/ngene/ngene.h
+++ b/drivers/media/pci/ngene/ngene.h
@@ -29,13 +29,13 @@
#include <linux/dvb/frontend.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_ca_en50221.h"
-#include "dvb_frontend.h"
-#include "dvb_ringbuffer.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_ca_en50221.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_ringbuffer.h>
+#include <media/dvb_net.h>
#include "cxd2099.h"
#define DEVICE_NAME "ngene"
diff --git a/drivers/media/pci/pluto2/Makefile b/drivers/media/pci/pluto2/Makefile
index 524bf841f42b..3c2aea1ac752 100644
--- a/drivers/media/pci/pluto2/Makefile
+++ b/drivers/media/pci/pluto2/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_DVB_PLUTO2) += pluto2.o
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/dvb-frontends/
diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c
index 39dcba2b620c..5e6fe686f420 100644
--- a/drivers/media/pci/pluto2/pluto2.c
+++ b/drivers/media/pci/pluto2/pluto2.c
@@ -4,7 +4,7 @@
* Copyright (C) 2005 Andreas Oberritter <obi@linuxtv.org>
*
* based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/
- * by Dany Salman <salmandany@yahoo.fr>
+ * by Dany Salman <salmandany@yahoo.fr>
* Copyright (c) 2004 TDF
*
* This program is free software; you can redistribute it and/or modify
@@ -29,12 +29,12 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
#include "tda1004x.h"
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
diff --git a/drivers/media/pci/pt1/Makefile b/drivers/media/pci/pt1/Makefile
index 98e391295afe..ab873ae088a0 100644
--- a/drivers/media/pci/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-core -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c
index b6b1a8d20d86..4f6867af8311 100644
--- a/drivers/media/pci/pt1/pt1.c
+++ b/drivers/media/pci/pt1/pt1.c
@@ -4,7 +4,7 @@
* Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
*
* based on pt1dvr - http://pt1dvr.sourceforge.jp/
- * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -27,11 +27,11 @@
#include <linux/freezer.h>
#include <linux/ratelimit.h>
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dmxdev.h"
-#include "dvb_net.h"
-#include "dvb_frontend.h"
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_net.h>
+#include <media/dvb_frontend.h>
#include "va1j5jf8007t.h"
#include "va1j5jf8007s.h"
@@ -116,8 +116,8 @@ static u32 pt1_read_reg(struct pt1 *pt1, int reg)
return readl(pt1->regs + reg * 4);
}
-static int pt1_nr_tables = 8;
-module_param_named(nr_tables, pt1_nr_tables, int, 0);
+static unsigned int pt1_nr_tables = 8;
+module_param_named(nr_tables, pt1_nr_tables, uint, 0);
static void pt1_increment_table_count(struct pt1 *pt1)
{
@@ -443,6 +443,9 @@ static int pt1_init_tables(struct pt1 *pt1)
int i, ret;
u32 first_pfn, pfn;
+ if (!pt1_nr_tables)
+ return 0;
+
tables = vmalloc(sizeof(struct pt1_table) * pt1_nr_tables);
if (tables == NULL)
return -ENOMEM;
@@ -450,12 +453,10 @@ static int pt1_init_tables(struct pt1 *pt1)
pt1_init_table_count(pt1);
i = 0;
- if (pt1_nr_tables) {
- ret = pt1_init_table(pt1, &tables[0], &first_pfn);
- if (ret)
- goto err;
- i++;
- }
+ ret = pt1_init_table(pt1, &tables[0], &first_pfn);
+ if (ret)
+ goto err;
+ i++;
while (i < pt1_nr_tables) {
ret = pt1_init_table(pt1, &tables[i], &pfn);
diff --git a/drivers/media/pci/pt1/va1j5jf8007s.c b/drivers/media/pci/pt1/va1j5jf8007s.c
index f75f69556be7..f49867aef054 100644
--- a/drivers/media/pci/pt1/va1j5jf8007s.c
+++ b/drivers/media/pci/pt1/va1j5jf8007s.c
@@ -4,7 +4,7 @@
* Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
*
* based on pt1dvr - http://pt1dvr.sourceforge.jp/
- * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "va1j5jf8007s.h"
enum va1j5jf8007s_tune_state {
diff --git a/drivers/media/pci/pt1/va1j5jf8007s.h b/drivers/media/pci/pt1/va1j5jf8007s.h
index efbe6ccae8b4..f8ce5609095d 100644
--- a/drivers/media/pci/pt1/va1j5jf8007s.h
+++ b/drivers/media/pci/pt1/va1j5jf8007s.h
@@ -4,7 +4,7 @@
* Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
*
* based on pt1dvr - http://pt1dvr.sourceforge.jp/
- * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/pci/pt1/va1j5jf8007t.c b/drivers/media/pci/pt1/va1j5jf8007t.c
index 63fda79a75c0..a52984a6f9b3 100644
--- a/drivers/media/pci/pt1/va1j5jf8007t.c
+++ b/drivers/media/pci/pt1/va1j5jf8007t.c
@@ -4,7 +4,7 @@
* Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
*
* based on pt1dvr - http://pt1dvr.sourceforge.jp/
- * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,8 +21,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
-#include "dvb_frontend.h"
-#include "dvb_math.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_math.h>
#include "va1j5jf8007t.h"
enum va1j5jf8007t_tune_state {
diff --git a/drivers/media/pci/pt1/va1j5jf8007t.h b/drivers/media/pci/pt1/va1j5jf8007t.h
index 6fb119c6e73a..95eb7d294d20 100644
--- a/drivers/media/pci/pt1/va1j5jf8007t.h
+++ b/drivers/media/pci/pt1/va1j5jf8007t.h
@@ -4,7 +4,7 @@
* Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
*
* based on pt1dvr - http://pt1dvr.sourceforge.jp/
- * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
+ * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/media/pci/pt3/Makefile b/drivers/media/pci/pt3/Makefile
index aded8752ac2b..8698d5dfaf52 100644
--- a/drivers/media/pci/pt3/Makefile
+++ b/drivers/media/pci/pt3/Makefile
@@ -4,6 +4,5 @@ earth-pt3-objs += pt3.o pt3_i2c.o pt3_dma.o
obj-$(CONFIG_DVB_PT3) += earth-pt3.o
-ccflags-y += -Idrivers/media/dvb-core
ccflags-y += -Idrivers/media/dvb-frontends
ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/pt3/pt3.c b/drivers/media/pci/pt3/pt3.c
index 34044a45fecc..da74828805bc 100644
--- a/drivers/media/pci/pt3/pt3.c
+++ b/drivers/media/pci/pt3/pt3.c
@@ -23,10 +23,10 @@
#include <linux/string.h>
#include <linux/sched/signal.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
#include "pt3.h"
diff --git a/drivers/media/pci/pt3/pt3.h b/drivers/media/pci/pt3/pt3.h
index 1b3f2ad25db3..fbe8d9b847b0 100644
--- a/drivers/media/pci/pt3/pt3.h
+++ b/drivers/media/pci/pt3/pt3.h
@@ -20,9 +20,9 @@
#include <linux/atomic.h>
#include <linux/types.h>
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dmxdev.h"
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dmxdev.h>
#include "tc90522.h"
#include "mxl301rf.h"
diff --git a/drivers/media/pci/pt3/pt3_i2c.c b/drivers/media/pci/pt3/pt3_i2c.c
index ec6a8a2e4744..b66138c7b364 100644
--- a/drivers/media/pci/pt3/pt3_i2c.c
+++ b/drivers/media/pci/pt3/pt3_i2c.c
@@ -85,7 +85,6 @@ static void put_byte_write(struct pt3_i2cbuf *cbuf, u8 val)
{
u8 mask;
- mask = 0x80;
for (mask = 0x80; mask > 0; mask >>= 1)
cmdbuf_add(cbuf, (val & mask) ? I_DATA_H_NOP : I_DATA_L_NOP);
cmdbuf_add(cbuf, I_DATA_H_ACK0);
diff --git a/drivers/media/pci/saa7134/Makefile b/drivers/media/pci/saa7134/Makefile
index dbaadddf4320..82ac7f31221b 100644
--- a/drivers/media/pci/saa7134/Makefile
+++ b/drivers/media/pci/saa7134/Makefile
@@ -12,8 +12,6 @@ obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
-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 += -I$(srctree)/drivers/media/usb/go7007
diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c
index 9965d3531c80..9d6688a82b50 100644
--- a/drivers/media/pci/saa7134/saa7134-cards.c
+++ b/drivers/media/pci/saa7134/saa7134-cards.c
@@ -323,7 +323,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
+ .empress_addr = 0x20,
.inputs = {{
.type = SAA7134_INPUT_COMPOSITE1,
@@ -454,7 +454,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x820000,
.inputs = {{
@@ -849,7 +849,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
+ .empress_addr = 0x20,
.inputs = {{
.type = SAA7134_INPUT_COMPOSITE1,
.vmux = 4,
@@ -1006,7 +1006,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
+ .empress_addr = 0x20,
.inputs = {{
.type = SAA7134_INPUT_COMPOSITE1,
.vmux = 1,
@@ -1767,7 +1767,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.type = SAA7134_INPUT_TV,
@@ -2412,7 +2412,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .empress_addr = 0x21,
+ .empress_addr = 0x21,
.inputs = {{
.type = SAA7134_INPUT_COMPOSITE0,
.vmux = 0,
@@ -3978,13 +3978,13 @@ struct saa7134_board saa7134_boards[] = {
[SAA7134_BOARD_BEHOLD_407] = {
/* Beholder Intl. Ltd. 2008 */
/*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 407",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
+ .name = "Beholder BeholdTV 407",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x00008000,
.inputs = {{
.type = SAA7134_INPUT_SVIDEO,
@@ -4006,13 +4006,13 @@ struct saa7134_board saa7134_boards[] = {
[SAA7134_BOARD_BEHOLD_407FM] = {
/* Beholder Intl. Ltd. 2008 */
/*Dmitry Belimov <d.belimov@gmail.com> */
- .name = "Beholder BeholdTV 407 FM",
- .audio_clock = 0x00187de7,
- .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
- .radio_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .tda9887_conf = TDA9887_PRESENT,
+ .name = "Beholder BeholdTV 407 FM",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x00008000,
.inputs = {{
.type = SAA7134_INPUT_SVIDEO,
@@ -4103,7 +4103,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x00008000,
.inputs = {{
@@ -4166,7 +4166,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x00008000,
.inputs = {{
@@ -4196,7 +4196,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x00008000,
.inputs = {{
@@ -4366,7 +4366,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.type = SAA7134_INPUT_TV,
@@ -4394,7 +4394,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.type = SAA7134_INPUT_TV,
@@ -4422,7 +4422,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.type = SAA7134_INPUT_TV,
@@ -4450,7 +4450,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.type = SAA7134_INPUT_TV,
@@ -4481,7 +4481,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.type = SAA7134_INPUT_TV,
@@ -4517,7 +4517,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .empress_addr = 0x20,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.type = SAA7134_INPUT_TV,
@@ -4554,8 +4554,8 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
- .empress_addr = 0x20,
+ .rds_addr = 0x10,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.type = SAA7134_INPUT_TV,
@@ -5297,7 +5297,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .rds_addr = 0x10,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x00008000,
.inputs = {{
diff --git a/drivers/media/pci/saa7134/saa7134-dvb.c b/drivers/media/pci/saa7134/saa7134-dvb.c
index 731dee0a66e7..a7a63d608dde 100644
--- a/drivers/media/pci/saa7134/saa7134-dvb.c
+++ b/drivers/media/pci/saa7134/saa7134-dvb.c
@@ -29,7 +29,7 @@
#include <media/v4l2-common.h>
#include "dvb-pll.h"
-#include <dvb_frontend.h>
+#include <media/dvb_frontend.h>
#include "mt352.h"
#include "mt352_priv.h" /* FIXME */
@@ -1389,7 +1389,7 @@ static int dvb_init(struct saa7134_dev *dev)
if (configure_tda827x_fe(dev, &lifeview_trio_config,
&tda827x_cfg_0) < 0)
goto detach_frontend;
- } else { /* satellite */
+ } else { /* satellite */
fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
if (fe0->dvb.frontend) {
if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63,
@@ -1659,7 +1659,7 @@ static int dvb_init(struct saa7134_dev *dev)
if (configure_tda827x_fe(dev, &asus_tiger_3in1_config,
&tda827x_cfg_2) < 0)
goto detach_frontend;
- } else { /* satellite */
+ } else { /* satellite */
fe0->dvb.frontend = dvb_attach(tda10086_attach,
&flydvbs, &dev->i2c_adap);
if (fe0->dvb.frontend) {
diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c
index 2d5abeddc079..33ee8322895e 100644
--- a/drivers/media/pci/saa7134/saa7134-input.c
+++ b/drivers/media/pci/saa7134/saa7134-input.c
@@ -43,7 +43,8 @@ MODULE_PARM_DESC(pinnacle_remote, "Specify Pinnacle PCTV remote: 0=coloured, 1=g
} while (0)
#define ir_dbg(ir, fmt, arg...) do { \
if (ir_debug) \
- printk(KERN_DEBUG pr_fmt("ir %s: " fmt), ir->name, ## arg); \
+ printk(KERN_DEBUG pr_fmt("ir %s: " fmt), ir->rc->device_name, \
+ ## arg); \
} while (0)
/* Helper function for raw decoding at GPIO16 or GPIO18 */
diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c
index 0ceaa3473cf2..1ca6a32ad10e 100644
--- a/drivers/media/pci/saa7134/saa7134-video.c
+++ b/drivers/media/pci/saa7134/saa7134-video.c
@@ -1531,6 +1531,8 @@ int saa7134_querycap(struct file *file, void *priv,
case VFL_TYPE_VBI:
cap->device_caps |= vbi_caps;
break;
+ default:
+ return -EINVAL;
}
cap->capabilities = radio_caps | video_caps | vbi_caps |
cap->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -2041,14 +2043,14 @@ static const struct v4l2_ioctl_ops radio_ioctl_ops = {
struct video_device saa7134_video_template = {
.name = "saa7134-video",
.fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
+ .ioctl_ops = &video_ioctl_ops,
.tvnorms = SAA7134_NORMS,
};
struct video_device saa7134_radio_template = {
.name = "saa7134-radio",
.fops = &radio_fops,
- .ioctl_ops = &radio_ioctl_ops,
+ .ioctl_ops = &radio_ioctl_ops,
};
static const struct v4l2_ctrl_ops saa7134_ctrl_ops = {
diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h
index 39c36e6aefbe..d99e937a98c1 100644
--- a/drivers/media/pci/saa7134/saa7134.h
+++ b/drivers/media/pci/saa7134/saa7134.h
@@ -261,8 +261,8 @@ struct saa7134_card_ir {
#define SAA7134_BOARD_SABRENT_TV_PCB05 115
#define SAA7134_BOARD_10MOONSTVMASTER3 116
#define SAA7134_BOARD_AVERMEDIA_SUPER_007 117
-#define SAA7134_BOARD_BEHOLD_401 118
-#define SAA7134_BOARD_BEHOLD_403 119
+#define SAA7134_BOARD_BEHOLD_401 118
+#define SAA7134_BOARD_BEHOLD_403 119
#define SAA7134_BOARD_BEHOLD_403FM 120
#define SAA7134_BOARD_BEHOLD_405 121
#define SAA7134_BOARD_BEHOLD_405FM 122
@@ -581,7 +581,7 @@ struct saa7134_dev {
/* config info */
unsigned int board;
unsigned int tuner_type;
- unsigned int radio_type;
+ unsigned int radio_type;
unsigned char tuner_addr;
unsigned char radio_addr;
@@ -592,7 +592,7 @@ struct saa7134_dev {
struct i2c_adapter i2c_adap;
struct i2c_client i2c_client;
unsigned char eedata[256];
- int has_rds;
+ int has_rds;
/* video overlay */
struct v4l2_framebuffer ovbuf;
diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c
index d31a2d4494d1..5817d9cde4d0 100644
--- a/drivers/media/pci/saa7146/hexium_gemini.c
+++ b/drivers/media/pci/saa7146/hexium_gemini.c
@@ -27,6 +27,7 @@
#include <media/drv-intf/saa7146_vv.h>
#include <linux/module.h>
+#include <linux/kernel.h>
static int debug;
module_param(debug, int, 0);
@@ -69,8 +70,8 @@ struct hexium
struct video_device video_dev;
struct i2c_adapter i2c_adapter;
- int cur_input; /* current input */
- v4l2_std_id cur_std; /* current standard */
+ int cur_input; /* current input */
+ v4l2_std_id cur_std; /* current standard */
};
/* Samsung KS0127B decoder default registers */
@@ -137,19 +138,19 @@ static struct hexium_data hexium_input_select[] = {
are currently *not* supported*/
static struct saa7146_standard hexium_standards[] = {
{
- .name = "PAL", .id = V4L2_STD_PAL,
- .v_offset = 28, .v_field = 288,
- .h_offset = 1, .h_pixels = 680,
+ .name = "PAL", .id = V4L2_STD_PAL,
+ .v_offset = 28, .v_field = 288,
+ .h_offset = 1, .h_pixels = 680,
.v_max_out = 576, .h_max_out = 768,
}, {
- .name = "NTSC", .id = V4L2_STD_NTSC,
- .v_offset = 28, .v_field = 240,
- .h_offset = 1, .h_pixels = 640,
+ .name = "NTSC", .id = V4L2_STD_NTSC,
+ .v_offset = 28, .v_field = 240,
+ .h_offset = 1, .h_pixels = 640,
.v_max_out = 480, .h_max_out = 640,
}, {
- .name = "SECAM", .id = V4L2_STD_SECAM,
- .v_offset = 28, .v_field = 288,
- .h_offset = 1, .h_pixels = 720,
+ .name = "SECAM", .id = V4L2_STD_SECAM,
+ .v_offset = 28, .v_field = 288,
+ .h_offset = 1, .h_pixels = 720,
.v_max_out = 576, .h_max_out = 768,
}
};
@@ -388,7 +389,7 @@ static struct saa7146_ext_vv vv_data = {
.inputs = HEXIUM_INPUTS,
.capabilities = 0,
.stds = &hexium_standards[0],
- .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
+ .num_stds = ARRAY_SIZE(hexium_standards),
.std_callback = &std_callback,
};
diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c
index 043318aa19e2..0a05176c18ab 100644
--- a/drivers/media/pci/saa7146/hexium_orion.c
+++ b/drivers/media/pci/saa7146/hexium_orion.c
@@ -27,6 +27,7 @@
#include <media/drv-intf/saa7146_vv.h>
#include <linux/module.h>
+#include <linux/kernel.h>
static int debug;
module_param(debug, int, 0);
@@ -187,19 +188,19 @@ static struct {
static struct saa7146_standard hexium_standards[] = {
{
- .name = "PAL", .id = V4L2_STD_PAL,
- .v_offset = 16, .v_field = 288,
- .h_offset = 1, .h_pixels = 680,
+ .name = "PAL", .id = V4L2_STD_PAL,
+ .v_offset = 16, .v_field = 288,
+ .h_offset = 1, .h_pixels = 680,
.v_max_out = 576, .h_max_out = 768,
}, {
- .name = "NTSC", .id = V4L2_STD_NTSC,
- .v_offset = 16, .v_field = 240,
- .h_offset = 1, .h_pixels = 640,
+ .name = "NTSC", .id = V4L2_STD_NTSC,
+ .v_offset = 16, .v_field = 240,
+ .h_offset = 1, .h_pixels = 640,
.v_max_out = 480, .h_max_out = 640,
}, {
- .name = "SECAM", .id = V4L2_STD_SECAM,
- .v_offset = 16, .v_field = 288,
- .h_offset = 1, .h_pixels = 720,
+ .name = "SECAM", .id = V4L2_STD_SECAM,
+ .v_offset = 16, .v_field = 288,
+ .h_offset = 1, .h_pixels = 720,
.v_max_out = 576, .h_max_out = 768,
}
};
@@ -460,7 +461,7 @@ static struct saa7146_ext_vv vv_data = {
.inputs = HEXIUM_INPUTS,
.capabilities = 0,
.stds = &hexium_standards[0],
- .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
+ .num_stds = ARRAY_SIZE(hexium_standards),
.std_callback = &std_callback,
};
diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c
index 930218cc2de1..6b5582b7c595 100644
--- a/drivers/media/pci/saa7146/mxb.c
+++ b/drivers/media/pci/saa7146/mxb.c
@@ -3,7 +3,7 @@
Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
- Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html
+ Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html
for further details about this card.
This program is free software; you can redistribute it and/or modify
@@ -30,6 +30,7 @@
#include <media/v4l2-common.h>
#include <media/i2c/saa7115.h>
#include <linux/module.h>
+#include <linux/kernel.h>
#include "tea6415c.h"
#include "tea6420.h"
@@ -792,24 +793,24 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
static struct saa7146_standard standard[] = {
{
- .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
- .v_offset = 0x17, .v_field = 288,
- .h_offset = 0x14, .h_pixels = 680,
+ .name = "PAL-BG", .id = V4L2_STD_PAL_BG,
+ .v_offset = 0x17, .v_field = 288,
+ .h_offset = 0x14, .h_pixels = 680,
.v_max_out = 576, .h_max_out = 768,
}, {
- .name = "PAL-I", .id = V4L2_STD_PAL_I,
- .v_offset = 0x17, .v_field = 288,
- .h_offset = 0x14, .h_pixels = 680,
+ .name = "PAL-I", .id = V4L2_STD_PAL_I,
+ .v_offset = 0x17, .v_field = 288,
+ .h_offset = 0x14, .h_pixels = 680,
.v_max_out = 576, .h_max_out = 768,
}, {
- .name = "NTSC", .id = V4L2_STD_NTSC,
- .v_offset = 0x16, .v_field = 240,
- .h_offset = 0x06, .h_pixels = 708,
+ .name = "NTSC", .id = V4L2_STD_NTSC,
+ .v_offset = 0x16, .v_field = 240,
+ .h_offset = 0x06, .h_pixels = 708,
.v_max_out = 480, .h_max_out = 640,
}, {
- .name = "SECAM", .id = V4L2_STD_SECAM,
- .v_offset = 0x14, .v_field = 288,
- .h_offset = 0x14, .h_pixels = 720,
+ .name = "SECAM", .id = V4L2_STD_SECAM,
+ .v_offset = 0x14, .v_field = 288,
+ .h_offset = 0x14, .h_pixels = 720,
.v_max_out = 576, .h_max_out = 768,
}
};
@@ -837,7 +838,7 @@ static struct saa7146_ext_vv vv_data = {
.inputs = MXB_INPUTS,
.capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_AUDIO,
.stds = &standard[0],
- .num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
+ .num_stds = ARRAY_SIZE(standard),
.std_callback = &std_callback,
};
diff --git a/drivers/media/pci/saa7164/Makefile b/drivers/media/pci/saa7164/Makefile
index 3896bcdb99d2..dea076744ec9 100644
--- a/drivers/media/pci/saa7164/Makefile
+++ b/drivers/media/pci/saa7164/Makefile
@@ -5,9 +5,5 @@ 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/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/pci/saa7164/saa7164.h b/drivers/media/pci/saa7164/saa7164.h
index 81b3f0e19993..f3358f43195f 100644
--- a/drivers/media/pci/saa7164/saa7164.h
+++ b/drivers/media/pci/saa7164/saa7164.h
@@ -50,11 +50,11 @@
#include <media/tuner.h>
#include <media/tveeprom.h>
-#include <dvb_demux.h>
-#include <dvb_frontend.h>
-#include <dvb_net.h>
-#include <dvbdev.h>
-#include <dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
+#include <media/dmxdev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-device.h>
diff --git a/drivers/media/pci/smipcie/Makefile b/drivers/media/pci/smipcie/Makefile
index 6006aac3c41f..214ebfe12cf7 100644
--- a/drivers/media/pci/smipcie/Makefile
+++ b/drivers/media/pci/smipcie/Makefile
@@ -5,6 +5,5 @@ smipcie-objs := smipcie-main.o smipcie-ir.o
obj-$(CONFIG_DVB_SMIPCIE) += smipcie.o
ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/pci/smipcie/smipcie.h b/drivers/media/pci/smipcie/smipcie.h
index c8368c78ddd5..a6c5b1bd7edb 100644
--- a/drivers/media/pci/smipcie/smipcie.h
+++ b/drivers/media/pci/smipcie/smipcie.h
@@ -29,12 +29,12 @@
#include <linux/slab.h>
#include <media/rc-core.h>
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
/* -------- Register Base -------- */
#define MSI_CONTROL_REG_BASE 0x0800
diff --git a/drivers/media/pci/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c
index ca0873e47bea..19ffd2ed3cc7 100644
--- a/drivers/media/pci/solo6x10/solo6x10-core.c
+++ b/drivers/media/pci/solo6x10/solo6x10-core.c
@@ -47,18 +47,19 @@ MODULE_PARM_DESC(full_eeprom, "Allow access to full 128B EEPROM (dangerous)");
static void solo_set_time(struct solo_dev *solo_dev)
{
- struct timespec ts;
+ struct timespec64 ts;
- ktime_get_ts(&ts);
+ ktime_get_ts64(&ts);
- solo_reg_write(solo_dev, SOLO_TIMER_SEC, ts.tv_sec);
- solo_reg_write(solo_dev, SOLO_TIMER_USEC, ts.tv_nsec / NSEC_PER_USEC);
+ /* no overflow because we use monotonic timestamps */
+ solo_reg_write(solo_dev, SOLO_TIMER_SEC, (u32)ts.tv_sec);
+ solo_reg_write(solo_dev, SOLO_TIMER_USEC, (u32)ts.tv_nsec / NSEC_PER_USEC);
}
static void solo_timer_sync(struct solo_dev *solo_dev)
{
u32 sec, usec;
- struct timespec ts;
+ struct timespec64 ts;
long diff;
if (solo_dev->type != SOLO_DEV_6110)
@@ -72,11 +73,11 @@ static void solo_timer_sync(struct solo_dev *solo_dev)
sec = solo_reg_read(solo_dev, SOLO_TIMER_SEC);
usec = solo_reg_read(solo_dev, SOLO_TIMER_USEC);
- ktime_get_ts(&ts);
+ ktime_get_ts64(&ts);
- diff = (long)ts.tv_sec - (long)sec;
+ diff = (s32)ts.tv_sec - (s32)sec;
diff = (diff * 1000000)
- + ((long)(ts.tv_nsec / NSEC_PER_USEC) - (long)usec);
+ + ((s32)(ts.tv_nsec / NSEC_PER_USEC) - (s32)usec);
if (diff > 1000 || diff < -1000) {
solo_set_time(solo_dev);
diff --git a/drivers/media/pci/solo6x10/solo6x10-gpio.c b/drivers/media/pci/solo6x10/solo6x10-gpio.c
index 3d0d1aa2f6a8..7b4641a2cb84 100644
--- a/drivers/media/pci/solo6x10/solo6x10-gpio.c
+++ b/drivers/media/pci/solo6x10/solo6x10-gpio.c
@@ -162,7 +162,9 @@ static void solo_gpiochip_set(struct gpio_chip *chip,
int solo_gpio_init(struct solo_dev *solo_dev)
{
+#ifdef CONFIG_GPIOLIB
int ret;
+#endif
solo_gpio_config(solo_dev);
#ifdef CONFIG_GPIOLIB
diff --git a/drivers/media/pci/ttpci/Makefile b/drivers/media/pci/ttpci/Makefile
index 0b805339c123..58ca12732aad 100644
--- a/drivers/media/pci/ttpci/Makefile
+++ b/drivers/media/pci/ttpci/Makefile
@@ -18,5 +18,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-core/ -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/dvb-frontends/
ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c
index 6d415bdeef18..dc8e577b2f74 100644
--- a/drivers/media/pci/ttpci/av7110.c
+++ b/drivers/media/pci/ttpci/av7110.c
@@ -53,7 +53,7 @@
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "ttpci-eeprom.h"
#include "av7110.h"
diff --git a/drivers/media/pci/ttpci/av7110.h b/drivers/media/pci/ttpci/av7110.h
index cbb150d6cbb1..8606ef5ebbe2 100644
--- a/drivers/media/pci/ttpci/av7110.h
+++ b/drivers/media/pci/ttpci/av7110.h
@@ -17,14 +17,14 @@
#include <linux/dvb/net.h>
#include <linux/mutex.h>
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_demux.h"
-#include "dmxdev.h"
+#include <media/dvbdev.h>
+#include <media/demux.h>
+#include <media/dvb_demux.h>
+#include <media/dmxdev.h>
#include "dvb_filter.h"
-#include "dvb_net.h"
-#include "dvb_ringbuffer.h"
-#include "dvb_frontend.h"
+#include <media/dvb_net.h>
+#include <media/dvb_ringbuffer.h>
+#include <media/dvb_frontend.h>
#include "ves1820.h"
#include "ves1x93.h"
#include "stv0299.h"
@@ -52,7 +52,7 @@ extern int av7110_debug;
enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM};
enum av7110_video_mode {
- AV7110_VIDEO_MODE_PAL = 0,
+ AV7110_VIDEO_MODE_PAL = 0,
AV7110_VIDEO_MODE_NTSC = 1
};
diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c
index ac83fff9fe0b..abc98f1ad26c 100644
--- a/drivers/media/pci/ttpci/budget-av.c
+++ b/drivers/media/pci/ttpci/budget-av.c
@@ -51,7 +51,7 @@
#include <linux/input.h>
#include <linux/spinlock.h>
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
#define DEBICICAM 0x02420000
@@ -1181,14 +1181,14 @@ static u8 read_pwm(struct budget_av *budget_av)
#define SUBID_DVBS_KNC1_PLUS 0x0011
#define SUBID_DVBS_TYPHOON 0x4f56
#define SUBID_DVBS_CINERGY1200 0x1154
-#define SUBID_DVBS_CYNERGY1200N 0x1155
+#define SUBID_DVBS_CYNERGY1200N 0x1155
#define SUBID_DVBS_TV_STAR 0x0014
#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015
#define SUBID_DVBS_TV_STAR_CI 0x0016
#define SUBID_DVBS2_KNC1 0x0018
#define SUBID_DVBS2_KNC1_OEM 0x0019
-#define SUBID_DVBS_EASYWATCH_1 0x001a
-#define SUBID_DVBS_EASYWATCH_2 0x001b
+#define SUBID_DVBS_EASYWATCH_1 0x001a
+#define SUBID_DVBS_EASYWATCH_2 0x001b
#define SUBID_DVBS2_EASYWATCH 0x001d
#define SUBID_DVBS_EASYWATCH 0x001e
diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c
index 57af11804fd6..ec8f92540f7c 100644
--- a/drivers/media/pci/ttpci/budget-ci.c
+++ b/drivers/media/pci/ttpci/budget-ci.c
@@ -35,7 +35,7 @@
#include "budget.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
#include "stv0299.h"
#include "stv0297.h"
#include "tda1004x.h"
@@ -1050,70 +1050,70 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
{ STB0899_DEV_ID , 0x81 },
{ STB0899_DISCNTRL1 , 0x32 },
- { STB0899_DISCNTRL2 , 0x80 },
- { STB0899_DISRX_ST0 , 0x04 },
- { STB0899_DISRX_ST1 , 0x00 },
- { STB0899_DISPARITY , 0x00 },
+ { STB0899_DISCNTRL2 , 0x80 },
+ { STB0899_DISRX_ST0 , 0x04 },
+ { STB0899_DISRX_ST1 , 0x00 },
+ { STB0899_DISPARITY , 0x00 },
{ STB0899_DISSTATUS , 0x20 },
- { STB0899_DISF22 , 0x8c },
- { STB0899_DISF22RX , 0x9a },
+ { STB0899_DISF22 , 0x8c },
+ { STB0899_DISF22RX , 0x9a },
{ STB0899_SYSREG , 0x0b },
- { STB0899_ACRPRESC , 0x11 },
- { STB0899_ACRDIV1 , 0x0a },
- { STB0899_ACRDIV2 , 0x05 },
- { STB0899_DACR1 , 0x00 },
- { STB0899_DACR2 , 0x00 },
- { STB0899_OUTCFG , 0x00 },
- { STB0899_MODECFG , 0x00 },
+ { STB0899_ACRPRESC , 0x11 },
+ { STB0899_ACRDIV1 , 0x0a },
+ { STB0899_ACRDIV2 , 0x05 },
+ { STB0899_DACR1 , 0x00 },
+ { STB0899_DACR2 , 0x00 },
+ { STB0899_OUTCFG , 0x00 },
+ { STB0899_MODECFG , 0x00 },
{ STB0899_IRQSTATUS_3 , 0x30 },
{ STB0899_IRQSTATUS_2 , 0x00 },
{ STB0899_IRQSTATUS_1 , 0x00 },
{ STB0899_IRQSTATUS_0 , 0x00 },
- { STB0899_IRQMSK_3 , 0xf3 },
- { STB0899_IRQMSK_2 , 0xfc },
- { STB0899_IRQMSK_1 , 0xff },
+ { STB0899_IRQMSK_3 , 0xf3 },
+ { STB0899_IRQMSK_2 , 0xfc },
+ { STB0899_IRQMSK_1 , 0xff },
{ STB0899_IRQMSK_0 , 0xff },
{ STB0899_IRQCFG , 0x00 },
- { STB0899_I2CCFG , 0x88 },
- { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
+ { STB0899_I2CCFG , 0x88 },
+ { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */
{ STB0899_IOPVALUE5 , 0x00 },
{ STB0899_IOPVALUE4 , 0x20 },
{ STB0899_IOPVALUE3 , 0xc9 },
{ STB0899_IOPVALUE2 , 0x90 },
{ STB0899_IOPVALUE1 , 0x40 },
{ STB0899_IOPVALUE0 , 0x00 },
- { STB0899_GPIO00CFG , 0x82 },
- { STB0899_GPIO01CFG , 0x82 },
- { STB0899_GPIO02CFG , 0x82 },
- { STB0899_GPIO03CFG , 0x82 },
- { STB0899_GPIO04CFG , 0x82 },
- { STB0899_GPIO05CFG , 0x82 },
- { STB0899_GPIO06CFG , 0x82 },
- { STB0899_GPIO07CFG , 0x82 },
- { STB0899_GPIO08CFG , 0x82 },
- { STB0899_GPIO09CFG , 0x82 },
- { STB0899_GPIO10CFG , 0x82 },
- { STB0899_GPIO11CFG , 0x82 },
- { STB0899_GPIO12CFG , 0x82 },
- { STB0899_GPIO13CFG , 0x82 },
- { STB0899_GPIO14CFG , 0x82 },
- { STB0899_GPIO15CFG , 0x82 },
- { STB0899_GPIO16CFG , 0x82 },
- { STB0899_GPIO17CFG , 0x82 },
- { STB0899_GPIO18CFG , 0x82 },
- { STB0899_GPIO19CFG , 0x82 },
- { STB0899_GPIO20CFG , 0x82 },
- { STB0899_SDATCFG , 0xb8 },
- { STB0899_SCLTCFG , 0xba },
- { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
- { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
- { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
- { STB0899_DIRCLKCFG , 0x82 },
- { STB0899_CLKOUT27CFG , 0x7e },
- { STB0899_STDBYCFG , 0x82 },
- { STB0899_CS0CFG , 0x82 },
- { STB0899_CS1CFG , 0x82 },
- { STB0899_DISEQCOCFG , 0x20 },
+ { STB0899_GPIO00CFG , 0x82 },
+ { STB0899_GPIO01CFG , 0x82 },
+ { STB0899_GPIO02CFG , 0x82 },
+ { STB0899_GPIO03CFG , 0x82 },
+ { STB0899_GPIO04CFG , 0x82 },
+ { STB0899_GPIO05CFG , 0x82 },
+ { STB0899_GPIO06CFG , 0x82 },
+ { STB0899_GPIO07CFG , 0x82 },
+ { STB0899_GPIO08CFG , 0x82 },
+ { STB0899_GPIO09CFG , 0x82 },
+ { STB0899_GPIO10CFG , 0x82 },
+ { STB0899_GPIO11CFG , 0x82 },
+ { STB0899_GPIO12CFG , 0x82 },
+ { STB0899_GPIO13CFG , 0x82 },
+ { STB0899_GPIO14CFG , 0x82 },
+ { STB0899_GPIO15CFG , 0x82 },
+ { STB0899_GPIO16CFG , 0x82 },
+ { STB0899_GPIO17CFG , 0x82 },
+ { STB0899_GPIO18CFG , 0x82 },
+ { STB0899_GPIO19CFG , 0x82 },
+ { STB0899_GPIO20CFG , 0x82 },
+ { STB0899_SDATCFG , 0xb8 },
+ { STB0899_SCLTCFG , 0xba },
+ { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
+ { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
+ { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
+ { STB0899_DIRCLKCFG , 0x82 },
+ { STB0899_CLKOUT27CFG , 0x7e },
+ { STB0899_STDBYCFG , 0x82 },
+ { STB0899_CS0CFG , 0x82 },
+ { STB0899_CS1CFG , 0x82 },
+ { STB0899_DISEQCOCFG , 0x20 },
{ STB0899_GPIO32CFG , 0x82 },
{ STB0899_GPIO33CFG , 0x82 },
{ STB0899_GPIO34CFG , 0x82 },
@@ -1122,35 +1122,35 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
{ STB0899_GPIO37CFG , 0x82 },
{ STB0899_GPIO38CFG , 0x82 },
{ STB0899_GPIO39CFG , 0x82 },
- { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
- { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
- { STB0899_FILTCTRL , 0x00 },
- { STB0899_SYSCTRL , 0x00 },
- { STB0899_STOPCLK1 , 0x20 },
- { STB0899_STOPCLK2 , 0x00 },
+ { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+ { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+ { STB0899_FILTCTRL , 0x00 },
+ { STB0899_SYSCTRL , 0x00 },
+ { STB0899_STOPCLK1 , 0x20 },
+ { STB0899_STOPCLK2 , 0x00 },
{ STB0899_INTBUFSTATUS , 0x00 },
- { STB0899_INTBUFCTRL , 0x0a },
+ { STB0899_INTBUFCTRL , 0x0a },
{ 0xffff , 0xff },
};
static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
- { STB0899_DEMOD , 0x00 },
- { STB0899_RCOMPC , 0xc9 },
- { STB0899_AGC1CN , 0x41 },
- { STB0899_AGC1REF , 0x10 },
+ { STB0899_DEMOD , 0x00 },
+ { STB0899_RCOMPC , 0xc9 },
+ { STB0899_AGC1CN , 0x41 },
+ { STB0899_AGC1REF , 0x10 },
{ STB0899_RTC , 0x7a },
- { STB0899_TMGCFG , 0x4e },
- { STB0899_AGC2REF , 0x34 },
- { STB0899_TLSR , 0x84 },
- { STB0899_CFD , 0xc7 },
+ { STB0899_TMGCFG , 0x4e },
+ { STB0899_AGC2REF , 0x34 },
+ { STB0899_TLSR , 0x84 },
+ { STB0899_CFD , 0xc7 },
{ STB0899_ACLC , 0x87 },
- { STB0899_BCLC , 0x94 },
- { STB0899_EQON , 0x41 },
- { STB0899_LDT , 0xdd },
- { STB0899_LDT2 , 0xc9 },
- { STB0899_EQUALREF , 0xb4 },
- { STB0899_TMGRAMP , 0x10 },
- { STB0899_TMGTHD , 0x30 },
+ { STB0899_BCLC , 0x94 },
+ { STB0899_EQON , 0x41 },
+ { STB0899_LDT , 0xdd },
+ { STB0899_LDT2 , 0xc9 },
+ { STB0899_EQUALREF , 0xb4 },
+ { STB0899_TMGRAMP , 0x10 },
+ { STB0899_TMGTHD , 0x30 },
{ STB0899_IDCCOMP , 0xfb },
{ STB0899_QDCCOMP , 0x03 },
{ STB0899_POWERI , 0x3b },
@@ -1169,12 +1169,12 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
{ STB0899_NIRL , 0x05 },
{ STB0899_ISYMB , 0x17 },
{ STB0899_QSYMB , 0xfa },
- { STB0899_SFRH , 0x2f },
- { STB0899_SFRM , 0x68 },
- { STB0899_SFRL , 0x40 },
- { STB0899_SFRUPH , 0x2f },
- { STB0899_SFRUPM , 0x68 },
- { STB0899_SFRUPL , 0x40 },
+ { STB0899_SFRH , 0x2f },
+ { STB0899_SFRM , 0x68 },
+ { STB0899_SFRL , 0x40 },
+ { STB0899_SFRUPH , 0x2f },
+ { STB0899_SFRUPM , 0x68 },
+ { STB0899_SFRUPL , 0x40 },
{ STB0899_EQUAI1 , 0xfd },
{ STB0899_EQUAQ1 , 0x04 },
{ STB0899_EQUAI2 , 0x0f },
@@ -1186,7 +1186,7 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
{ STB0899_EQUAI5 , 0xbd },
{ STB0899_EQUAQ5 , 0xf7 },
{ STB0899_DSTATUS2 , 0x00 },
- { STB0899_VSTATUS , 0x00 },
+ { STB0899_VSTATUS , 0x00 },
{ STB0899_VERROR , 0xff },
{ STB0899_IQSWAP , 0x2a },
{ STB0899_ECNT1M , 0x00 },
@@ -1195,26 +1195,26 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
{ STB0899_ECNT2L , 0x00 },
{ STB0899_ECNT3M , 0x00 },
{ STB0899_ECNT3L , 0x00 },
- { STB0899_FECAUTO1 , 0x06 },
+ { STB0899_FECAUTO1 , 0x06 },
{ STB0899_FECM , 0x01 },
- { STB0899_VTH12 , 0xf0 },
- { STB0899_VTH23 , 0xa0 },
+ { STB0899_VTH12 , 0xf0 },
+ { STB0899_VTH23 , 0xa0 },
{ STB0899_VTH34 , 0x78 },
- { STB0899_VTH56 , 0x4e },
- { STB0899_VTH67 , 0x48 },
- { STB0899_VTH78 , 0x38 },
- { STB0899_PRVIT , 0xff },
- { STB0899_VITSYNC , 0x19 },
- { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
- { STB0899_TSULC , 0x42 },
- { STB0899_RSLLC , 0x40 },
+ { STB0899_VTH56 , 0x4e },
+ { STB0899_VTH67 , 0x48 },
+ { STB0899_VTH78 , 0x38 },
+ { STB0899_PRVIT , 0xff },
+ { STB0899_VITSYNC , 0x19 },
+ { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+ { STB0899_TSULC , 0x42 },
+ { STB0899_RSLLC , 0x40 },
{ STB0899_TSLPL , 0x12 },
- { STB0899_TSCFGH , 0x0c },
- { STB0899_TSCFGM , 0x00 },
- { STB0899_TSCFGL , 0x0c },
+ { STB0899_TSCFGH , 0x0c },
+ { STB0899_TSCFGM , 0x00 },
+ { STB0899_TSCFGL , 0x0c },
{ STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */
- { STB0899_RSSYNCDEL , 0x00 },
- { STB0899_TSINHDELH , 0x02 },
+ { STB0899_RSSYNCDEL , 0x00 },
+ { STB0899_TSINHDELH , 0x02 },
{ STB0899_TSINHDELM , 0x00 },
{ STB0899_TSINHDELL , 0x00 },
{ STB0899_TSLLSTKM , 0x00 },
@@ -1225,18 +1225,18 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = {
{ STB0899_PCKLENLL , 0xcc },
{ STB0899_RSPCKLEN , 0xcc },
{ STB0899_TSSTATUS , 0x80 },
- { STB0899_ERRCTRL1 , 0xb6 },
- { STB0899_ERRCTRL2 , 0x96 },
- { STB0899_ERRCTRL3 , 0x89 },
+ { STB0899_ERRCTRL1 , 0xb6 },
+ { STB0899_ERRCTRL2 , 0x96 },
+ { STB0899_ERRCTRL3 , 0x89 },
{ STB0899_DMONMSK1 , 0x27 },
{ STB0899_DMONMSK0 , 0x03 },
- { STB0899_DEMAPVIT , 0x5c },
+ { STB0899_DEMAPVIT , 0x5c },
{ STB0899_PLPARM , 0x1f },
- { STB0899_PDELCTRL , 0x48 },
- { STB0899_PDELCTRL2 , 0x00 },
- { STB0899_BBHCTRL1 , 0x00 },
- { STB0899_BBHCTRL2 , 0x00 },
- { STB0899_HYSTTHRESH , 0x77 },
+ { STB0899_PDELCTRL , 0x48 },
+ { STB0899_PDELCTRL2 , 0x00 },
+ { STB0899_BBHCTRL1 , 0x00 },
+ { STB0899_BBHCTRL2 , 0x00 },
+ { STB0899_HYSTTHRESH , 0x77 },
{ STB0899_MATCSTM , 0x00 },
{ STB0899_MATCSTL , 0x00 },
{ STB0899_UPLCSTM , 0x00 },
@@ -1275,7 +1275,7 @@ static struct stb0899_config tt3200_config = {
.postproc = NULL,
- .demod_address = 0x68,
+ .demod_address = 0x68,
.xtal_freq = 27000000,
.inversion = IQ_SWAP_ON,
diff --git a/drivers/media/pci/ttpci/budget.h b/drivers/media/pci/ttpci/budget.h
index fae83866b199..a7463daf39f1 100644
--- a/drivers/media/pci/ttpci/budget.h
+++ b/drivers/media/pci/ttpci/budget.h
@@ -3,13 +3,13 @@
#ifndef __BUDGET_DVB__
#define __BUDGET_DVB__
-#include "dvb_frontend.h"
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_demux.h"
-#include "dmxdev.h"
+#include <media/dvb_frontend.h>
+#include <media/dvbdev.h>
+#include <media/demux.h>
+#include <media/dvb_demux.h>
+#include <media/dmxdev.h>
#include "dvb_filter.h"
-#include "dvb_net.h"
+#include <media/dvb_net.h>
#include <linux/module.h>
#include <linux/mutex.h>
diff --git a/drivers/media/pci/ttpci/dvb_filter.h b/drivers/media/pci/ttpci/dvb_filter.h
index 3d410d02a987..67a3c6333bca 100644
--- a/drivers/media/pci/ttpci/dvb_filter.h
+++ b/drivers/media/pci/ttpci/dvb_filter.h
@@ -19,7 +19,7 @@
#include <linux/slab.h>
-#include "demux.h"
+#include <media/demux.h>
typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
diff --git a/drivers/media/pci/tw5864/tw5864-video.c b/drivers/media/pci/tw5864/tw5864-video.c
index e7bd2b8484e3..ff2b7da90c08 100644
--- a/drivers/media/pci/tw5864/tw5864-video.c
+++ b/drivers/media/pci/tw5864/tw5864-video.c
@@ -730,7 +730,7 @@ static int tw5864_frameinterval_get(struct tw5864_input *input,
frameinterval->denominator = 25;
break;
default:
- dev_warn(&dev->pci->dev, "tw5864_frameinterval_get requested for unknown std %d\n",
+ dev_warn(&dev->pci->dev, "tw5864_frameinterval_get requested for unknown std %d\n",
input->std);
return -EINVAL;
}
diff --git a/drivers/media/pci/zoran/videocodec.c b/drivers/media/pci/zoran/videocodec.c
index 303289a7fd3f..5ff23ef89215 100644
--- a/drivers/media/pci/zoran/videocodec.c
+++ b/drivers/media/pci/zoran/videocodec.c
@@ -325,7 +325,6 @@ static int proc_videocodecs_show(struct seq_file *m, void *v)
seq_printf(m, "<S>lave or attached <M>aster name type flags magic ");
seq_printf(m, "(connected as)\n");
- h = codeclist_top;
while (h) {
seq_printf(m, "S %32s %04x %08lx %08lx (TEMPLATE)\n",
h->codec->name, h->codec->type,
diff --git a/drivers/media/pci/zoran/zoran_driver.c b/drivers/media/pci/zoran/zoran_driver.c
index b6a6c4f171d0..c464dae0389c 100644
--- a/drivers/media/pci/zoran/zoran_driver.c
+++ b/drivers/media/pci/zoran/zoran_driver.c
@@ -2792,21 +2792,21 @@ zoran_mmap (struct file *file,
}
static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
- .vidioc_querycap = zoran_querycap,
+ .vidioc_querycap = zoran_querycap,
.vidioc_s_selection = zoran_s_selection,
.vidioc_g_selection = zoran_g_selection,
- .vidioc_enum_input = zoran_enum_input,
- .vidioc_g_input = zoran_g_input,
- .vidioc_s_input = zoran_s_input,
- .vidioc_enum_output = zoran_enum_output,
- .vidioc_g_output = zoran_g_output,
- .vidioc_s_output = zoran_s_output,
+ .vidioc_enum_input = zoran_enum_input,
+ .vidioc_g_input = zoran_g_input,
+ .vidioc_s_input = zoran_s_input,
+ .vidioc_enum_output = zoran_enum_output,
+ .vidioc_g_output = zoran_g_output,
+ .vidioc_s_output = zoran_s_output,
.vidioc_g_fbuf = zoran_g_fbuf,
.vidioc_s_fbuf = zoran_s_fbuf,
- .vidioc_g_std = zoran_g_std,
- .vidioc_s_std = zoran_s_std,
- .vidioc_g_jpegcomp = zoran_g_jpegcomp,
- .vidioc_s_jpegcomp = zoran_s_jpegcomp,
+ .vidioc_g_std = zoran_g_std,
+ .vidioc_s_std = zoran_s_std,
+ .vidioc_g_jpegcomp = zoran_g_jpegcomp,
+ .vidioc_s_jpegcomp = zoran_s_jpegcomp,
.vidioc_overlay = zoran_overlay,
.vidioc_reqbufs = zoran_reqbufs,
.vidioc_querybuf = zoran_querybuf,
@@ -2814,18 +2814,18 @@ static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
.vidioc_dqbuf = zoran_dqbuf,
.vidioc_streamon = zoran_streamon,
.vidioc_streamoff = zoran_streamoff,
- .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap,
- .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out,
- .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay,
- .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out,
+ .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay,
+ .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap,
.vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out,
.vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay,
- .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap,
.vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out,
.vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay,
- .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap,
- .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out,
- .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay,
+ .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap,
+ .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out,
+ .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay,
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
diff --git a/drivers/media/pci/zoran/zr36057.h b/drivers/media/pci/zoran/zr36057.h
index c9ffef15532d..c8acb21dcb5c 100644
--- a/drivers/media/pci/zoran/zr36057.h
+++ b/drivers/media/pci/zoran/zr36057.h
@@ -103,8 +103,8 @@
#define ZR36057_ICR_IntPinEn (1<<24)
#define ZR36057_I2CBR 0x044 /* I2C Bus Register */
-#define ZR36057_I2CBR_SDA (1<<1)
-#define ZR36057_I2CBR_SCL (1<<0)
+#define ZR36057_I2CBR_SDA (1<<1)
+#define ZR36057_I2CBR_SCL (1<<0)
#define ZR36057_JMC 0x100 /* JPEG Mode and Control */
#define ZR36057_JMC_JPG (1 << 31)
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index fd0c99859d6f..614fbef08ddc 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -353,10 +353,10 @@ config VIDEO_STI_HVA_DEBUGFS
depends on DEBUG_FS
help
Select this to see information about the internal state and the last
- operation of STMicroelectronics HVA multi-format video encoder in
- debugfs.
+ operation of STMicroelectronics HVA multi-format video encoder in
+ debugfs.
- Choose N unless you know you need this.
+ Choose N unless you know you need this.
config VIDEO_STI_DELTA
tristate "STMicroelectronics DELTA multi-format video decoder V4L2 driver"
@@ -586,10 +586,10 @@ config VIDEO_SAMSUNG_S5P_CEC
select CEC_CORE
select CEC_NOTIFIER
---help---
- This is a driver for Samsung S5P HDMI CEC interface. It uses the
- generic CEC framework interface.
- CEC bus is present in the HDMI connector and enables communication
- between compatible devices.
+ This is a driver for Samsung S5P HDMI CEC interface. It uses the
+ generic CEC framework interface.
+ CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
config VIDEO_STI_HDMI_CEC
tristate "STMicroelectronics STiH4xx HDMI CEC driver"
@@ -597,10 +597,10 @@ config VIDEO_STI_HDMI_CEC
select CEC_CORE
select CEC_NOTIFIER
---help---
- This is a driver for STIH4xx HDMI CEC interface. It uses the
- generic CEC framework interface.
- CEC bus is present in the HDMI connector and enables communication
- between compatible devices.
+ This is a driver for STIH4xx HDMI CEC interface. It uses the
+ generic CEC framework interface.
+ CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
config VIDEO_STM32_HDMI_CEC
tristate "STMicroelectronics STM32 HDMI CEC driver"
@@ -609,10 +609,10 @@ config VIDEO_STM32_HDMI_CEC
select REGMAP_MMIO
select CEC_CORE
---help---
- This is a driver for STM32 interface. It uses the
- generic CEC framework interface.
- CEC bus is present in the HDMI connector and enables communication
- between compatible devices.
+ This is a driver for STM32 interface. It uses the
+ generic CEC framework interface.
+ CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
config VIDEO_TEGRA_HDMI_CEC
tristate "Tegra HDMI CEC driver"
@@ -620,10 +620,10 @@ config VIDEO_TEGRA_HDMI_CEC
select CEC_CORE
select CEC_NOTIFIER
---help---
- This is a driver for the Tegra HDMI CEC interface. It uses the
- generic CEC framework interface.
- The CEC bus is present in the HDMI connector and enables communication
- between compatible devices.
+ This is a driver for the Tegra HDMI CEC interface. It uses the
+ generic CEC framework interface.
+ The CEC bus is present in the HDMI connector and enables communication
+ between compatible devices.
endif #CEC_PLATFORM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 003b0bb2cddf..7f3080437be6 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_VIDEO_TI_VPE) += ti-vpe/
obj-$(CONFIG_VIDEO_TI_CAL) += ti-vpe/
obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
-obj-$(CONFIG_VIDEO_CODA) += coda/
+obj-$(CONFIG_VIDEO_CODA) += coda/
obj-$(CONFIG_VIDEO_SH_VEU) += sh_veu.o
@@ -33,8 +33,8 @@ obj-$(CONFIG_VIDEO_MEM2MEM_DEINTERLACE) += m2m-deinterlace.o
obj-$(CONFIG_VIDEO_MUX) += video-mux.o
-obj-$(CONFIG_VIDEO_S3C_CAMIF) += s3c-camif/
-obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS) += exynos4-is/
+obj-$(CONFIG_VIDEO_S3C_CAMIF) += s3c-camif/
+obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS) += exynos4-is/
obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg/
obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) += s5p-mfc/
@@ -45,13 +45,13 @@ obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC) += exynos-gsc/
obj-$(CONFIG_VIDEO_STI_BDISP) += sti/bdisp/
obj-$(CONFIG_VIDEO_STI_HVA) += sti/hva/
obj-$(CONFIG_DVB_C8SECTPFE) += sti/c8sectpfe/
-obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += sti/cec/
+obj-$(CONFIG_VIDEO_STI_HDMI_CEC) += sti/cec/
obj-$(CONFIG_VIDEO_STI_DELTA) += sti/delta/
obj-$(CONFIG_VIDEO_TEGRA_HDMI_CEC) += tegra-cec/
-obj-y += stm32/
+obj-y += stm32/
obj-y += blackfin/
@@ -62,9 +62,9 @@ obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o
obj-$(CONFIG_SOC_CAMERA) += soc_camera/
obj-$(CONFIG_VIDEO_RCAR_DRIF) += rcar_drif.o
-obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o
+obj-$(CONFIG_VIDEO_RENESAS_FCP) += rcar-fcp.o
obj-$(CONFIG_VIDEO_RENESAS_FDP1) += rcar_fdp1.o
-obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
+obj-$(CONFIG_VIDEO_RENESAS_JPU) += rcar_jpu.o
obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/
obj-$(CONFIG_VIDEO_ROCKCHIP_RGA) += rockchip/rga/
@@ -82,8 +82,6 @@ obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel/
obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32/
-ccflags-y += -I$(srctree)/drivers/media/i2c
-
obj-$(CONFIG_VIDEO_MEDIATEK_VPU) += mtk-vpu/
obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec/
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
index 0997c640191d..601ae6487617 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -2304,8 +2304,8 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
vpfe_dbg(1, vpfe, "vpfe_async_bound\n");
for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) {
- if (vpfe->cfg->asd[i]->match.fwnode.fwnode ==
- asd[i].match.fwnode.fwnode) {
+ if (vpfe->cfg->asd[i]->match.fwnode ==
+ asd[i].match.fwnode) {
sdinfo = &vpfe->cfg->sub_devs[i];
vpfe->sd[i] = subdev;
vpfe->sd[i]->grp_id = sdinfo->grp_id;
@@ -2510,7 +2510,7 @@ vpfe_get_pdata(struct platform_device *pdev)
}
pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
- pdata->asd[i]->match.fwnode.fwnode = of_fwnode_handle(rem);
+ pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);
of_node_put(rem);
}
diff --git a/drivers/media/platform/arv.c b/drivers/media/platform/arv.c
index 8fe59bf6cd3f..1e865fea803c 100644
--- a/drivers/media/platform/arv.c
+++ b/drivers/media/platform/arv.c
@@ -56,7 +56,7 @@
#define VERSION "0.0.5"
-#define ar_inl(addr) inl((unsigned long)(addr))
+#define ar_inl(addr) inl((unsigned long)(addr))
#define ar_outl(val, addr) outl((unsigned long)(val), (unsigned long)(addr))
extern struct cpuinfo_m32r boot_cpu_data;
@@ -66,7 +66,7 @@ extern struct cpuinfo_m32r boot_cpu_data;
* Note that M32700UT does not support CIF mode, but QVGA is
* supported by M32700UT hardware using VGA mode of AR LSI.
*
- * Supported: VGA (Normal mode, Interlace mode)
+ * Supported: VGA (Normal mode, Interlace mode)
* QVGA (Always Interlace mode of VGA)
*
*/
@@ -210,8 +210,8 @@ static void init_iic(void)
* ICU Setting (iic)
*/
/* I2C Setting */
- ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */
- ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
+ ar_outl(0x0, PLDI2CCR); /* I2CCR Disable */
+ ar_outl(0x0300, PLDI2CMOD); /* I2CMOD ACK/8b-data/7b-addr/auto */
ar_outl(0x1, PLDI2CACK); /* I2CACK ACK */
/* I2C CLK */
@@ -222,7 +222,7 @@ static void init_iic(void)
ar_outl(244, PLDI2CFREQ); /* BCLK = 50MHz */
else
ar_outl(244, PLDI2CFREQ); /* default: BCLK = 50MHz */
- ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */
+ ar_outl(0x1, PLDI2CCR); /* I2CCR Enable */
}
/**************************************************************************
@@ -300,9 +300,9 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL); /* destination addr. */
- ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); /* reload address */
- ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); /* byte count (bytes) */
- ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */
+ ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); /* reload address */
+ ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); /* byte count (bytes) */
+ ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); /* reload count (bytes) */
/*
* Okay, kick AR LSI to invoke an interrupt
@@ -364,7 +364,7 @@ static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
/*
* convert YUV422 to YUV422P
- * +--------------------+
+ * +--------------------+
* | Y0,Y1,... |
* | ..............Yn |
* +--------------------+
@@ -533,9 +533,9 @@ static void ar_interrupt(int irq, void *dev)
line_count = ar_inl(ARVHCOUNT); /* line number */
if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
/* operations for interlace mode */
- if (line_count < (AR_HEIGHT_VGA / 2)) /* even line */
+ if (line_count < (AR_HEIGHT_VGA / 2)) /* even line */
line_number = (line_count << 1);
- else /* odd line */
+ else /* odd line */
line_number =
(((line_count - (AR_HEIGHT_VGA / 2)) << 1) + 1);
} else {
@@ -568,7 +568,7 @@ static void ar_interrupt(int irq, void *dev)
* if captured all line of a frame, disable AR interrupt
* and wake a process up.
*/
- if (line_number == (ar->height - 1)) { /* end of line */
+ if (line_number == (ar->height - 1)) { /* end of line */
ar->start_capture = 0;
@@ -590,7 +590,7 @@ static void ar_interrupt(int irq, void *dev)
/*
* ar_initialize()
- * ar_initialize() is called by video_register_device() and
+ * ar_initialize() is called by video_register_device() and
* initializes AR LSI and peripherals.
*
* -1 is returned in all failures.
@@ -718,14 +718,14 @@ static const struct v4l2_file_operations ar_fops = {
};
static const struct v4l2_ioctl_ops ar_ioctl_ops = {
- .vidioc_querycap = ar_querycap,
- .vidioc_g_input = ar_g_input,
- .vidioc_s_input = ar_s_input,
- .vidioc_enum_input = ar_enum_input,
- .vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap,
+ .vidioc_querycap = ar_querycap,
+ .vidioc_g_input = ar_g_input,
+ .vidioc_s_input = ar_s_input,
+ .vidioc_enum_input = ar_enum_input,
+ .vidioc_enum_fmt_vid_cap = ar_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = ar_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = ar_s_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = ar_try_fmt_vid_cap,
};
#define ALIGN4(x) ((((int)(x)) & 0x3) == 0)
@@ -776,9 +776,9 @@ static int __init ar_init(void)
video_set_drvdata(&ar->vdev, ar);
if (vga) {
- ar->width = AR_WIDTH_VGA;
- ar->height = AR_HEIGHT_VGA;
- ar->size = AR_SIZE_VGA;
+ ar->width = AR_WIDTH_VGA;
+ ar->height = AR_HEIGHT_VGA;
+ ar->size = AR_SIZE_VGA;
ar->frame_bytes = AR_FRAME_BYTES_VGA;
ar->line_bytes = AR_LINE_BYTES_VGA;
if (vga_interlace)
@@ -786,9 +786,9 @@ static int __init ar_init(void)
else
ar->mode = AR_MODE_NORMAL;
} else {
- ar->width = AR_WIDTH_QVGA;
- ar->height = AR_HEIGHT_QVGA;
- ar->size = AR_SIZE_QVGA;
+ ar->width = AR_WIDTH_QVGA;
+ ar->height = AR_HEIGHT_QVGA;
+ ar->size = AR_SIZE_QVGA;
ar->frame_bytes = AR_FRAME_BYTES_QVGA;
ar->line_bytes = AR_LINE_BYTES_QVGA;
ar->mode = AR_MODE_INTERLACE;
diff --git a/drivers/media/platform/atmel/atmel-isc.c b/drivers/media/platform/atmel/atmel-isc.c
index 13f1c1c797b0..34676409ca08 100644
--- a/drivers/media/platform/atmel/atmel-isc.c
+++ b/drivers/media/platform/atmel/atmel-isc.c
@@ -2039,10 +2039,10 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
INIT_LIST_HEAD(&isc->subdev_entities);
- for (; ;) {
+ while (1) {
epn = of_graph_get_next_endpoint(np, epn);
if (!epn)
- break;
+ return 0;
rem = of_graph_get_remote_port_parent(epn);
if (!rem) {
@@ -2088,7 +2088,7 @@ static int isc_parse_dt(struct device *dev, struct isc_device *isc)
subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW;
subdev_entity->asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
- subdev_entity->asd->match.fwnode.fwnode =
+ subdev_entity->asd->match.fwnode =
of_fwnode_handle(rem);
list_add_tail(&subdev_entity->list, &isc->subdev_entities);
}
diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c
index e900995143a3..9958918e2449 100644
--- a/drivers/media/platform/atmel/atmel-isi.c
+++ b/drivers/media/platform/atmel/atmel-isi.c
@@ -1128,7 +1128,7 @@ static int isi_graph_parse(struct atmel_isi *isi, struct device_node *node)
/* Remote node to connect */
isi->entity.node = remote;
isi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
- isi->entity.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+ isi->entity.asd.match.fwnode = of_fwnode_handle(remote);
return 0;
}
}
diff --git a/drivers/media/platform/blackfin/ppi.c b/drivers/media/platform/blackfin/ppi.c
index 478eb2f7d723..d3dc765c1609 100644
--- a/drivers/media/platform/blackfin/ppi.c
+++ b/drivers/media/platform/blackfin/ppi.c
@@ -52,7 +52,7 @@ static irqreturn_t ppi_irq_err(int irq, void *dev_id)
struct bfin_ppi_regs *reg = info->base;
unsigned short status;
- /* register on bf561 is cleared when read
+ /* register on bf561 is cleared when read
* others are W1C
*/
status = bfin_read16(&reg->status);
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index bfc4ecf6f068..9fe113cb901f 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -395,6 +395,7 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx,
if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 ||
ctx->codec->dst_fourcc == V4L2_PIX_FMT_H264 ||
+ ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4 ||
ctx->codec->dst_fourcc == V4L2_PIX_FMT_MPEG4) {
width = round_up(q_data->width, 16);
height = round_up(q_data->height, 16);
@@ -413,8 +414,10 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx,
size = round_up(ysize, 4096) + ysize / 2;
else
size = ysize + ysize / 2;
- if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 &&
- dev->devtype->product != CODA_DX6)
+ /* Add space for mvcol buffers */
+ if (dev->devtype->product != CODA_DX6 &&
+ (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 ||
+ (ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4 && i == 0)))
size += ysize / 4;
name = kasprintf(GFP_KERNEL, "fb%d", i);
if (!name) {
@@ -452,18 +455,16 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx,
coda_parabuf_write(ctx, i * 3 + 1, cb);
coda_parabuf_write(ctx, i * 3 + 2, cr);
- /* mvcol buffer for h.264 */
- if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264 &&
- dev->devtype->product != CODA_DX6)
+ if (dev->devtype->product == CODA_DX6)
+ continue;
+
+ /* mvcol buffer for h.264 and mpeg4 */
+ if (ctx->codec->src_fourcc == V4L2_PIX_FMT_H264)
coda_parabuf_write(ctx, 96 + i, mvcol);
+ if (ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4 && i == 0)
+ coda_parabuf_write(ctx, 97, mvcol);
}
- /* mvcol buffer for mpeg4 */
- if ((dev->devtype->product != CODA_DX6) &&
- (ctx->codec->src_fourcc == V4L2_PIX_FMT_MPEG4))
- coda_parabuf_write(ctx, 97, ctx->internal_frames[0].paddr +
- ysize + ysize/4 + ysize/4);
-
return 0;
}
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index 15eb5dc4dff9..e8a7554a61d2 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -486,8 +486,8 @@ static int coda_try_fmt_vdoa(struct coda_ctx *ctx, struct v4l2_format *f,
return 0;
}
- err = vdoa_context_configure(NULL, f->fmt.pix.width, f->fmt.pix.height,
- f->fmt.pix.pixelformat);
+ err = vdoa_context_configure(NULL, round_up(f->fmt.pix.width, 16),
+ f->fmt.pix.height, f->fmt.pix.pixelformat);
if (err) {
*use_vdoa = false;
return 0;
@@ -730,7 +730,8 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f,
if (ctx->tiled_map_type == GDI_TILED_FRAME_MB_RASTER_MAP &&
!coda_try_fmt_vdoa(ctx, f, &ctx->use_vdoa) &&
ctx->use_vdoa)
- vdoa_context_configure(ctx->vdoa, f->fmt.pix.width,
+ vdoa_context_configure(ctx->vdoa,
+ round_up(f->fmt.pix.width, 16),
f->fmt.pix.height,
f->fmt.pix.pixelformat);
else
@@ -1884,6 +1885,12 @@ static int coda_queue_init(struct coda_ctx *ctx, struct vb2_queue *vq)
* that videobuf2 will keep the value of bytesused intact.
*/
vq->allow_zero_bytesused = 1;
+ /*
+ * We might be fine with no buffers on some of the queues, but that
+ * would need to be reflected in job_ready(). Currently we expect all
+ * queues to have at least one buffer queued.
+ */
+ vq->min_buffers_needed = 1;
vq->dev = &ctx->dev->plat_dev->dev;
return vb2_queue_init(vq);
diff --git a/drivers/media/platform/coda/coda_regs.h b/drivers/media/platform/coda/coda_regs.h
index 38df5fd9a2fa..3b650b8aabe9 100644
--- a/drivers/media/platform/coda/coda_regs.h
+++ b/drivers/media/platform/coda/coda_regs.h
@@ -125,7 +125,7 @@
#define CODA9_MODE_ENCODE_H264 8
#define CODA9_MODE_ENCODE_MP4 11
#define CODA9_MODE_ENCODE_MJPG 13
-#define CODA_MODE_INVALID 0xffff
+#define CODA_MODE_INVALID 0xffff
#define CODA_REG_BIT_INT_ENABLE 0x170
#define CODA_INT_INTERRUPT_ENABLE (1 << 3)
#define CODA_REG_BIT_INT_REASON 0x174
@@ -254,7 +254,6 @@
#define CODA9_STD_H264 0
#define CODA_STD_H263 1
#define CODA_STD_H264 2
-#define CODA_STD_MJPG 3
#define CODA9_STD_MPEG4 3
#define CODA_CMD_ENC_SEQ_SRC_SIZE 0x190
diff --git a/drivers/media/platform/coda/imx-vdoa.c b/drivers/media/platform/coda/imx-vdoa.c
index 8eb3e0c05473..85a66e4e2f9a 100644
--- a/drivers/media/platform/coda/imx-vdoa.c
+++ b/drivers/media/platform/coda/imx-vdoa.c
@@ -86,7 +86,6 @@ struct vdoa_data {
struct device *dev;
struct clk *vdoa_clk;
void __iomem *regs;
- int irq;
};
struct vdoa_q_data {
@@ -293,6 +292,7 @@ static int vdoa_probe(struct platform_device *pdev)
{
struct vdoa_data *vdoa;
struct resource *res;
+ int ret;
dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
@@ -316,12 +316,12 @@ static int vdoa_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res)
return -EINVAL;
- vdoa->irq = devm_request_threaded_irq(&pdev->dev, res->start, NULL,
+ ret = devm_request_threaded_irq(&pdev->dev, res->start, NULL,
vdoa_irq_handler, IRQF_ONESHOT,
"vdoa", vdoa);
- if (vdoa->irq < 0) {
+ if (ret < 0) {
dev_err(vdoa->dev, "Failed to get irq\n");
- return vdoa->irq;
+ return ret;
}
platform_set_drvdata(pdev, vdoa);
diff --git a/drivers/media/platform/davinci/dm355_ccdc.c b/drivers/media/platform/davinci/dm355_ccdc.c
index 89cb3094d7e6..238d01b7f066 100644
--- a/drivers/media/platform/davinci/dm355_ccdc.c
+++ b/drivers/media/platform/davinci/dm355_ccdc.c
@@ -20,10 +20,10 @@
* pre-process the Bayer RGB data, before writing it to SDRAM.
*
* TODO: 1) Raw bayer parameter settings and bayer capture
- * 2) Split module parameter structure to module specific ioctl structs
+ * 2) Split module parameter structure to module specific ioctl structs
* 3) add support for lense shading correction
* 4) investigate if enum used for user space type definition
- * to be replaced by #defines or integer
+ * to be replaced by #defines or integer
*/
#include <linux/platform_device.h>
#include <linux/uaccess.h>
diff --git a/drivers/media/platform/davinci/dm355_ccdc_regs.h b/drivers/media/platform/davinci/dm355_ccdc_regs.h
index a753ce262583..20ba390763b5 100644
--- a/drivers/media/platform/davinci/dm355_ccdc_regs.h
+++ b/drivers/media/platform/davinci/dm355_ccdc_regs.h
@@ -107,7 +107,7 @@
#define CCDC_RAW_IP_MODE 0
#define CCDC_VDHDOUT_INPUT 0
#define CCDC_YCINSWP_RAW (0 << 4)
-#define CCDC_EXWEN_DISABLE 0
+#define CCDC_EXWEN_DISABLE 0
#define CCDC_DATAPOL_NORMAL 0
#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC 0
#define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC (1 << 6)
@@ -152,7 +152,7 @@
#define CCDC_ALAW_GAMMA_WD_MASK 7
#define CCDC_REC656IF_BT656_EN 3
-#define CCDC_FMTCFG_FMTMODE_MASK 3
+#define CCDC_FMTCFG_FMTMODE_MASK 3
#define CCDC_FMTCFG_FMTMODE_SHIFT 1
#define CCDC_FMTCFG_LNUM_MASK 3
#define CCDC_FMTCFG_LNUM_SHIFT 4
@@ -196,7 +196,7 @@
#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15)
#define CCDC_LATCH_ON_VSYNC_ENABLE (0 << 15)
#define CCDC_FPC_ENABLE (1 << 15)
-#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
+#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
#define CCDC_DATA_PACK_ENABLE (1 << 11)
#define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF
#define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF
diff --git a/drivers/media/platform/davinci/dm644x_ccdc.c b/drivers/media/platform/davinci/dm644x_ccdc.c
index 5fa0a1f32536..592d3fc91e26 100644
--- a/drivers/media/platform/davinci/dm644x_ccdc.c
+++ b/drivers/media/platform/davinci/dm644x_ccdc.c
@@ -22,9 +22,9 @@
* may be supported using the same module.
*
* TODO: Test Raw bayer parameter settings and bayer capture
- * Split module parameter structure to module specific ioctl structs
- * investigate if enum used for user space type definition
- * to be replaced by #defines or integer
+ * Split module parameter structure to module specific ioctl structs
+ * investigate if enum used for user space type definition
+ * to be replaced by #defines or integer
*/
#include <linux/platform_device.h>
#include <linux/uaccess.h>
diff --git a/drivers/media/platform/davinci/dm644x_ccdc_regs.h b/drivers/media/platform/davinci/dm644x_ccdc_regs.h
index bece0bd9c9de..ffd89c7ea2b6 100644
--- a/drivers/media/platform/davinci/dm644x_ccdc_regs.h
+++ b/drivers/media/platform/davinci/dm644x_ccdc_regs.h
@@ -97,7 +97,7 @@
#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15)
#define CCDC_FPC_ENABLE (1 << 15)
#define CCDC_FPC_DISABLE 0
-#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
+#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
#define CCDC_DATA_PACK_ENABLE (1 << 11)
#define CCDC_FMTCFG_VPIN_MASK 7
#define CCDC_FMTCFG_VPIN_SHIFT 12
@@ -143,7 +143,7 @@
#define CCDC_REC656IF_BT656_EN 3
#define CCDC_SYN_MODE_VD_POL_NEGATIVE (1 << 2)
#define CCDC_CCDCFG_Y8POS_SHIFT 11
-#define CCDC_CCDCFG_BW656_10BIT (1 << 5)
+#define CCDC_CCDCFG_BW656_10BIT (1 << 5)
#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249
#define CCDC_NO_CULLING 0xffff00ff
#endif
diff --git a/drivers/media/platform/davinci/isif_regs.h b/drivers/media/platform/davinci/isif_regs.h
index a3564abe08ae..97d3ba1614d6 100644
--- a/drivers/media/platform/davinci/isif_regs.h
+++ b/drivers/media/platform/davinci/isif_regs.h
@@ -35,7 +35,7 @@
#define LINCFG0 0x44
#define LINCFG1 0x48
#define CCOLP 0x4c
-#define CRGAIN 0x50
+#define CRGAIN 0x50
#define CGRGAIN 0x54
#define CGBGAIN 0x58
#define CBGAIN 0x5c
@@ -46,7 +46,7 @@
#define VDINT0 0x70
#define VDINT1 0x74
#define VDINT2 0x78
-#define MISC 0x7c
+#define MISC 0x7c
#define CGAMMAWD 0x80
#define REC656IF 0x84
#define CCDCFG 0x88
@@ -191,7 +191,7 @@
#define ISIF_VD_POL_SHIFT 2
#define ISIF_DATAPOL_NORMAL 0
#define ISIF_DATAPOL_SHIFT 6
-#define ISIF_EXWEN_DISABLE 0
+#define ISIF_EXWEN_DISABLE 0
#define ISIF_EXWEN_SHIFT 5
#define ISIF_FRM_FMT_SHIFT 7
#define ISIF_DATASFT_SHIFT 8
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index cf65b39807fe..6f44abf7fa31 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -26,8 +26,8 @@
*
*
* decoder(TVP5146/ YUV/
- * MT9T001) --> Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
- * data input | |
+ * MT9T001) --> Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
+ * data input | |
* V |
* SDRAM |
* V
@@ -47,7 +47,7 @@
* block such as IPIPE (on DM355 only).
*
* Features supported
- * - MMAP IO
+ * - MMAP IO
* - Capture using TVP5146 over BT.656
* - support for interfacing decoders using sub device model
* - Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV
@@ -1794,7 +1794,7 @@ static int vpfe_probe(struct platform_device *pdev)
vfd->fops = &vpfe_fops;
vfd->ioctl_ops = &vpfe_ioctl_ops;
vfd->tvnorms = 0;
- vfd->v4l2_dev = &vpfe_dev->v4l2_dev;
+ vfd->v4l2_dev = &vpfe_dev->v4l2_dev;
snprintf(vfd->name, sizeof(vfd->name),
"%s_V%d.%d.%d",
CAPTURE_DRV_NAME,
diff --git a/drivers/media/platform/davinci/vpif.h b/drivers/media/platform/davinci/vpif.h
index 9956e6788693..2466c7c77deb 100644
--- a/drivers/media/platform/davinci/vpif.h
+++ b/drivers/media/platform/davinci/vpif.h
@@ -226,11 +226,11 @@ static inline void vpif_clr_bit(u32 reg, u32 bit)
(VPIF_INT_BOTH << VPIF_CH1_INT_CTRL_SHIFT)), VPIF_CH1_CTRL))
/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
-#define channel2_intr_assert() (regw((regr(VPIF_CH2_CTRL)|\
+#define channel2_intr_assert() (regw((regr(VPIF_CH2_CTRL)|\
(VPIF_INT_BOTH << VPIF_CH2_INT_CTRL_SHIFT)), VPIF_CH2_CTRL))
/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
-#define channel3_intr_assert() (regw((regr(VPIF_CH3_CTRL)|\
+#define channel3_intr_assert() (regw((regr(VPIF_CH3_CTRL)|\
(VPIF_INT_BOTH << VPIF_CH3_INT_CTRL_SHIFT)), VPIF_CH3_CTRL))
#define VPIF_CH_FID_MASK (0x20)
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index fca4dc829f73..9364cdf62f54 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -1390,16 +1390,16 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
struct v4l2_async_subdev *_asd = vpif_obj.config->asd[i];
- const struct fwnode_handle *fwnode = _asd->match.fwnode.fwnode;
+ const struct fwnode_handle *fwnode = _asd->match.fwnode;
if (fwnode == subdev->fwnode) {
vpif_obj.sd[i] = subdev;
vpif_obj.config->chan_config->inputs[i].subdev_name =
(char *)to_of_node(subdev->fwnode)->full_name;
vpif_dbg(2, debug,
- "%s: setting input %d subdev_name = %pOF\n",
+ "%s: setting input %d subdev_name = %s\n",
__func__, i,
- to_of_node(subdev->fwnode));
+ vpif_obj.config->chan_config->inputs[i].subdev_name);
return 0;
}
}
@@ -1550,6 +1550,8 @@ vpif_capture_get_pdata(struct platform_device *pdev)
sizeof(*chan->inputs) *
VPIF_CAPTURE_NUM_CHANNELS,
GFP_KERNEL);
+ if (!chan->inputs)
+ return NULL;
chan->input_count++;
chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;
@@ -1593,7 +1595,7 @@ vpif_capture_get_pdata(struct platform_device *pdev)
}
pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_FWNODE;
- pdata->asd[i]->match.fwnode.fwnode = of_fwnode_handle(rem);
+ pdata->asd[i]->match.fwnode = of_fwnode_handle(rem);
of_node_put(rem);
}
diff --git a/drivers/media/platform/davinci/vpss.c b/drivers/media/platform/davinci/vpss.c
index f2d27b932999..b73886519f4f 100644
--- a/drivers/media/platform/davinci/vpss.c
+++ b/drivers/media/platform/davinci/vpss.c
@@ -59,9 +59,9 @@ MODULE_AUTHOR("Texas Instruments");
#define DM365_ISP5_INTSEL1 0x10
#define DM365_ISP5_INTSEL2 0x14
#define DM365_ISP5_INTSEL3 0x18
-#define DM365_ISP5_CCDCMUX 0x20
-#define DM365_ISP5_PG_FRAME_SIZE 0x28
-#define DM365_VPBE_CLK_CTRL 0x00
+#define DM365_ISP5_CCDCMUX 0x20
+#define DM365_ISP5_PG_FRAME_SIZE 0x28
+#define DM365_VPBE_CLK_CTRL 0x00
#define VPSS_CLK_CTRL 0x01c40044
#define VPSS_CLK_CTRL_VENCCLKEN BIT(3)
@@ -78,8 +78,8 @@ MODULE_AUTHOR("Texas Instruments");
#define DM365_ISP5_INTSEL3_DEFAULT 0x00000015
/* masks and shifts for DM365*/
-#define DM365_CCDC_PG_VD_POL_SHIFT 0
-#define DM365_CCDC_PG_HD_POL_SHIFT 1
+#define DM365_CCDC_PG_VD_POL_SHIFT 0
+#define DM365_CCDC_PG_HD_POL_SHIFT 1
#define CCD_SRC_SEL_MASK (BIT_MASK(5) | BIT_MASK(4))
#define CCD_SRC_SEL_SHIFT 4
diff --git a/drivers/media/platform/exynos-gsc/gsc-m2m.c b/drivers/media/platform/exynos-gsc/gsc-m2m.c
index b2dc524112f7..e9ff27949a91 100644
--- a/drivers/media/platform/exynos-gsc/gsc-m2m.c
+++ b/drivers/media/platform/exynos-gsc/gsc-m2m.c
@@ -298,9 +298,7 @@ static int gsc_m2m_querycap(struct file *file, void *fh,
strlcpy(cap->card, GSC_MODULE_NAME " gscaler", sizeof(cap->card));
snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
dev_name(&gsc->pdev->dev));
- cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE |
- V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
-
+ cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
diff --git a/drivers/media/platform/exynos4-is/Kconfig b/drivers/media/platform/exynos4-is/Kconfig
index 46a7d242a1a5..7b2c49e5a592 100644
--- a/drivers/media/platform/exynos4-is/Kconfig
+++ b/drivers/media/platform/exynos4-is/Kconfig
@@ -41,7 +41,7 @@ config VIDEO_S5P_MIPI_CSIS
To compile this driver as a module, choose M here: the
module will be called s5p-csis.
-if SOC_EXYNOS4212 || SOC_EXYNOS4412 || SOC_EXYNOS5250
+if SOC_EXYNOS4412 || SOC_EXYNOS5250
config VIDEO_EXYNOS_FIMC_LITE
tristate "EXYNOS FIMC-LITE camera interface driver"
diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index 099c735a39b7..d8d8c9902b19 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -1211,7 +1211,7 @@ static const struct fimc_drvdata fimc_drvdata_exynos4210 = {
.out_buf_count = 32,
};
-/* EXYNOS4212, EXYNOS4412 */
+/* EXYNOS4412 */
static const struct fimc_drvdata fimc_drvdata_exynos4x12 = {
.num_entities = 4,
.lclk_frequency = 166000000UL,
@@ -1246,7 +1246,7 @@ static struct platform_driver fimc_driver = {
.driver = {
.of_match_table = fimc_of_match,
.name = FIMC_DRIVER_NAME,
- .pm = &fimc_pm_ops,
+ .pm = &fimc_pm_ops,
}
};
diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h
index c0373aede81a..82d514df97f0 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.h
+++ b/drivers/media/platform/exynos4-is/fimc-core.h
@@ -303,7 +303,7 @@ struct fimc_m2m_device {
* @input: capture input type, grp_id of the attached subdev
* @user_subdev_api: true if subdevs are not configured by the host driver
* @inh_sensor_ctrls: a flag indicating v4l2 controls are inherited from
- * an image sensor subdev
+ * an image sensor subdev
*/
struct fimc_vid_cap {
struct fimc_ctx *ctx;
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index fd793d3ac072..9a48c0f69320 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -366,16 +366,16 @@ static int fimc_isp_subdev_s_power(struct v4l2_subdev *sd, int on)
static int fimc_isp_subdev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
- struct v4l2_mbus_framefmt fmt;
struct v4l2_mbus_framefmt *format;
+ struct v4l2_mbus_framefmt fmt = {
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .code = fimc_isp_formats[0].mbus_code,
+ .width = DEFAULT_PREVIEW_STILL_WIDTH + FIMC_ISP_CAC_MARGIN_WIDTH,
+ .height = DEFAULT_PREVIEW_STILL_HEIGHT + FIMC_ISP_CAC_MARGIN_HEIGHT,
+ .field = V4L2_FIELD_NONE,
+ };
format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SINK);
-
- fmt.colorspace = V4L2_COLORSPACE_SRGB;
- fmt.code = fimc_isp_formats[0].mbus_code;
- fmt.width = DEFAULT_PREVIEW_STILL_WIDTH + FIMC_ISP_CAC_MARGIN_WIDTH;
- fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT + FIMC_ISP_CAC_MARGIN_HEIGHT;
- fmt.field = V4L2_FIELD_NONE;
*format = fmt;
format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SRC_FIFO);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 4a3c9948ca54..70d5f5586a5d 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1462,10 +1462,7 @@ static void fimc_lite_clk_put(struct fimc_lite *fimc)
static int fimc_lite_clk_get(struct fimc_lite *fimc)
{
fimc->clock = clk_get(&fimc->pdev->dev, FLITE_CLK_NAME);
- if (IS_ERR(fimc->clock))
- return PTR_ERR(fimc->clock);
-
- return 0;
+ return PTR_ERR_OR_ZERO(fimc->clock);
}
static const struct of_device_id flite_of_match[];
@@ -1646,7 +1643,7 @@ static const struct dev_pm_ops fimc_lite_pm_ops = {
NULL)
};
-/* EXYNOS4212, EXYNOS4412 */
+/* EXYNOS4412 */
static struct flite_drvdata fimc_lite_drvdata_exynos4 = {
.max_width = 8192,
.max_height = 8192,
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.h b/drivers/media/platform/exynos4-is/fimc-lite.h
index 9ae1e96a1bc7..3e238b8c834a 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.h
+++ b/drivers/media/platform/exynos4-is/fimc-lite.h
@@ -56,9 +56,9 @@ enum {
* @max_height: maximum camera interface input height in pixels
* @out_width_align: minimum output width alignment in pixels
* @win_hor_offs_align: minimum camera interface crop window horizontal
- * offset alignment in pixels
+ * offset alignment in pixels
* @out_hor_offs_align: minimum output DMA compose rectangle horizontal
- * offset alignment in pixels
+ * offset alignment in pixels
* @max_dma_bufs: number of output DMA buffer start address registers
* @num_instances: total number of FIMC-LITE IP instances available
*/
diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c
index 9027d0b0d2bd..a19f8b164a47 100644
--- a/drivers/media/platform/exynos4-is/fimc-m2m.c
+++ b/drivers/media/platform/exynos4-is/fimc-m2m.c
@@ -236,15 +236,7 @@ static int fimc_m2m_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
struct fimc_dev *fimc = video_drvdata(file);
- unsigned int caps;
-
- /*
- * 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.
- */
- caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE |
- V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
+ unsigned int caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
__fimc_vidioc_querycap(&fimc->pdev->dev, cap, caps);
return 0;
diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c
index 0ef583cfc424..78b48a1fa26c 100644
--- a/drivers/media/platform/exynos4-is/media-dev.c
+++ b/drivers/media/platform/exynos4-is/media-dev.c
@@ -456,7 +456,7 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
}
fmd->sensor[index].asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
- fmd->sensor[index].asd.match.fwnode.fwnode = of_fwnode_handle(rem);
+ fmd->sensor[index].asd.match.fwnode = of_fwnode_handle(rem);
fmd->async_subdevs[index] = &fmd->sensor[index].asd;
fmd->num_sensors++;
@@ -1364,7 +1364,7 @@ static int subdev_notifier_bound(struct v4l2_async_notifier *notifier,
/* Find platform data for this sensor subdev */
for (i = 0; i < ARRAY_SIZE(fmd->sensor); i++)
- if (fmd->sensor[i].asd.match.fwnode.fwnode ==
+ if (fmd->sensor[i].asd.match.fwnode ==
of_fwnode_handle(subdev->dev->of_node))
si = &fmd->sensor[i];
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index 945ef1e2ccc7..1e4195144f39 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -384,16 +384,16 @@ static void deinterlace_device_run(void *priv)
* 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.
+ * 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.
+ * 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.
+ * 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.
+ * 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:
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index 46768c056193..0c28d0b995cc 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -115,3 +115,6 @@ struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev)
return ctx;
}
EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Mediatek video codec driver");
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index 0dc9ed01fffe..cd37bb2a610f 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -26,7 +26,7 @@
* @inst_addr : VPU decoder instance address
* @signaled : 1 - Host has received ack message from VPU, 0 - not received
* @ctx : context for v4l2 layer integration
- * @dev : platform device of VPU
+ * @dev : platform device of VPU
* @wq : wait queue to wait VPU message ack
* @handler : ipi handler for each decoder
*/
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index abb14ee20538..a795a9fae899 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -1774,8 +1774,8 @@ static int vidioc_g_fbuf(struct file *file, void *fh,
}
static const struct v4l2_ioctl_ops vout_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
+ .vidioc_querycap = vidioc_querycap,
+ .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,
@@ -1795,12 +1795,12 @@ static const struct v4l2_ioctl_ops vout_ioctl_ops = {
};
static const struct v4l2_file_operations omap_vout_fops = {
- .owner = THIS_MODULE,
+ .owner = THIS_MODULE,
.poll = omap_vout_poll,
.unlocked_ioctl = video_ioctl2,
- .mmap = omap_vout_mmap,
- .open = omap_vout_open,
- .release = omap_vout_release,
+ .mmap = omap_vout_mmap,
+ .open = omap_vout_open,
+ .release = omap_vout_release,
};
/* Init functions used during driver initialization */
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index b7ff3842afc0..8eb000e3d8fd 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -920,7 +920,7 @@ static void isp_pipeline_suspend(struct isp_pipeline *pipe)
/*
* isp_pipeline_is_last - Verify if entity has an enabled link to the output
- * video node
+ * video node
* @me: ISP module's media entity
*
* Returns 1 if the entity has an enabled link to the output video node or 0
diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c
index 295f34ad1080..c71a00736541 100644
--- a/drivers/media/platform/pxa_camera.c
+++ b/drivers/media/platform/pxa_camera.c
@@ -32,7 +32,6 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/dmaengine.h>
-#include <linux/dma-mapping.h>
#include <linux/dma/pxa-dma.h>
#include <media/v4l2-async.h>
@@ -647,16 +646,16 @@ static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cf
}
/**
- * struct soc_camera_format_xlate - match between host and sensor formats
+ * struct pxa_camera_format_xlate - match between host and sensor formats
* @code: code of a sensor provided format
* @host_fmt: host format after host translation from code
*
* Host and sensor translation structure. Used in table of host and sensor
- * formats matchings in soc_camera_device. A host can override the generic list
+ * formats matchings in pxa_camera_device. A host can override the generic list
* generation by implementing get_formats(), and use it for format checks and
* format setup.
*/
-struct soc_camera_format_xlate {
+struct pxa_camera_format_xlate {
u32 code;
const struct pxa_mbus_pixelfmt *host_fmt;
};
@@ -693,8 +692,8 @@ struct pxa_camera_dev {
struct v4l2_async_notifier notifier;
struct vb2_queue vb2_vq;
struct v4l2_subdev *sensor;
- struct soc_camera_format_xlate *user_formats;
- const struct soc_camera_format_xlate *current_fmt;
+ struct pxa_camera_format_xlate *user_formats;
+ const struct pxa_camera_format_xlate *current_fmt;
struct v4l2_pix_format current_pix;
struct v4l2_async_subdev asd;
@@ -743,8 +742,8 @@ static const char *pxa_cam_driver_description = "PXA_Camera";
/*
* Format translation functions
*/
-static const struct soc_camera_format_xlate
-*pxa_mbus_xlate_by_fourcc(struct soc_camera_format_xlate *user_formats,
+static const struct pxa_camera_format_xlate
+*pxa_mbus_xlate_by_fourcc(struct pxa_camera_format_xlate *user_formats,
unsigned int fourcc)
{
unsigned int i;
@@ -755,17 +754,17 @@ static const struct soc_camera_format_xlate
return NULL;
}
-static struct soc_camera_format_xlate *pxa_mbus_build_fmts_xlate(
+static struct pxa_camera_format_xlate *pxa_mbus_build_fmts_xlate(
struct v4l2_device *v4l2_dev, struct v4l2_subdev *subdev,
int (*get_formats)(struct v4l2_device *, unsigned int,
- struct soc_camera_format_xlate *xlate))
+ struct pxa_camera_format_xlate *xlate))
{
unsigned int i, fmts = 0, raw_fmts = 0;
int ret;
struct v4l2_subdev_mbus_code_enum code = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
};
- struct soc_camera_format_xlate *user_formats;
+ struct pxa_camera_format_xlate *user_formats;
while (!v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) {
raw_fmts++;
@@ -1722,7 +1721,7 @@ static bool pxa_camera_packing_supported(const struct pxa_mbus_pixelfmt *fmt)
static int pxa_camera_get_formats(struct v4l2_device *v4l2_dev,
unsigned int idx,
- struct soc_camera_format_xlate *xlate)
+ struct pxa_camera_format_xlate *xlate)
{
struct pxa_camera_dev *pcdev = v4l2_dev_to_pcdev(v4l2_dev);
int formats = 0, ret;
@@ -1794,7 +1793,7 @@ static int pxa_camera_get_formats(struct v4l2_device *v4l2_dev,
static int pxa_camera_build_formats(struct pxa_camera_dev *pcdev)
{
- struct soc_camera_format_xlate *xlate;
+ struct pxa_camera_format_xlate *xlate;
xlate = pxa_mbus_build_fmts_xlate(&pcdev->v4l2_dev, pcdev->sensor,
pxa_camera_get_formats);
@@ -1883,7 +1882,7 @@ static int pxac_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
struct v4l2_format *f)
{
struct pxa_camera_dev *pcdev = video_drvdata(filp);
- const struct soc_camera_format_xlate *xlate;
+ const struct pxa_camera_format_xlate *xlate;
struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_subdev_pad_config pad_cfg;
struct v4l2_subdev_format format = {
@@ -1947,7 +1946,7 @@ static int pxac_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
struct v4l2_format *f)
{
struct pxa_camera_dev *pcdev = video_drvdata(filp);
- const struct soc_camera_format_xlate *xlate;
+ const struct pxa_camera_format_xlate *xlate;
struct v4l2_pix_format *pix = &f->fmt.pix;
struct v4l2_subdev_format format = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
@@ -2336,7 +2335,7 @@ static int pxa_camera_pdata_from_dt(struct device *dev,
asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
remote = of_graph_get_remote_port(np);
if (remote) {
- asd->match.fwnode.fwnode = of_fwnode_handle(remote);
+ asd->match.fwnode = of_fwnode_handle(remote);
of_node_put(remote);
} else {
dev_notice(dev, "no remote for %pOF\n", np);
@@ -2492,7 +2491,7 @@ static int pxa_camera_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, pcdev);
err = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev);
if (err)
- goto exit_free_dma;
+ goto exit_deactivate;
pcdev->asds[0] = &pcdev->asd;
pcdev->notifier.subdevs = pcdev->asds;
@@ -2528,6 +2527,8 @@ exit_free_clk:
v4l2_clk_unregister(pcdev->mclk_clk);
exit_free_v4l2dev:
v4l2_device_unregister(&pcdev->v4l2_dev);
+exit_deactivate:
+ pxa_camera_deactivate(pcdev);
exit_free_dma:
dma_release_channel(pcdev->dma_chans[2]);
exit_free_dma_u:
diff --git a/drivers/media/platform/qcom/camss-8x16/camss.c b/drivers/media/platform/qcom/camss-8x16/camss.c
index 390a42c17b66..05f06c98aa64 100644
--- a/drivers/media/platform/qcom/camss-8x16/camss.c
+++ b/drivers/media/platform/qcom/camss-8x16/camss.c
@@ -341,7 +341,7 @@ static int camss_of_parse_ports(struct device *dev,
}
csd->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
- csd->asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+ csd->asd.match.fwnode = of_fwnode_handle(remote);
}
return notifier->num_subdevs;
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index a0fe80df0cbd..0360d295f4c8 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -144,8 +144,8 @@ struct venc_controls {
u32 h264_min_qp;
u32 h264_max_qp;
u32 h264_loop_filter_mode;
- u32 h264_loop_filter_alpha;
- u32 h264_loop_filter_beta;
+ s32 h264_loop_filter_alpha;
+ s32 h264_loop_filter_beta;
u32 vp8_min_qp;
u32 vp8_max_qp;
diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c
index b83c5b8ddccb..1cfeb7743041 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.c
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
@@ -421,12 +421,12 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
pkt->shdr.session_id = hash32_ptr(cookie);
pkt->num_properties = 1;
+ pkt->data[0] = ptype;
switch (ptype) {
case HFI_PROPERTY_CONFIG_FRAME_RATE: {
struct hfi_framerate *in = pdata, *frate = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_FRAME_RATE;
frate->buffer_type = in->buffer_type;
frate->framerate = in->framerate;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*frate);
@@ -436,7 +436,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
struct hfi_uncompressed_format_select *in = pdata;
struct hfi_uncompressed_format_select *hfi = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
hfi->buffer_type = in->buffer_type;
hfi->format = in->format;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hfi);
@@ -445,7 +444,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_FRAME_SIZE: {
struct hfi_framesize *in = pdata, *fsize = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_FRAME_SIZE;
fsize->buffer_type = in->buffer_type;
fsize->height = in->height;
fsize->width = in->width;
@@ -455,7 +453,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_REALTIME: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_REALTIME;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) * 2;
break;
@@ -463,7 +460,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: {
struct hfi_buffer_count_actual *in = pdata, *count = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
count->count_actual = in->count_actual;
count->type = in->type;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
@@ -472,7 +468,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL: {
struct hfi_buffer_size_actual *in = pdata, *sz = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
sz->size = in->size;
sz->type = in->type;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*sz);
@@ -482,8 +477,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
struct hfi_buffer_display_hold_count_actual *in = pdata;
struct hfi_buffer_display_hold_count_actual *count = prop_data;
- pkt->data[0] =
- HFI_PROPERTY_PARAM_BUFFER_DISPLAY_HOLD_COUNT_ACTUAL;
count->hold_count = in->hold_count;
count->type = in->type;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
@@ -493,7 +486,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
struct hfi_nal_stream_format_select *in = pdata;
struct hfi_nal_stream_format_select *fmt = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT;
fmt->format = in->format;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*fmt);
break;
@@ -510,7 +502,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
break;
}
- pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER;
pkt->data[1] = *in;
pkt->shdr.hdr.size += sizeof(u32) * 2;
break;
@@ -518,7 +509,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE: {
struct hfi_enable_picture *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_PICTURE_TYPE_DECODE;
en->picture_type = in->picture_type;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -526,8 +516,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] =
- HFI_PROPERTY_PARAM_VDEC_OUTPUT2_KEEP_ASPECT_RATIO;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -536,7 +524,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
struct hfi_enable *in = pdata;
struct hfi_enable *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -544,7 +531,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM: {
struct hfi_multi_stream *in = pdata, *multi = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
multi->buffer_type = in->buffer_type;
multi->enable = in->enable;
multi->width = in->width;
@@ -556,8 +542,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
struct hfi_display_picture_buffer_count *in = pdata;
struct hfi_display_picture_buffer_count *count = prop_data;
- pkt->data[0] =
- HFI_PROPERTY_PARAM_VDEC_DISPLAY_PICTURE_BUFFER_COUNT;
count->count = in->count;
count->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
@@ -576,7 +560,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
break;
}
- pkt->data[0] = HFI_PROPERTY_PARAM_DIVX_FORMAT;
pkt->data[1] = *in;
pkt->shdr.hdr.size += sizeof(u32) * 2;
break;
@@ -584,7 +567,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VDEC_MB_ERROR_MAP_REPORTING;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -592,7 +574,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -600,7 +581,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_THUMBNAIL_MODE;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -608,14 +588,11 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] =
- HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
}
case HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME:
- pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_REQUEST_SYNC_FRAME;
pkt->shdr.hdr.size += sizeof(u32);
break;
case HFI_PROPERTY_PARAM_VENC_MPEG4_SHORT_HEADER:
@@ -625,7 +602,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE: {
struct hfi_bitrate *in = pdata, *brate = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_TARGET_BITRATE;
brate->bitrate = in->bitrate;
brate->layer_id = in->layer_id;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*brate);
@@ -634,7 +610,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE: {
struct hfi_bitrate *in = pdata, *hfi = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE;
hfi->bitrate = in->bitrate;
hfi->layer_id = in->layer_id;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hfi);
@@ -643,7 +618,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT: {
struct hfi_profile_level *in = pdata, *pl = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
pl->level = in->level;
pl->profile = in->profile;
if (pl->profile <= 0)
@@ -660,7 +634,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL: {
struct hfi_h264_entropy_control *in = pdata, *hfi = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL;
hfi->entropy_mode = in->entropy_mode;
if (hfi->entropy_mode == HFI_H264_ENTROPY_CABAC)
hfi->cabac_model = in->cabac_model;
@@ -682,7 +655,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
break;
}
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_RATE_CONTROL;
pkt->data[1] = *in;
pkt->shdr.hdr.size += sizeof(u32) * 2;
break;
@@ -690,7 +662,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_MPEG4_TIME_RESOLUTION: {
struct hfi_mpeg4_time_resolution *in = pdata, *res = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_MPEG4_TIME_RESOLUTION;
res->time_increment_resolution = in->time_increment_resolution;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*res);
break;
@@ -698,7 +669,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_MPEG4_HEADER_EXTENSION: {
struct hfi_mpeg4_header_extension *in = pdata, *ext = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_MPEG4_HEADER_EXTENSION;
ext->header_extension = in->header_extension;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ext);
break;
@@ -716,7 +686,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
break;
}
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL;
db->mode = in->mode;
db->slice_alpha_offset = in->slice_alpha_offset;
db->slice_beta_offset = in->slice_beta_offset;
@@ -726,7 +695,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_SESSION_QP: {
struct hfi_quantization *in = pdata, *quant = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_SESSION_QP;
quant->qp_i = in->qp_i;
quant->qp_p = in->qp_p;
quant->qp_b = in->qp_b;
@@ -738,7 +706,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
struct hfi_quantization_range *in = pdata, *range = prop_data;
u32 min_qp, max_qp;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE;
min_qp = in->min_qp;
max_qp = in->max_qp;
@@ -764,8 +731,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_VC1_PERF_CFG: {
struct hfi_vc1e_perf_cfg_type *in = pdata, *perf = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_VC1_PERF_CFG;
-
memcpy(perf->search_range_x_subsampled,
in->search_range_x_subsampled,
sizeof(perf->search_range_x_subsampled));
@@ -780,7 +745,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
struct hfi_max_num_b_frames *bframes = prop_data;
u32 *in = pdata;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_MAX_NUM_B_FRAMES;
bframes->max_num_b_frames = *in;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*bframes);
break;
@@ -788,7 +752,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD: {
struct hfi_intra_period *in = pdata, *intra = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD;
intra->pframes = in->pframes;
intra->bframes = in->bframes;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*intra);
@@ -797,7 +760,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD: {
struct hfi_idr_period *in = pdata, *idr = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD;
idr->idr_period = in->idr_period;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*idr);
break;
@@ -806,7 +768,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
struct hfi_conceal_color *color = prop_data;
u32 *in = pdata;
- pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_CONCEAL_COLOR;
color->conceal_color = *in;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*color);
break;
@@ -835,7 +796,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
break;
}
- pkt->data[0] = HFI_PROPERTY_CONFIG_VPE_OPERATIONS;
ops->rotation = in->rotation;
ops->flip = in->flip;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ops);
@@ -856,7 +816,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
break;
}
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH;
intra->mode = in->mode;
intra->air_mbs = in->air_mbs;
intra->air_ref = in->air_ref;
@@ -878,7 +837,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
break;
}
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_MULTI_SLICE_CONTROL;
multi->multi_slice = in->multi_slice;
multi->slice_size = in->slice_size;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*multi);
@@ -887,7 +845,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_SLICE_DELIVERY_MODE: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_SLICE_DELIVERY_MODE;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -895,7 +852,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO: {
struct hfi_h264_vui_timing_info *in = pdata, *vui = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO;
vui->enable = in->enable;
vui->fixed_framerate = in->fixed_framerate;
vui->time_scale = in->time_scale;
@@ -905,7 +861,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VPE_DEINTERLACE: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VPE_DEINTERLACE;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -913,7 +868,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_H264_GENERATE_AUDNAL: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_H264_GENERATE_AUDNAL;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -921,7 +875,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE: {
struct hfi_buffer_alloc_mode *in = pdata, *mode = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE;
mode->type = in->type;
mode->mode = in->mode;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*mode);
@@ -930,7 +883,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VDEC_FRAME_ASSEMBLY: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_FRAME_ASSEMBLY;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -938,8 +890,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_H264_VUI_BITSTREAM_RESTRC: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] =
- HFI_PROPERTY_PARAM_VENC_H264_VUI_BITSTREAM_RESTRC;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -947,7 +897,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_PRESERVE_TEXT_QUALITY: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_PRESERVE_TEXT_QUALITY;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -956,7 +905,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
struct hfi_scs_threshold *thres = prop_data;
u32 *in = pdata;
- pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_SCS_THRESHOLD;
thres->threshold_value = *in;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*thres);
break;
@@ -974,7 +922,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
break;
}
- pkt->data[0] = HFI_PROPERTY_PARAM_MVC_BUFFER_LAYOUT;
mvc->layout_type = in->layout_type;
mvc->bright_view_first = in->bright_view_first;
mvc->ngap = in->ngap;
@@ -994,7 +941,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
break;
}
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_LTRMODE;
ltr->ltr_mode = in->ltr_mode;
ltr->ltr_count = in->ltr_count;
ltr->trust_mode = in->trust_mode;
@@ -1004,7 +950,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VENC_USELTRFRAME: {
struct hfi_ltr_use *in = pdata, *ltr_use = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_USELTRFRAME;
ltr_use->frames = in->frames;
ltr_use->ref_ltr = in->ref_ltr;
ltr_use->use_constrnt = in->use_constrnt;
@@ -1014,7 +959,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME: {
struct hfi_ltr_mark *in = pdata, *ltr_mark = prop_data;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME;
ltr_mark->mark_frame = in->mark_frame;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*ltr_mark);
break;
@@ -1022,7 +966,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER: {
u32 *in = pdata;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_HIER_P_MAX_NUM_ENH_LAYER;
pkt->data[1] = *in;
pkt->shdr.hdr.size += sizeof(u32) * 2;
break;
@@ -1030,7 +973,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER: {
u32 *in = pdata;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_HIER_P_ENH_LAYER;
pkt->data[1] = *in;
pkt->shdr.hdr.size += sizeof(u32) * 2;
break;
@@ -1038,7 +980,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_DISABLE_RC_TIMESTAMP;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -1046,7 +987,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_INITIAL_QP: {
struct hfi_initial_quantization *in = pdata, *quant = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_INITIAL_QP;
quant->init_qp_enable = in->init_qp_enable;
quant->qp_i = in->qp_i;
quant->qp_p = in->qp_p;
@@ -1058,7 +998,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
struct hfi_vpe_color_space_conversion *in = pdata;
struct hfi_vpe_color_space_conversion *csc = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VPE_COLOR_SPACE_CONVERSION;
memcpy(csc->csc_matrix, in->csc_matrix,
sizeof(csc->csc_matrix));
memcpy(csc->csc_bias, in->csc_bias, sizeof(csc->csc_bias));
@@ -1069,8 +1008,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] =
- HFI_PROPERTY_PARAM_VENC_VPX_ERROR_RESILIENCE_MODE;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -1078,7 +1015,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_H264_NAL_SVC_EXT: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_H264_NAL_SVC_EXT;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -1086,7 +1022,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_VENC_PERF_MODE: {
u32 *in = pdata;
- pkt->data[0] = HFI_PROPERTY_CONFIG_VENC_PERF_MODE;
pkt->data[1] = *in;
pkt->shdr.hdr.size += sizeof(u32) * 2;
break;
@@ -1094,7 +1029,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_HIER_B_MAX_NUM_ENH_LAYER: {
u32 *in = pdata;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_HIER_B_MAX_NUM_ENH_LAYER;
pkt->data[1] = *in;
pkt->shdr.hdr.size += sizeof(u32) * 2;
break;
@@ -1102,7 +1036,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VDEC_NONCP_OUTPUT2: {
struct hfi_enable *in = pdata, *en = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_NONCP_OUTPUT2;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*en);
break;
@@ -1110,7 +1043,6 @@ static int pkt_session_set_property_1x(struct hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE: {
struct hfi_hybrid_hierp *in = pdata, *hierp = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_HIER_P_HYBRID_MODE;
hierp->layers = in->layers;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hierp);
break;
@@ -1185,6 +1117,7 @@ pkt_session_set_property_3xx(struct hfi_session_set_property_pkt *pkt,
pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
pkt->shdr.session_id = hash32_ptr(cookie);
pkt->num_properties = 1;
+ pkt->data[0] = ptype;
/*
* Any session set property which is different in 3XX packetization
@@ -1196,7 +1129,6 @@ pkt_session_set_property_3xx(struct hfi_session_set_property_pkt *pkt,
struct hfi_multi_stream *in = pdata;
struct hfi_multi_stream_3x *multi = prop_data;
- pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_MULTI_STREAM;
multi->buffer_type = in->buffer_type;
multi->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*multi);
@@ -1218,7 +1150,6 @@ pkt_session_set_property_3xx(struct hfi_session_set_property_pkt *pkt,
break;
}
- pkt->data[0] = HFI_PROPERTY_PARAM_VENC_INTRA_REFRESH;
intra->mode = in->mode;
intra->mbs = in->cir_mbs;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*intra);
diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h b/drivers/media/platform/qcom/venus/hfi_helper.h
index 8d282dba9e57..55d8eb21403a 100644
--- a/drivers/media/platform/qcom/venus/hfi_helper.h
+++ b/drivers/media/platform/qcom/venus/hfi_helper.h
@@ -585,8 +585,8 @@ struct hfi_enable {
struct hfi_h264_db_control {
u32 mode;
- u32 slice_alpha_offset;
- u32 slice_beta_offset;
+ s32 slice_alpha_offset;
+ s32 slice_beta_offset;
};
#define HFI_H264_ENTROPY_CAVLC 0x1
diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c
index 3fcf0e9b7b29..e3a10a852cad 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -234,6 +234,16 @@ static int venc_v4l2_to_hfi(int id, int value)
case 3:
return HFI_VPX_PROFILE_VERSION_3;
}
+ case V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE:
+ switch (value) {
+ case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED:
+ default:
+ return HFI_H264_DB_MODE_ALL_BOUNDARY;
+ case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED:
+ return HFI_H264_DB_MODE_DISABLE;
+ case V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY:
+ return HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY;
+ }
}
return 0;
@@ -641,6 +651,8 @@ static int venc_set_properties(struct venus_inst *inst)
if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264) {
struct hfi_h264_vui_timing_info info;
+ struct hfi_h264_entropy_control entropy;
+ struct hfi_h264_db_control deblock;
ptype = HFI_PROPERTY_PARAM_VENC_H264_VUI_TIMING_INFO;
info.enable = 1;
@@ -650,10 +662,36 @@ static int venc_set_properties(struct venus_inst *inst)
ret = hfi_session_set_property(inst, ptype, &info);
if (ret)
return ret;
+
+ ptype = HFI_PROPERTY_PARAM_VENC_H264_ENTROPY_CONTROL;
+ entropy.entropy_mode = venc_v4l2_to_hfi(
+ V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
+ ctr->h264_entropy_mode);
+ entropy.cabac_model = HFI_H264_CABAC_MODEL_0;
+
+ ret = hfi_session_set_property(inst, ptype, &entropy);
+ if (ret)
+ return ret;
+
+ ptype = HFI_PROPERTY_PARAM_VENC_H264_DEBLOCK_CONTROL;
+ deblock.mode = venc_v4l2_to_hfi(
+ V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE,
+ ctr->h264_loop_filter_mode);
+ deblock.slice_alpha_offset = ctr->h264_loop_filter_alpha;
+ deblock.slice_beta_offset = ctr->h264_loop_filter_beta;
+
+ ret = hfi_session_set_property(inst, ptype, &deblock);
+ if (ret)
+ return ret;
}
+ /* IDR periodicity, n:
+ * n = 0 - only the first I-frame is IDR frame
+ * n = 1 - all I-frames will be IDR frames
+ * n > 1 - every n-th I-frame will be IDR frame
+ */
ptype = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD;
- idrp.idr_period = ctr->gop_size;
+ idrp.idr_period = 0;
ret = hfi_session_set_property(inst, ptype, &idrp);
if (ret)
return ret;
@@ -667,10 +705,6 @@ static int venc_set_properties(struct venus_inst *inst)
return ret;
}
- /* intra_period = pframes + bframes + 1 */
- if (!ctr->num_p_frames)
- ctr->num_p_frames = 2 * 15 - 1,
-
ptype = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD;
intra_period.pframes = ctr->num_p_frames;
intra_period.bframes = ctr->num_b_frames;
@@ -767,6 +801,10 @@ static int venc_init_session(struct venus_inst *inst)
if (ret)
goto deinit;
+ ret = venc_set_properties(inst);
+ if (ret)
+ goto deinit;
+
return 0;
deinit:
hfi_session_deinit(inst);
diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c b/drivers/media/platform/qcom/venus/venc_ctrls.c
index ab0fe51ff0f7..21e938a28662 100644
--- a/drivers/media/platform/qcom/venus/venc_ctrls.c
+++ b/drivers/media/platform/qcom/venus/venc_ctrls.c
@@ -30,10 +30,57 @@
#define AT_SLICE_BOUNDARY \
V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
+static int venc_calc_bpframes(u32 gop_size, u32 conseq_b, u32 *bf, u32 *pf)
+{
+ u32 half = (gop_size - 1) >> 1;
+ u32 b, p, ratio;
+ bool found = false;
+
+ if (!gop_size)
+ return -EINVAL;
+
+ *bf = *pf = 0;
+
+ if (!conseq_b) {
+ *pf = gop_size - 1;
+ return 0;
+ }
+
+ b = p = half;
+
+ for (; b <= gop_size - 1; b++, p--) {
+ if (b % p)
+ continue;
+
+ ratio = b / p;
+
+ if (ratio == conseq_b) {
+ found = true;
+ break;
+ }
+
+ if (ratio > conseq_b)
+ break;
+ }
+
+ if (!found)
+ return -EINVAL;
+
+ if (b + p + 1 != gop_size)
+ return -EINVAL;
+
+ *bf = b;
+ *pf = p;
+
+ return 0;
+}
+
static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct venus_inst *inst = ctrl_to_inst(ctrl);
struct venc_controls *ctr = &inst->controls.enc;
+ u32 bframes;
+ int ret;
switch (ctrl->id) {
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
@@ -102,6 +149,11 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
break;
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ ret = venc_calc_bpframes(ctrl->val, ctr->num_b_frames, &bframes,
+ &ctr->num_p_frames);
+ if (ret)
+ return ret;
+
ctr->gop_size = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
@@ -114,7 +166,12 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
ctr->vp8_max_qp = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- ctr->num_b_frames = ctrl->val;
+ ret = venc_calc_bpframes(ctr->gop_size, ctrl->val, &bframes,
+ &ctr->num_p_frames);
+ if (ret)
+ return ret;
+
+ ctr->num_b_frames = bframes;
break;
default:
return -EINVAL;
diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c
index 108d776f3265..f1fc7978d6d1 100644
--- a/drivers/media/platform/rcar-vin/rcar-core.c
+++ b/drivers/media/platform/rcar-vin/rcar-core.c
@@ -187,7 +187,7 @@ static int rvin_digital_graph_init(struct rvin_dev *vin)
return -ENODEV;
vin_dbg(vin, "Found digital subdevice %pOF\n",
- to_of_node(vin->digital->asd.match.fwnode.fwnode));
+ to_of_node(vin->digital->asd.match.fwnode));
vin->notifier.ops = &rvin_digital_notify_ops;
ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier);
diff --git a/drivers/media/platform/rcar_drif.c b/drivers/media/platform/rcar_drif.c
index 63c94f4028a7..b2e080ef5391 100644
--- a/drivers/media/platform/rcar_drif.c
+++ b/drivers/media/platform/rcar_drif.c
@@ -1107,7 +1107,7 @@ static int rcar_drif_notify_bound(struct v4l2_async_notifier *notifier,
struct rcar_drif_sdr *sdr =
container_of(notifier, struct rcar_drif_sdr, notifier);
- if (sdr->ep.asd.match.fwnode.fwnode !=
+ if (sdr->ep.asd.match.fwnode !=
of_fwnode_handle(subdev->dev->of_node)) {
rdrif_err(sdr, "subdev %s cannot bind\n", subdev->name);
return -EINVAL;
@@ -1235,7 +1235,7 @@ static int rcar_drif_parse_subdevs(struct rcar_drif_sdr *sdr)
return -EINVAL;
}
- sdr->ep.asd.match.fwnode.fwnode = fwnode;
+ sdr->ep.asd.match.fwnode = fwnode;
sdr->ep.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
notifier->num_subdevs++;
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index faac8161b683..79b63da27f53 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -3086,7 +3086,7 @@ static int s5p_jpeg_runtime_resume(struct device *dev)
for (i = 0; i < jpeg->variant->num_clocks; i++) {
ret = clk_prepare_enable(jpeg->clocks[i]);
if (ret) {
- while (--i > 0)
+ while (--i >= 0)
clk_disable_unprepare(jpeg->clocks[i]);
return ret;
}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index fe94bd6b705e..f15cf24c1c63 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1309,6 +1309,12 @@ static int s5p_mfc_probe(struct platform_device *pdev)
goto err_dma;
}
+ /*
+ * Load fails if fs isn't mounted. Try loading anyway.
+ * _open() will load it, it it fails now. Ignore failure.
+ */
+ s5p_mfc_load_firmware(dev);
+
mutex_init(&dev->mfc_mutex);
init_waitqueue_head(&dev->queue);
dev->hw_lock = 0;
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
index 4220914529b2..76119a8cc477 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h
@@ -290,6 +290,8 @@ struct s5p_mfc_priv_buf {
* @mfc_cmds: cmd structure holding HW commands function pointers
* @mfc_regs: structure holding MFC registers
* @fw_ver: loaded firmware sub-version
+ * @fw_get_done flag set when request_firmware() is complete and
+ * copied into fw_buf
* risc_on: flag indicates RISC is on or off
*
*/
@@ -336,6 +338,7 @@ struct s5p_mfc_dev {
struct s5p_mfc_hw_cmds *mfc_cmds;
const struct s5p_mfc_regs *mfc_regs;
enum s5p_mfc_fw_ver fw_ver;
+ bool fw_get_done;
bool risc_on; /* indicates if RISC is on or off */
};
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
index 69ef9c23a99a..f95cd76af537 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
@@ -55,6 +55,9 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
* into kernel. */
mfc_debug_enter();
+ if (dev->fw_get_done)
+ return 0;
+
for (i = MFC_FW_MAX_VERSIONS - 1; i >= 0; i--) {
if (!dev->variant->fw_name[i])
continue;
@@ -75,13 +78,9 @@ int s5p_mfc_load_firmware(struct s5p_mfc_dev *dev)
release_firmware(fw_blob);
return -ENOMEM;
}
- if (!dev->fw_buf.virt) {
- mfc_err("MFC firmware is not allocated\n");
- release_firmware(fw_blob);
- return -EINVAL;
- }
memcpy(dev->fw_buf.virt, fw_blob->data, fw_blob->size);
wmb();
+ dev->fw_get_done = true;
release_firmware(fw_blob);
mfc_debug_leave();
return 0;
@@ -93,6 +92,7 @@ int s5p_mfc_release_firmware(struct s5p_mfc_dev *dev)
/* Before calling this function one has to make sure
* that MFC is no longer processing */
s5p_mfc_release_priv_buf(dev, &dev->fw_buf);
+ dev->fw_get_done = false;
return 0;
}
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
index 2a5fd7c42cd5..0d5d465561be 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
@@ -2080,7 +2080,7 @@ int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx)
if (cfg.type == V4L2_CTRL_TYPE_MENU) {
cfg.step = 0;
- cfg.menu_skip_mask = cfg.menu_skip_mask;
+ cfg.menu_skip_mask = controls[i].menu_skip_mask;
cfg.qmenu = mfc51_get_menu(cfg.id);
} else {
cfg.step = controls[i].step;
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 871da2a2a91c..4dccf29e9d78 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -1181,7 +1181,7 @@ static int sh_vou_release(struct file *file)
/* sh_vou display ioctl operations */
static const struct v4l2_ioctl_ops sh_vou_ioctl_ops = {
- .vidioc_querycap = sh_vou_querycap,
+ .vidioc_querycap = sh_vou_querycap,
.vidioc_enum_fmt_vid_out = sh_vou_enum_fmt_vid_out,
.vidioc_g_fmt_vid_out = sh_vou_g_fmt_vid_out,
.vidioc_s_fmt_vid_out = sh_vou_s_fmt_vid_out,
diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
index 9b069783e3ed..242342fd7ede 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c
@@ -451,13 +451,18 @@ static void sh_mobile_ceu_stop_streaming(struct vb2_queue *q)
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
struct list_head *buf_head, *tmp;
+ struct vb2_v4l2_buffer *vbuf;
spin_lock_irq(&pcdev->lock);
pcdev->active = NULL;
- list_for_each_safe(buf_head, tmp, &pcdev->capture)
+ list_for_each_safe(buf_head, tmp, &pcdev->capture) {
+ vbuf = &list_entry(buf_head, struct sh_mobile_ceu_buffer,
+ queue)->vb;
+ vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
list_del_init(buf_head);
+ }
spin_unlock_irq(&pcdev->lock);
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index d964c072832c..70fc5f01942d 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -1517,7 +1517,7 @@ static int soc_of_bind(struct soc_camera_host *ici,
if (!info)
return -ENOMEM;
- info->sasd.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+ info->sasd.asd.match.fwnode = of_fwnode_handle(remote);
info->sasd.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
info->subdev = &info->sasd.asd;
diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c
index 270ec613c27c..6164102e6f9f 100644
--- a/drivers/media/platform/soc_camera/soc_scale_crop.c
+++ b/drivers/media/platform/soc_camera/soc_scale_crop.c
@@ -420,3 +420,7 @@ void soc_camera_calc_client_output(struct soc_camera_device *icd,
mf->height = soc_camera_shift_scale(rect->height, shift, scale_v);
}
EXPORT_SYMBOL(soc_camera_calc_client_output);
+
+MODULE_DESCRIPTION("soc-camera scaling-cropping functions");
+MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/sti/bdisp/bdisp-debug.c b/drivers/media/platform/sti/bdisp/bdisp-debug.c
index 2cc289e4dea1..c6a4e2de5c0c 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-debug.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-debug.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2014
* Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/debugfs.h>
diff --git a/drivers/media/platform/sti/bdisp/bdisp-filter.h b/drivers/media/platform/sti/bdisp/bdisp-filter.h
index 53e52fb4127f..d25adb57e3d0 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-filter.h
+++ b/drivers/media/platform/sti/bdisp/bdisp-filter.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2014
* Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#define BDISP_HF_NB 64
diff --git a/drivers/media/platform/sti/bdisp/bdisp-hw.c b/drivers/media/platform/sti/bdisp/bdisp-hw.c
index b7892f3efd98..a5eb592e12c0 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-hw.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-hw.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2014
* Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/delay.h>
@@ -1064,7 +1064,7 @@ static void bdisp_hw_save_request(struct bdisp_ctx *ctx)
if (!copy_node[i]) {
copy_node[i] = devm_kzalloc(ctx->bdisp_dev->dev,
sizeof(*copy_node[i]),
- GFP_KERNEL);
+ GFP_ATOMIC);
if (!copy_node[i])
return;
}
diff --git a/drivers/media/platform/sti/bdisp/bdisp-reg.h b/drivers/media/platform/sti/bdisp/bdisp-reg.h
index e7e1a425f65a..b07ecc903707 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-reg.h
+++ b/drivers/media/platform/sti/bdisp/bdisp-reg.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2014
* Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
struct bdisp_node {
diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
index 7e9ed9c7b3e1..bf4ca16db440 100644
--- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
+++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2014
* Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/errno.h>
diff --git a/drivers/media/platform/sti/bdisp/bdisp.h b/drivers/media/platform/sti/bdisp/bdisp.h
index b3fbf9902595..e309cde379ca 100644
--- a/drivers/media/platform/sti/bdisp/bdisp.h
+++ b/drivers/media/platform/sti/bdisp/bdisp.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2014
* Authors: Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/clk.h>
diff --git a/drivers/media/platform/sti/c8sectpfe/Kconfig b/drivers/media/platform/sti/c8sectpfe/Kconfig
index 7420a50572d3..740190f8a3b6 100644
--- a/drivers/media/platform/sti/c8sectpfe/Kconfig
+++ b/drivers/media/platform/sti/c8sectpfe/Kconfig
@@ -1,6 +1,6 @@
config DVB_C8SECTPFE
tristate "STMicroelectronics C8SECTPFE DVB support"
- depends on PINCTRL && DVB_CORE && I2C
+ depends on PINCTRL && DVB_CORE && I2C && HAS_DMA
depends on ARCH_STI || ARCH_MULTIPLATFORM || COMPILE_TEST
select FW_LOADER
select DEBUG_FS
diff --git a/drivers/media/platform/sti/c8sectpfe/Makefile b/drivers/media/platform/sti/c8sectpfe/Makefile
index b642b4fd5045..34d69472b6f0 100644
--- a/drivers/media/platform/sti/c8sectpfe/Makefile
+++ b/drivers/media/platform/sti/c8sectpfe/Makefile
@@ -4,7 +4,6 @@ c8sectpfe-y += c8sectpfe-core.o c8sectpfe-common.o c8sectpfe-dvb.o \
obj-$(CONFIG_DVB_C8SECTPFE) += c8sectpfe.o
-ccflags-y += -Idrivers/media/i2c
ccflags-y += -Idrivers/media/common
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends/ \
- -Idrivers/media/tuners/
+ccflags-y += -Idrivers/media/dvb-frontends/
+ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.c
index 2dfbe8ab5214..5df67da25525 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* c8sectpfe-common.c - C8SECTPFE STi DVB driver
*
@@ -5,10 +6,6 @@
*
* Author: Peter Griffin <peter.griffin@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/completion.h>
#include <linux/delay.h>
@@ -24,11 +21,11 @@
#include <linux/time.h>
#include <linux/wait.h>
-#include "dmxdev.h"
-#include "dvbdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvbdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "c8sectpfe-common.h"
#include "c8sectpfe-core.h"
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h
index da21c0ac0fc1..5ab7ca448cf9 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-common.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* c8sectpfe-common.h - C8SECTPFE STi DVB driver
*
@@ -5,10 +6,6 @@
*
* Author: Peter Griffin <peter.griffin@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 _C8SECTPFE_COMMON_H_
#define _C8SECTPFE_COMMON_H_
@@ -18,10 +15,10 @@
#include <linux/gpio.h>
#include <linux/version.h>
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
/* Maximum number of channels */
#define C8SECTPFE_MAXADAPTER (4)
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
index a0acee7671b1..3c05b3dc49ec 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* c8sectpfe-core.c - C8SECTPFE STi DVB driver
*
@@ -6,10 +7,6 @@
* Author:Peter Bennett <peter.bennett@st.com>
* Peter Griffin <peter.griffin@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/atomic.h>
#include <linux/clk.h>
@@ -38,10 +35,10 @@
#include "c8sectpfe-core.h"
#include "c8sectpfe-common.h"
#include "c8sectpfe-debugfs.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#define FIRMWARE_MEMDMA "pti_memdma_h407.elf"
MODULE_FIRMWARE(FIRMWARE_MEMDMA);
@@ -83,7 +80,7 @@ static void c8sectpfe_timer_interrupt(struct timer_list *t)
static void channel_swdemux_tsklet(unsigned long data)
{
struct channel_info *channel = (struct channel_info *)data;
- struct c8sectpfei *fei = channel->fei;
+ struct c8sectpfei *fei;
unsigned long wp, rp;
int pos, num_packets, n, size;
u8 *buf;
@@ -91,6 +88,8 @@ static void channel_swdemux_tsklet(unsigned long data)
if (unlikely(!channel || !channel->irec))
return;
+ fei = channel->fei;
+
wp = readl(channel->irec + DMA_PRDS_BUSWP_TP(0));
rp = readl(channel->irec + DMA_PRDS_BUSRP_TP(0));
@@ -691,7 +690,7 @@ static int c8sectpfe_probe(struct platform_device *pdev)
if (IS_ERR(fei->sram))
return PTR_ERR(fei->sram);
- fei->sram_size = res->end - res->start;
+ fei->sram_size = resource_size(res);
fei->idle_irq = platform_get_irq_byname(pdev, "c8sectpfe-idle-irq");
if (fei->idle_irq < 0) {
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.h b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.h
index 39e7a221a941..3dbb3a287cc0 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.h
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* c8sectpfe-core.h - C8SECTPFE STi DVB driver
*
@@ -6,10 +7,6 @@
* Author:Peter Bennett <peter.bennett@st.com>
* Peter Griffin <peter.griffin@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 _C8SECTPFE_CORE_H_
#define _C8SECTPFE_CORE_H_
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.c
index e9ba13db49cd..8f0ddcbeed9d 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* c8sectpfe-debugfs.c - C8SECTPFE STi DVB driver
*
@@ -5,14 +6,6 @@
*
* Author: Peter Griffin <peter.griffin@linaro.org>
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 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.
*/
#include <linux/debugfs.h>
#include <linux/device.h>
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.h b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.h
index 8af1ac1378c8..b8c30bcc8df9 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.h
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-debugfs.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
* c8sectpfe-debugfs.h - C8SECTPFE STi DVB driver debugfs header
*
@@ -5,14 +6,6 @@
*
* Authors: Peter Griffin <peter.griffin@linaro.org>
*
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 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.
*/
#ifndef __C8SECTPFE_DEBUG_H
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c
index 2c0015b1264d..075d4695ee4d 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* c8sectpfe-dvb.c - C8SECTPFE STi DVB driver
*
@@ -5,16 +6,6 @@
*
* Author Peter Griffin <peter.griffin@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.
*/
#include <linux/completion.h>
#include <linux/delay.h>
diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.h b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.h
index bd366dbc82b3..3d87a9ae8702 100644
--- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.h
+++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* c8sectpfe-common.h - C8SECTPFE STi DVB driver
*
@@ -5,10 +6,6 @@
*
* Author: Peter Griffin <peter.griffin@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 _C8SECTPFE_DVB_H_
#define _C8SECTPFE_DVB_H_
diff --git a/drivers/media/platform/sti/cec/stih-cec.c b/drivers/media/platform/sti/cec/stih-cec.c
index 70160df36de9..d34099f75990 100644
--- a/drivers/media/platform/sti/cec/stih-cec.c
+++ b/drivers/media/platform/sti/cec/stih-cec.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* STIH4xx CEC driver
* Copyright (C) STMicroelectronics SA 2016
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the 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/interrupt.h>
diff --git a/drivers/media/platform/sti/delta/delta-cfg.h b/drivers/media/platform/sti/delta/delta-cfg.h
index c6388f575800..f47c6e6ff083 100644
--- a/drivers/media/platform/sti/delta/delta-cfg.h
+++ b/drivers/media/platform/sti/delta/delta-cfg.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2015
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#ifndef DELTA_CFG_H
diff --git a/drivers/media/platform/sti/delta/delta-debug.c b/drivers/media/platform/sti/delta/delta-debug.c
index a7ebf2cc7783..4b2eb6b63aa2 100644
--- a/drivers/media/platform/sti/delta/delta-debug.c
+++ b/drivers/media/platform/sti/delta/delta-debug.c
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Hugues Fruchet <hugues.fruchet@st.com>
* Fabrice Lecoultre <fabrice.lecoultre@st.com>
* for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#include "delta.h"
diff --git a/drivers/media/platform/sti/delta/delta-debug.h b/drivers/media/platform/sti/delta/delta-debug.h
index 955c1587ac2d..fa90252623e1 100644
--- a/drivers/media/platform/sti/delta/delta-debug.h
+++ b/drivers/media/platform/sti/delta/delta-debug.h
@@ -1,9 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Hugues Fruchet <hugues.fruchet@st.com>
* Fabrice Lecoultre <fabrice.lecoultre@st.com>
* for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#ifndef DELTA_DEBUG_H
diff --git a/drivers/media/platform/sti/delta/delta-ipc.c b/drivers/media/platform/sti/delta/delta-ipc.c
index 41e4a4c259b3..a4603d573c34 100644
--- a/drivers/media/platform/sti/delta/delta-ipc.c
+++ b/drivers/media/platform/sti/delta/delta-ipc.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2015
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/rpmsg.h>
diff --git a/drivers/media/platform/sti/delta/delta-ipc.h b/drivers/media/platform/sti/delta/delta-ipc.h
index cef2019c72d4..9fba6b5d169a 100644
--- a/drivers/media/platform/sti/delta/delta-ipc.h
+++ b/drivers/media/platform/sti/delta/delta-ipc.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2015
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#ifndef DELTA_IPC_H
diff --git a/drivers/media/platform/sti/delta/delta-mem.c b/drivers/media/platform/sti/delta/delta-mem.c
index d7b53d31caa6..aeccd50583da 100644
--- a/drivers/media/platform/sti/delta/delta-mem.c
+++ b/drivers/media/platform/sti/delta/delta-mem.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2015
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#include "delta.h"
diff --git a/drivers/media/platform/sti/delta/delta-mem.h b/drivers/media/platform/sti/delta/delta-mem.h
index f8ca109e1241..ff7d02f00b28 100644
--- a/drivers/media/platform/sti/delta/delta-mem.h
+++ b/drivers/media/platform/sti/delta/delta-mem.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2015
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#ifndef DELTA_MEM_H
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg-dec.c b/drivers/media/platform/sti/delta/delta-mjpeg-dec.c
index 84ea43c0eb46..0533d4a083d2 100644
--- a/drivers/media/platform/sti/delta/delta-mjpeg-dec.c
+++ b/drivers/media/platform/sti/delta/delta-mjpeg-dec.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2013
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/slab.h>
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg-fw.h b/drivers/media/platform/sti/delta/delta-mjpeg-fw.h
index de803d0c2fe8..5a9404f4d055 100644
--- a/drivers/media/platform/sti/delta/delta-mjpeg-fw.h
+++ b/drivers/media/platform/sti/delta/delta-mjpeg-fw.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2015
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#ifndef DELTA_MJPEG_FW_H
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg-hdr.c b/drivers/media/platform/sti/delta/delta-mjpeg-hdr.c
index a8fd8fa0ecb5..90e5b2f72c82 100644
--- a/drivers/media/platform/sti/delta/delta-mjpeg-hdr.c
+++ b/drivers/media/platform/sti/delta/delta-mjpeg-hdr.c
@@ -1,7 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2013
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#include "delta.h"
diff --git a/drivers/media/platform/sti/delta/delta-mjpeg.h b/drivers/media/platform/sti/delta/delta-mjpeg.h
index 18e6b37217ee..43f7a88b6e59 100644
--- a/drivers/media/platform/sti/delta/delta-mjpeg.h
+++ b/drivers/media/platform/sti/delta/delta-mjpeg.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2013
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#ifndef DELTA_MJPEG_H
diff --git a/drivers/media/platform/sti/delta/delta-v4l2.c b/drivers/media/platform/sti/delta/delta-v4l2.c
index b2dc3d223a9c..232d508c5b66 100644
--- a/drivers/media/platform/sti/delta/delta-v4l2.c
+++ b/drivers/media/platform/sti/delta/delta-v4l2.c
@@ -1,9 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Hugues Fruchet <hugues.fruchet@st.com>
* Jean-Christophe Trotin <jean-christophe.trotin@st.com>
* for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/clk.h>
diff --git a/drivers/media/platform/sti/delta/delta.h b/drivers/media/platform/sti/delta/delta.h
index 60c073246a01..2ba99922c05b 100644
--- a/drivers/media/platform/sti/delta/delta.h
+++ b/drivers/media/platform/sti/delta/delta.h
@@ -1,7 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2015
* Author: Hugues Fruchet <hugues.fruchet@st.com> for STMicroelectronics.
- * License terms: GNU General Public License (GPL), version 2
*/
#ifndef DELTA_H
diff --git a/drivers/media/platform/sti/hva/hva-debugfs.c b/drivers/media/platform/sti/hva/hva-debugfs.c
index 83a6258a155b..9f7e8ac875d1 100644
--- a/drivers/media/platform/sti/hva/hva-debugfs.c
+++ b/drivers/media/platform/sti/hva/hva-debugfs.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Yannick Fertre <yannick.fertre@st.com>
* Hugues Fruchet <hugues.fruchet@st.com>
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/debugfs.h>
diff --git a/drivers/media/platform/sti/hva/hva-h264.c b/drivers/media/platform/sti/hva/hva-h264.c
index 17f1eb0ba957..b61a5d337d2a 100644
--- a/drivers/media/platform/sti/hva/hva-h264.c
+++ b/drivers/media/platform/sti/hva/hva-h264.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Yannick Fertre <yannick.fertre@st.com>
* Hugues Fruchet <hugues.fruchet@st.com>
- * License terms: GNU General Public License (GPL), version 2
*/
#include "hva.h"
diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c
index ec25bdcfa3d1..7917fd2c4bd4 100644
--- a/drivers/media/platform/sti/hva/hva-hw.c
+++ b/drivers/media/platform/sti/hva/hva-hw.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Yannick Fertre <yannick.fertre@st.com>
* Hugues Fruchet <hugues.fruchet@st.com>
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/clk.h>
diff --git a/drivers/media/platform/sti/hva/hva-hw.h b/drivers/media/platform/sti/hva/hva-hw.h
index b46017dcfae9..b298990264d5 100644
--- a/drivers/media/platform/sti/hva/hva-hw.h
+++ b/drivers/media/platform/sti/hva/hva-hw.h
@@ -1,8 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Yannick Fertre <yannick.fertre@st.com>
* Hugues Fruchet <hugues.fruchet@st.com>
- * License terms: GNU General Public License (GPL), version 2
*/
#ifndef HVA_HW_H
diff --git a/drivers/media/platform/sti/hva/hva-mem.c b/drivers/media/platform/sti/hva/hva-mem.c
index 821c78ed208c..caf50cd4bb77 100644
--- a/drivers/media/platform/sti/hva/hva-mem.c
+++ b/drivers/media/platform/sti/hva/hva-mem.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Yannick Fertre <yannick.fertre@st.com>
* Hugues Fruchet <hugues.fruchet@st.com>
- * License terms: GNU General Public License (GPL), version 2
*/
#include "hva.h"
diff --git a/drivers/media/platform/sti/hva/hva-mem.h b/drivers/media/platform/sti/hva/hva-mem.h
index a95c728a45e6..fec549dff2b3 100644
--- a/drivers/media/platform/sti/hva/hva-mem.h
+++ b/drivers/media/platform/sti/hva/hva-mem.h
@@ -1,8 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Yannick Fertre <yannick.fertre@st.com>
* Hugues Fruchet <hugues.fruchet@st.com>
- * License terms: GNU General Public License (GPL), version 2
*/
#ifndef HVA_MEM_H
diff --git a/drivers/media/platform/sti/hva/hva-v4l2.c b/drivers/media/platform/sti/hva/hva-v4l2.c
index 1c4fc33cbcb5..2ab0b5cc5c22 100644
--- a/drivers/media/platform/sti/hva/hva-v4l2.c
+++ b/drivers/media/platform/sti/hva/hva-v4l2.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Yannick Fertre <yannick.fertre@st.com>
* Hugues Fruchet <hugues.fruchet@st.com>
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/module.h>
diff --git a/drivers/media/platform/sti/hva/hva.h b/drivers/media/platform/sti/hva/hva.h
index 0d749b257a21..1226d60cc367 100644
--- a/drivers/media/platform/sti/hva/hva.h
+++ b/drivers/media/platform/sti/hva/hva.h
@@ -1,8 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) STMicroelectronics SA 2015
* Authors: Yannick Fertre <yannick.fertre@st.com>
* Hugues Fruchet <hugues.fruchet@st.com>
- * License terms: GNU General Public License (GPL), version 2
*/
#ifndef HVA_H
@@ -245,7 +245,7 @@ struct hva_enc;
* @dbg: context debug info
*/
struct hva_ctx {
- struct hva_dev *hva_dev;
+ struct hva_dev *hva_dev;
struct v4l2_fh fh;
struct v4l2_ctrl_handler ctrl_handler;
struct hva_controls ctrls;
diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
index ac4c450a6c7d..9460b3080dca 100644
--- a/drivers/media/platform/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/stm32/stm32-dcmi.c
@@ -1520,7 +1520,7 @@ static int dcmi_graph_parse(struct stm32_dcmi *dcmi, struct device_node *node)
/* Remote node to connect */
dcmi->entity.node = remote;
dcmi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
- dcmi->entity.asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+ dcmi->entity.asd.match.fwnode = of_fwnode_handle(remote);
return 0;
}
}
diff --git a/drivers/media/platform/tegra-cec/tegra_cec.c b/drivers/media/platform/tegra-cec/tegra_cec.c
index 807c94c70049..92f93a880015 100644
--- a/drivers/media/platform/tegra-cec/tegra_cec.c
+++ b/drivers/media/platform/tegra-cec/tegra_cec.c
@@ -493,3 +493,8 @@ static struct platform_driver tegra_cec_driver = {
};
module_platform_driver(tegra_cec_driver);
+
+MODULE_DESCRIPTION("Tegra HDMI CEC driver");
+MODULE_AUTHOR("NVIDIA CORPORATION");
+MODULE_AUTHOR("Cisco Systems, Inc. and/or its affiliates");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c
index 8b586c864524..d1febe5baa6d 100644
--- a/drivers/media/platform/ti-vpe/cal.c
+++ b/drivers/media/platform/ti-vpe/cal.c
@@ -28,10 +28,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-ctrls.h>
#include <media/v4l2-fh.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-common.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-dma-contig.h>
#include "cal_regs.h"
@@ -1705,7 +1702,7 @@ static int of_cal_create_instance(struct cal_ctx *ctx, int inst)
goto cleanup_exit;
}
asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
- asd->match.fwnode.fwnode = of_fwnode_handle(sensor_node);
+ asd->match.fwnode = of_fwnode_handle(sensor_node);
remote_ep = of_graph_get_remote_endpoint(ep_node);
if (!remote_ep) {
diff --git a/drivers/media/platform/via-camera.h b/drivers/media/platform/via-camera.h
index 2d67f8ce258d..54f16318b1b3 100644
--- a/drivers/media/platform/via-camera.h
+++ b/drivers/media/platform/via-camera.h
@@ -29,7 +29,7 @@
#define VCR_CI_BSS 0x00000002 /* WTF "bit stream selection" */
#define VCR_CI_3BUFS 0x00000004 /* 1 = 3 buffers, 0 = 2 buffers */
#define VCR_CI_VIPEN 0x00000008 /* VIP enable */
-#define VCR_CI_CCIR601_8 0 /* CCIR601 input stream, 8 bit */
+#define VCR_CI_CCIR601_8 0 /* CCIR601 input stream, 8 bit */
#define VCR_CI_CCIR656_8 0x00000010 /* ... CCIR656, 8 bit */
#define VCR_CI_CCIR601_16 0x00000020 /* ... CCIR601, 16 bit */
#define VCR_CI_CCIR656_16 0x00000030 /* ... CCIR656, 16 bit */
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
index dca528a316e7..2e9981b18166 100644
--- a/drivers/media/platform/vimc/vimc-common.h
+++ b/drivers/media/platform/vimc/vimc-common.h
@@ -22,6 +22,11 @@
#include <media/media-device.h>
#include <media/v4l2-device.h>
+/* VIMC-specific controls */
+#define VIMC_CID_VIMC_BASE (0x00f00000 | 0xf000)
+#define VIMC_CID_VIMC_CLASS (0x00f00000 | 1)
+#define VIMC_CID_TEST_PATTERN (VIMC_CID_VIMC_BASE + 0)
+
#define VIMC_FRAME_MAX_WIDTH 4096
#define VIMC_FRAME_MAX_HEIGHT 2160
#define VIMC_FRAME_MIN_WIDTH 16
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index 02e68c8fc02b..457e211514c6 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -22,8 +22,9 @@
#include <linux/platform_device.h>
#include <linux/v4l2-mediabus.h>
#include <linux/vmalloc.h>
+#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
-#include <media/v4l2-tpg.h>
+#include <media/tpg/v4l2-tpg.h>
#include "vimc-common.h"
@@ -38,6 +39,7 @@ struct vimc_sen_device {
u8 *frame;
/* The active format */
struct v4l2_mbus_framefmt mbus_format;
+ struct v4l2_ctrl_handler hdl;
};
static const struct v4l2_mbus_framefmt fmt_default = {
@@ -291,6 +293,31 @@ static const struct v4l2_subdev_ops vimc_sen_ops = {
.video = &vimc_sen_video_ops,
};
+static int vimc_sen_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct vimc_sen_device *vsen =
+ container_of(ctrl->handler, struct vimc_sen_device, hdl);
+
+ switch (ctrl->id) {
+ case VIMC_CID_TEST_PATTERN:
+ tpg_s_pattern(&vsen->tpg, ctrl->val);
+ break;
+ case V4L2_CID_HFLIP:
+ tpg_s_hflip(&vsen->tpg, ctrl->val);
+ break;
+ case V4L2_CID_VFLIP:
+ tpg_s_vflip(&vsen->tpg, ctrl->val);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = {
+ .s_ctrl = vimc_sen_s_ctrl,
+};
+
static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
void *master_data)
{
@@ -299,10 +326,28 @@ static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
container_of(ved, struct vimc_sen_device, ved);
vimc_ent_sd_unregister(ved, &vsen->sd);
+ v4l2_ctrl_handler_free(&vsen->hdl);
tpg_free(&vsen->tpg);
kfree(vsen);
}
+/* Image Processing Controls */
+static const struct v4l2_ctrl_config vimc_sen_ctrl_class = {
+ .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
+ .id = VIMC_CID_VIMC_CLASS,
+ .name = "VIMC Controls",
+ .type = V4L2_CTRL_TYPE_CTRL_CLASS,
+};
+
+static const struct v4l2_ctrl_config vimc_sen_ctrl_test_pattern = {
+ .ops = &vimc_sen_ctrl_ops,
+ .id = VIMC_CID_TEST_PATTERN,
+ .name = "Test Pattern",
+ .type = V4L2_CTRL_TYPE_MENU,
+ .max = TPG_PAT_NOISE,
+ .qmenu = tpg_pattern_strings,
+};
+
static int vimc_sen_comp_bind(struct device *comp, struct device *master,
void *master_data)
{
@@ -316,6 +361,20 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
if (!vsen)
return -ENOMEM;
+ v4l2_ctrl_handler_init(&vsen->hdl, 4);
+
+ v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_class, NULL);
+ v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_test_pattern, NULL);
+ v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+ V4L2_CID_VFLIP, 0, 1, 1, 0);
+ v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
+ V4L2_CID_HFLIP, 0, 1, 1, 0);
+ vsen->sd.ctrl_handler = &vsen->hdl;
+ if (vsen->hdl.error) {
+ ret = vsen->hdl.error;
+ goto err_free_vsen;
+ }
+
/* Initialize ved and sd */
ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
pdata->entity_name,
@@ -323,7 +382,7 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
(const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
&vimc_sen_ops);
if (ret)
- goto err_free_vsen;
+ goto err_free_hdl;
dev_set_drvdata(comp, &vsen->ved);
vsen->dev = comp;
@@ -342,6 +401,8 @@ static int vimc_sen_comp_bind(struct device *comp, struct device *master,
err_unregister_ent_sd:
vimc_ent_sd_unregister(&vsen->ved, &vsen->sd);
+err_free_hdl:
+ v4l2_ctrl_handler_free(&vsen->hdl);
err_free_vsen:
kfree(vsen);
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index c80239592088..9f036c5f51b0 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -995,7 +995,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
dev->edid_max_blocks = dev->edid_blocks = 2;
memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid));
- ktime_get_ts(&dev->radio_rds_init_ts);
+ dev->radio_rds_init_time = ktime_get();
/* create all controls */
ret = vivid_create_controls(dev, ccs_cap == -1, ccs_out == -1, no_error_inj,
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
index 5cdf95bdc4d1..c90e4a0ab94e 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -27,7 +27,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-dev.h>
#include <media/v4l2-ctrls.h>
-#include <media/v4l2-tpg.h>
+#include <media/tpg/v4l2-tpg.h>
#include "vivid-rds-gen.h"
#include "vivid-vbi-gen.h"
@@ -154,6 +154,7 @@ struct vivid_dev {
struct v4l2_ctrl_handler ctrl_hdl_streaming;
struct v4l2_ctrl_handler ctrl_hdl_sdtv_cap;
struct v4l2_ctrl_handler ctrl_hdl_loop_cap;
+ struct v4l2_ctrl_handler ctrl_hdl_fb;
struct video_device vid_cap_dev;
struct v4l2_ctrl_handler ctrl_hdl_vid_cap;
struct video_device vid_out_dev;
@@ -510,7 +511,7 @@ struct vivid_dev {
/* Shared between radio receiver and transmitter */
bool radio_rds_loop;
- struct timespec radio_rds_init_ts;
+ ktime_t radio_rds_init_time;
/* CEC */
struct cec_adapter *cec_rx_adap;
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
index 34731f71cc00..3f9d354827af 100644
--- a/drivers/media/platform/vivid/vivid-ctrls.c
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
@@ -120,9 +120,6 @@ static int vivid_user_gen_s_ctrl(struct v4l2_ctrl *ctrl)
clear_bit(V4L2_FL_REGISTERED, &dev->radio_rx_dev.flags);
clear_bit(V4L2_FL_REGISTERED, &dev->radio_tx_dev.flags);
break;
- case VIVID_CID_CLEAR_FB:
- vivid_clear_fb(dev);
- break;
case VIVID_CID_BUTTON:
dev->button_pressed = 30;
break;
@@ -274,8 +271,28 @@ static const struct v4l2_ctrl_config vivid_ctrl_disconnect = {
.type = V4L2_CTRL_TYPE_BUTTON,
};
+
+/* Framebuffer Controls */
+
+static int vivid_fb_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct vivid_dev *dev = container_of(ctrl->handler,
+ struct vivid_dev, ctrl_hdl_fb);
+
+ switch (ctrl->id) {
+ case VIVID_CID_CLEAR_FB:
+ vivid_clear_fb(dev);
+ break;
+ }
+ return 0;
+}
+
+static const struct v4l2_ctrl_ops vivid_fb_ctrl_ops = {
+ .s_ctrl = vivid_fb_s_ctrl,
+};
+
static const struct v4l2_ctrl_config vivid_ctrl_clear_fb = {
- .ops = &vivid_user_gen_ctrl_ops,
+ .ops = &vivid_fb_ctrl_ops,
.id = VIVID_CID_CLEAR_FB,
.name = "Clear Framebuffer",
.type = V4L2_CTRL_TYPE_BUTTON,
@@ -1357,6 +1374,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
struct v4l2_ctrl_handler *hdl_streaming = &dev->ctrl_hdl_streaming;
struct v4l2_ctrl_handler *hdl_sdtv_cap = &dev->ctrl_hdl_sdtv_cap;
struct v4l2_ctrl_handler *hdl_loop_cap = &dev->ctrl_hdl_loop_cap;
+ struct v4l2_ctrl_handler *hdl_fb = &dev->ctrl_hdl_fb;
struct v4l2_ctrl_handler *hdl_vid_cap = &dev->ctrl_hdl_vid_cap;
struct v4l2_ctrl_handler *hdl_vid_out = &dev->ctrl_hdl_vid_out;
struct v4l2_ctrl_handler *hdl_vbi_cap = &dev->ctrl_hdl_vbi_cap;
@@ -1384,10 +1402,12 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
v4l2_ctrl_new_custom(hdl_sdtv_cap, &vivid_ctrl_class, NULL);
v4l2_ctrl_handler_init(hdl_loop_cap, 1);
v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_class, NULL);
+ v4l2_ctrl_handler_init(hdl_fb, 1);
+ v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_class, NULL);
v4l2_ctrl_handler_init(hdl_vid_cap, 55);
v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL);
v4l2_ctrl_handler_init(hdl_vid_out, 26);
- if (!no_error_inj)
+ if (!no_error_inj || dev->has_fb)
v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL);
v4l2_ctrl_handler_init(hdl_vbi_cap, 21);
v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL);
@@ -1561,7 +1581,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
v4l2_ctrl_new_custom(hdl_loop_cap, &vivid_ctrl_loop_video, NULL);
if (dev->has_fb)
- v4l2_ctrl_new_custom(hdl_user_gen, &vivid_ctrl_clear_fb, NULL);
+ v4l2_ctrl_new_custom(hdl_fb, &vivid_ctrl_clear_fb, NULL);
if (dev->has_radio_rx) {
v4l2_ctrl_new_custom(hdl_radio_rx, &vivid_ctrl_radio_hw_seek_mode, NULL);
@@ -1658,6 +1678,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
v4l2_ctrl_add_handler(hdl_vid_cap, hdl_streaming, NULL);
v4l2_ctrl_add_handler(hdl_vid_cap, hdl_sdtv_cap, NULL);
v4l2_ctrl_add_handler(hdl_vid_cap, hdl_loop_cap, NULL);
+ v4l2_ctrl_add_handler(hdl_vid_cap, hdl_fb, NULL);
if (hdl_vid_cap->error)
return hdl_vid_cap->error;
dev->vid_cap_dev.ctrl_handler = hdl_vid_cap;
@@ -1666,6 +1687,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap,
v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_gen, NULL);
v4l2_ctrl_add_handler(hdl_vid_out, hdl_user_aud, NULL);
v4l2_ctrl_add_handler(hdl_vid_out, hdl_streaming, NULL);
+ v4l2_ctrl_add_handler(hdl_vid_out, hdl_fb, NULL);
if (hdl_vid_out->error)
return hdl_vid_out->error;
dev->vid_out_dev.ctrl_handler = hdl_vid_out;
@@ -1725,4 +1747,5 @@ void vivid_free_controls(struct vivid_dev *dev)
v4l2_ctrl_handler_free(&dev->ctrl_hdl_streaming);
v4l2_ctrl_handler_free(&dev->ctrl_hdl_sdtv_cap);
v4l2_ctrl_handler_free(&dev->ctrl_hdl_loop_cap);
+ v4l2_ctrl_handler_free(&dev->ctrl_hdl_fb);
}
diff --git a/drivers/media/platform/vivid/vivid-radio-rx.c b/drivers/media/platform/vivid/vivid-radio-rx.c
index 71f3ebb7aecf..fcb7a9f015b6 100644
--- a/drivers/media/platform/vivid/vivid-radio-rx.c
+++ b/drivers/media/platform/vivid/vivid-radio-rx.c
@@ -38,9 +38,9 @@ ssize_t vivid_radio_rx_read(struct file *file, char __user *buf,
size_t size, loff_t *offset)
{
struct vivid_dev *dev = video_drvdata(file);
- struct timespec ts;
struct v4l2_rds_data *data = dev->rds_gen.data;
bool use_alternates;
+ ktime_t timestamp;
unsigned blk;
int perc;
int i;
@@ -64,17 +64,16 @@ ssize_t vivid_radio_rx_read(struct file *file, char __user *buf,
}
retry:
- ktime_get_ts(&ts);
- use_alternates = ts.tv_sec % 10 >= 5;
+ timestamp = ktime_sub(ktime_get(), dev->radio_rds_init_time);
+ blk = ktime_divns(timestamp, VIVID_RDS_NSEC_PER_BLK);
+ use_alternates = (blk % VIVID_RDS_GEN_BLOCKS) & 1;
+
if (dev->radio_rx_rds_last_block == 0 ||
dev->radio_rx_rds_use_alternates != use_alternates) {
dev->radio_rx_rds_use_alternates = use_alternates;
/* Re-init the RDS generator */
vivid_radio_rds_init(dev);
}
- ts = timespec_sub(ts, dev->radio_rds_init_ts);
- blk = ts.tv_sec * 100 + ts.tv_nsec / 10000000;
- blk = (blk * VIVID_RDS_GEN_BLOCKS) / 500;
if (blk >= dev->radio_rx_rds_last_block + VIVID_RDS_GEN_BLOCKS)
dev->radio_rx_rds_last_block = blk - VIVID_RDS_GEN_BLOCKS + 1;
diff --git a/drivers/media/platform/vivid/vivid-radio-tx.c b/drivers/media/platform/vivid/vivid-radio-tx.c
index f0917f4e7d8c..af4907a197a3 100644
--- a/drivers/media/platform/vivid/vivid-radio-tx.c
+++ b/drivers/media/platform/vivid/vivid-radio-tx.c
@@ -37,7 +37,7 @@ ssize_t vivid_radio_tx_write(struct file *file, const char __user *buf,
{
struct vivid_dev *dev = video_drvdata(file);
struct v4l2_rds_data *data = dev->rds_gen.data;
- struct timespec ts;
+ ktime_t timestamp;
unsigned blk;
int i;
@@ -58,10 +58,8 @@ ssize_t vivid_radio_tx_write(struct file *file, const char __user *buf,
dev->radio_tx_rds_owner = file->private_data;
retry:
- ktime_get_ts(&ts);
- ts = timespec_sub(ts, dev->radio_rds_init_ts);
- blk = ts.tv_sec * 100 + ts.tv_nsec / 10000000;
- blk = (blk * VIVID_RDS_GEN_BLOCKS) / 500;
+ timestamp = ktime_sub(ktime_get(), dev->radio_rds_init_time);
+ blk = ktime_divns(timestamp, VIVID_RDS_NSEC_PER_BLK);
if (blk - VIVID_RDS_GEN_BLOCKS >= dev->radio_tx_rds_last_block)
dev->radio_tx_rds_last_block = blk - VIVID_RDS_GEN_BLOCKS + 1;
diff --git a/drivers/media/platform/vivid/vivid-rds-gen.c b/drivers/media/platform/vivid/vivid-rds-gen.c
index 53c7777dc001..996e35e28d37 100644
--- a/drivers/media/platform/vivid/vivid-rds-gen.c
+++ b/drivers/media/platform/vivid/vivid-rds-gen.c
@@ -103,7 +103,7 @@ void vivid_rds_generate(struct vivid_rds_gen *rds)
* EN 50067:1998 to convert a UTC date to an RDS Modified
* Julian Day.
*/
- time_to_tm(get_seconds(), 0, &tm);
+ time64_to_tm(ktime_get_real_seconds(), 0, &tm);
l = tm.tm_mon <= 1;
date = 14956 + tm.tm_mday + ((tm.tm_year - l) * 1461) / 4 +
((tm.tm_mon + 2 + l * 12) * 306001) / 10000;
diff --git a/drivers/media/platform/vivid/vivid-rds-gen.h b/drivers/media/platform/vivid/vivid-rds-gen.h
index eff4bf552ed3..e55e3b22b7ca 100644
--- a/drivers/media/platform/vivid/vivid-rds-gen.h
+++ b/drivers/media/platform/vivid/vivid-rds-gen.h
@@ -29,6 +29,7 @@
#define VIVID_RDS_GEN_GROUPS 57
#define VIVID_RDS_GEN_BLKS_PER_GRP 4
#define VIVID_RDS_GEN_BLOCKS (VIVID_RDS_GEN_BLKS_PER_GRP * VIVID_RDS_GEN_GROUPS)
+#define VIVID_RDS_NSEC_PER_BLK (u32)(5ull * NSEC_PER_SEC / VIVID_RDS_GEN_BLOCKS)
struct vivid_rds_gen {
struct v4l2_rds_data data[VIVID_RDS_GEN_BLOCKS];
diff --git a/drivers/media/platform/vivid/vivid-vbi-gen.c b/drivers/media/platform/vivid/vivid-vbi-gen.c
index a2159de83d0b..02c79d7cedab 100644
--- a/drivers/media/platform/vivid/vivid-vbi-gen.c
+++ b/drivers/media/platform/vivid/vivid-vbi-gen.c
@@ -190,7 +190,7 @@ static void vivid_vbi_gen_set_time_of_day(u8 *packet)
struct tm tm;
u8 checksum, i;
- time_to_tm(get_seconds(), 0, &tm);
+ time64_to_tm(ktime_get_real_seconds(), 0, &tm);
packet[0] = calc_parity(0x07);
packet[1] = calc_parity(0x01);
packet[2] = calc_parity(0x40 | tm.tm_min);
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
index 01419455e545..0fbbcde19f0d 100644
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
@@ -93,11 +93,6 @@ static const struct v4l2_fract webcam_intervals[VIVID_WEBCAM_IVALS] = {
{ 1, 60 },
};
-static const struct v4l2_discrete_probe webcam_probe = {
- webcam_sizes,
- VIVID_WEBCAM_SIZES
-};
-
static int vid_cap_queue_setup(struct vb2_queue *vq,
unsigned *nbuffers, unsigned *nplanes,
unsigned sizes[], struct device *alloc_devs[])
@@ -578,7 +573,9 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
mp->field = vivid_field_cap(dev, mp->field);
if (vivid_is_webcam(dev)) {
const struct v4l2_frmsize_discrete *sz =
- v4l2_find_nearest_format(&webcam_probe, mp->width, mp->height);
+ v4l2_find_nearest_format(webcam_sizes,
+ VIVID_WEBCAM_SIZES,
+ mp->width, mp->height);
w = sz->width;
h = sz->height;
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 962e4c304076..eed9516e25e1 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -571,7 +571,13 @@ static int __maybe_unused vsp1_pm_suspend(struct device *dev)
{
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
- vsp1_pipelines_suspend(vsp1);
+ /*
+ * When used as part of a display pipeline, the VSP is stopped and
+ * restarted explicitly by the DU.
+ */
+ if (!vsp1->drm)
+ vsp1_pipelines_suspend(vsp1);
+
pm_runtime_force_suspend(vsp1->dev);
return 0;
@@ -582,7 +588,13 @@ static int __maybe_unused vsp1_pm_resume(struct device *dev)
struct vsp1_device *vsp1 = dev_get_drvdata(dev);
pm_runtime_force_resume(vsp1->dev);
- vsp1_pipelines_resume(vsp1);
+
+ /*
+ * When used as part of a display pipeline, the VSP is stopped and
+ * restarted explicitly by the DU.
+ */
+ if (!vsp1->drm)
+ vsp1_pipelines_resume(vsp1);
return 0;
}
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
index d881cf09876d..6bb28cd49dae 100644
--- a/drivers/media/platform/xilinx/xilinx-vipp.c
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -76,20 +76,16 @@ static int xvip_graph_build_one(struct xvip_composite_device *xdev,
struct xvip_graph_entity *ent;
struct v4l2_fwnode_link link;
struct device_node *ep = NULL;
- struct device_node *next;
int ret = 0;
dev_dbg(xdev->dev, "creating links for entity %s\n", local->name);
while (1) {
/* Get the next endpoint and parse its link. */
- next = of_graph_get_next_endpoint(entity->node, ep);
- if (next == NULL)
+ ep = of_graph_get_next_endpoint(entity->node, ep);
+ if (ep == NULL)
break;
- of_node_put(ep);
- ep = next;
-
dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep);
ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
@@ -200,7 +196,6 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
struct xvip_graph_entity *ent;
struct v4l2_fwnode_link link;
struct device_node *ep = NULL;
- struct device_node *next;
struct xvip_dma *dma;
int ret = 0;
@@ -208,13 +203,10 @@ static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
while (1) {
/* Get the next endpoint and parse its link. */
- next = of_graph_get_next_endpoint(node, ep);
- if (next == NULL)
+ ep = of_graph_get_next_endpoint(node, ep);
+ if (ep == NULL)
break;
- of_node_put(ep);
- ep = next;
-
dev_dbg(xdev->dev, "processing endpoint %pOF\n", ep);
ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
@@ -395,7 +387,7 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
entity->node = remote;
entity->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
- entity->asd.match.fwnode.fwnode = of_fwnode_handle(remote);
+ entity->asd.match.fwnode = of_fwnode_handle(remote);
list_add_tail(&entity->list, &xdev->entities);
xdev->num_subdevs++;
}
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index ea9308796741..5ef635e72e10 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -26,7 +26,7 @@
* Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
*/
-#include <linux/module.h> /* Modules */
+#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* msleep */
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index f445327f282d..9e12c6027359 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -15,7 +15,7 @@
* Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
*/
-#include <linux/module.h> /* Modules */
+#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index dba611003a00..af7c68b344d1 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -30,7 +30,7 @@
* Changed API to V4L2
*/
-#include <linux/module.h> /* Modules */
+#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
@@ -503,7 +503,7 @@ static __poll_t cadet_poll(struct file *file, struct poll_table_struct *wait)
static const struct v4l2_file_operations cadet_fops = {
.owner = THIS_MODULE,
.open = cadet_open,
- .release = cadet_release,
+ .release = cadet_release,
.read = cadet_read,
.unlocked_ioctl = video_ioctl2,
.poll = cadet_poll,
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index ddc12b16f77c..3ff4c4e1435f 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -22,7 +22,7 @@
* Fully tested with the Keene USB FM Transmitter and the v4l2-compliance tool.
*/
-#include <linux/module.h> /* Modules */
+#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
@@ -102,9 +102,9 @@ struct gemtek {
u32 bu2614data;
};
-#define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */
+#define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */
#define BU2614_PORT_BITS 3 /* P0..P2, Output port control data */
-#define BU2614_VOID_BITS 4 /* unused */
+#define BU2614_VOID_BITS 4 /* unused */
#define BU2614_FMES_BITS 1 /* CT, Frequency measurement beginning data */
#define BU2614_STDF_BITS 3 /* R0..R2, Standard frequency data */
#define BU2614_SWIN_BITS 1 /* S, Switch between FMIN / AMIN */
@@ -113,7 +113,7 @@ struct gemtek {
#define BU2614_FMUN_BITS 1 /* GT, Frequency measurement time & unlock */
#define BU2614_TEST_BITS 1 /* TS, Test data is input */
-#define BU2614_FREQ_SHIFT 0
+#define BU2614_FREQ_SHIFT 0
#define BU2614_PORT_SHIFT (BU2614_FREQ_BITS + BU2614_FREQ_SHIFT)
#define BU2614_VOID_SHIFT (BU2614_PORT_BITS + BU2614_PORT_SHIFT)
#define BU2614_FMES_SHIFT (BU2614_VOID_BITS + BU2614_VOID_SHIFT)
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index 3aa5ad391581..95f06f3b35dc 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -13,7 +13,7 @@
* anybody does please mail me.
*
* For the pdf file see:
- * http://www.nxp.com/acrobat_download2/expired_datasheets/TEA5757_5759_3.pdf
+ * http://www.nxp.com/acrobat_download2/expired_datasheets/TEA5757_5759_3.pdf
*
*
* CHANGES:
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index c9f59129af79..dc6c4f985911 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -31,22 +31,22 @@
* http://www.spinics.net/lists/linux-usb-devel/msg10109.html
*
* Version 0.01: First working version.
- * It's required to blacklist AverMedia USB Radio
- * in usbhid/hid-quirks.c
+ * It's required to blacklist AverMedia USB Radio
+ * in usbhid/hid-quirks.c
* Version 0.10: A lot of cleanups and fixes: unpluging the device,
- * few mutex locks were added, codinstyle issues, etc.
- * Added stereo support. Thanks to
- * Douglas Schilling Landgraf <dougsland@gmail.com> and
- * David Ellingsworth <david@identd.dyndns.org>
- * for discussion, help and support.
+ * few mutex locks were added, codinstyle issues, etc.
+ * Added stereo support. Thanks to
+ * Douglas Schilling Landgraf <dougsland@gmail.com> and
+ * David Ellingsworth <david@identd.dyndns.org>
+ * for discussion, help and support.
* Version 0.11: Converted to v4l2_device.
*
* Many things to do:
- * - Correct power management of device (suspend & resume)
- * - Add code for scanning and smooth tuning
- * - Add code for sensitivity value
- * - Correct mistakes
- * - In Japan another FREQ_MIN and FREQ_MAX
+ * - Correct power management of device (suspend & resume)
+ * - Add code for scanning and smooth tuning
+ * - Add code for sensitivity value
+ * - Correct mistakes
+ * - In Japan another FREQ_MIN and FREQ_MAX
*/
/* kernel includes */
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 09cfbc373c92..abeaedd8d437 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -12,7 +12,7 @@
* Fully tested with actual hardware and the v4l2-compliance tool.
*/
-#include <linux/module.h> /* Modules */
+#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index 28a89466cddc..fc4e63d36e4c 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -17,7 +17,7 @@
*/
#include <linux/kernel.h> /* __setup */
-#include <linux/module.h> /* Modules */
+#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
@@ -110,7 +110,7 @@ static inline int fmi_getsigstr(struct fmi *fmi)
val = fmi->mute ? 0x00 : 0x08; /* mute/unmute */
outb(val, fmi->io);
outb(val | 0x10, fmi->io);
- msleep(143); /* was schedule_timeout(HZ/7) */
+ msleep(143); /* was schedule_timeout(HZ/7) */
res = (int)inb(fmi->io + 1);
outb(val, fmi->io);
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index de79d5569c2a..7b07d42a9909 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -7,7 +7,7 @@
*/
#include <linux/delay.h>
-#include <linux/module.h> /* Modules */
+#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/slab.h>
#include <linux/ioport.h> /* request_region */
diff --git a/drivers/media/radio/radio-si476x.c b/drivers/media/radio/radio-si476x.c
index 49293dd707b9..bff9789ae9bc 100644
--- a/drivers/media/radio/radio-si476x.c
+++ b/drivers/media/radio/radio-si476x.c
@@ -759,7 +759,7 @@ static int si476x_radio_s_hw_freq_seek(struct file *file, void *priv,
{
int err;
enum si476x_func func;
- u32 rangelow, rangehigh;
+ u32 rangelow = seek->rangelow, rangehigh = seek->rangehigh;
struct si476x_radio *radio = video_drvdata(file);
if (file->f_flags & O_NONBLOCK)
@@ -771,23 +771,21 @@ static int si476x_radio_s_hw_freq_seek(struct file *file, void *priv,
si476x_core_lock(radio->core);
- if (!seek->rangelow) {
+ if (!rangelow) {
err = regmap_read(radio->core->regmap,
SI476X_PROP_SEEK_BAND_BOTTOM,
&rangelow);
- if (!err)
- rangelow = si476x_to_v4l2(radio->core, rangelow);
- else
+ if (err)
goto unlock;
+ rangelow = si476x_to_v4l2(radio->core, rangelow);
}
- if (!seek->rangehigh) {
+ if (!rangehigh) {
err = regmap_read(radio->core->regmap,
SI476X_PROP_SEEK_BAND_TOP,
&rangehigh);
- if (!err)
- rangehigh = si476x_to_v4l2(radio->core, rangehigh);
- else
+ if (err)
goto unlock;
+ rangehigh = si476x_to_v4l2(radio->core, rangehigh);
}
if (rangelow > rangehigh) {
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index bc7e69e7e32e..afb763256fd6 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -417,7 +417,7 @@ static const struct v4l2_ioctl_ops tea5764_ioctl_ops = {
static const struct video_device tea5764_radio_template = {
.name = "TEA5764 FM-Radio",
.fops = &tea5764_fops,
- .ioctl_ops = &tea5764_ioctl_ops,
+ .ioctl_ops = &tea5764_ioctl_ops,
.release = video_device_release_empty,
};
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index be10a802e3a9..4f116ea294fb 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -20,7 +20,7 @@
* Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
*/
-#include <linux/module.h> /* Modules */
+#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/videodev2.h> /* kernel radio structs */
@@ -45,12 +45,12 @@ static int radio_nr = -1;
module_param(radio_nr, int, 0444);
MODULE_PARM_DESC(radio_nr, "Radio device number");
-#define WRT_DIS 0x00
+#define WRT_DIS 0x00
#define CLK_OFF 0x00
#define IIC_DATA 0x01
#define IIC_CLK 0x02
#define DATA 0x04
-#define CLK_ON 0x08
+#define CLK_ON 0x08
#define WRT_EN 0x10
static struct radio_isa_card *terratec_alloc(void)
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 68fe9e5c7a70..5b477b7d6a66 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -33,18 +33,18 @@
* - switched from bit structs to bit masks
* - header file cleaned and integrated
* 2008-01-14 Tobias Lorenz <tobias.lorenz@gmx.net>
- * Version 1.0.2
- * - hex values are now lower case
- * - commented USB ID for ADS/Tech moved on todo list
- * - blacklisted si470x in hid-quirks.c
- * - rds buffer handling functions integrated into *_work, *_read
- * - rds_command in si470x_poll exchanged against simple retval
- * - check for firmware version 15
- * - code order and prototypes still remain the same
- * - spacing and bottom of band codes remain the same
+ * Version 1.0.2
+ * - hex values are now lower case
+ * - commented USB ID for ADS/Tech moved on todo list
+ * - blacklisted si470x in hid-quirks.c
+ * - rds buffer handling functions integrated into *_work, *_read
+ * - rds_command in si470x_poll exchanged against simple retval
+ * - check for firmware version 15
+ * - code order and prototypes still remain the same
+ * - spacing and bottom of band codes remain the same
* 2008-01-16 Tobias Lorenz <tobias.lorenz@gmx.net>
* Version 1.0.3
- * - code reordered to avoid function prototypes
+ * - code reordered to avoid function prototypes
* - switch/case defaults are now more user-friendly
* - unified comment style
* - applied all checkpatch.pl v1.12 suggestions
@@ -88,8 +88,8 @@
* - more safety checks, let si470x_get_freq return errno
* - vidioc behavior corrected according to v4l2 spec
* 2008-10-20 Alexey Klimov <klimov.linux@gmail.com>
- * - add support for KWorld USB FM Radio FM700
- * - blacklisted KWorld radio in hid-core.c and hid-ids.h
+ * - add support for KWorld USB FM Radio FM700
+ * - blacklisted KWorld radio in hid-core.c and hid-ids.h
* 2008-12-03 Mark Lord <mlord@pobox.com>
* - add support for DealExtreme USB Radio
* 2009-01-31 Bob Ross <pigiron@gmx.com>
diff --git a/drivers/media/radio/tea575x.c b/drivers/media/radio/tea575x.c
index 4dc2067bce14..7412fe1b10c6 100644
--- a/drivers/media/radio/tea575x.c
+++ b/drivers/media/radio/tea575x.c
@@ -498,7 +498,7 @@ static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
};
static const struct video_device tea575x_radio = {
- .ioctl_ops = &tea575x_ioctl_ops,
+ .ioctl_ops = &tea575x_ioctl_ops,
.release = video_device_release_empty,
};
diff --git a/drivers/media/radio/wl128x/fmdrv_common.h b/drivers/media/radio/wl128x/fmdrv_common.h
index 7f1514eb1c07..552e22ea6bf3 100644
--- a/drivers/media/radio/wl128x/fmdrv_common.h
+++ b/drivers/media/radio/wl128x/fmdrv_common.h
@@ -311,11 +311,11 @@ struct fm_event_msg_hdr {
#define FM_RDS_GROUP_TYPE_MASK_15B ((unsigned long)1<<31)
/* RX Alternate Frequency info */
-#define FM_RDS_MIN_AF 1
-#define FM_RDS_MAX_AF 204
-#define FM_RDS_MAX_AF_JAPAN 140
-#define FM_RDS_1_AF_FOLLOWS 225
-#define FM_RDS_25_AF_FOLLOWS 249
+#define FM_RDS_MIN_AF 1
+#define FM_RDS_MAX_AF 204
+#define FM_RDS_MAX_AF_JAPAN 140
+#define FM_RDS_1_AF_FOLLOWS 225
+#define FM_RDS_25_AF_FOLLOWS 249
/* RDS system type (RDS/RBDS) */
#define FM_RDS_SYSTEM_RDS 0
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index afb3456d4e20..f14ead5954e0 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -16,34 +16,21 @@ menuconfig RC_CORE
if RC_CORE
source "drivers/media/rc/keymaps/Kconfig"
-menuconfig RC_DECODERS
- bool "Remote controller decoders"
- depends on RC_CORE
- default y
-
-if RC_DECODERS
config LIRC
- tristate "LIRC interface driver"
+ bool "LIRC user interface"
depends on RC_CORE
-
---help---
- Enable this option to build the Linux Infrared Remote
- Control (LIRC) core device interface driver. The LIRC
- interface passes raw IR to and from userspace, where the
- LIRC daemon handles protocol decoding for IR reception and
- encoding for IR transmitting (aka "blasting").
+ Enable this option to enable the Linux Infrared Remote
+ Control user interface (e.g. /dev/lirc*). This interface
+ passes raw IR to and from userspace, which is needed for
+ IR transmitting (aka "blasting") and for the lirc daemon.
-config IR_LIRC_CODEC
- tristate "Enable IR to LIRC bridge"
+menuconfig RC_DECODERS
+ bool "Remote controller decoders"
depends on RC_CORE
- depends on LIRC
default y
- ---help---
- Enable this option to pass raw IR to and from userspace via
- the LIRC interface.
-
-
+if RC_DECODERS
config IR_NEC_DECODER
tristate "Enable IR raw decoder for the NEC protocol"
depends on RC_CORE
@@ -465,9 +452,9 @@ config IR_SERIAL_TRANSMITTER
Serial Port Transmitter support
config IR_SIR
- tristate "Built-in SIR IrDA port"
- depends on RC_CORE
- ---help---
+ tristate "Built-in SIR IrDA port"
+ depends on RC_CORE
+ ---help---
Say Y if you want to use a IrDA SIR port Transceivers.
To compile this driver as a module, choose M here: the module will
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 10026477a677..0e857816ac2d 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -1,10 +1,10 @@
# SPDX-License-Identifier: GPL-2.0
-rc-core-objs := rc-main.o rc-ir-raw.o
obj-y += keymaps/
obj-$(CONFIG_RC_CORE) += rc-core.o
-obj-$(CONFIG_LIRC) += lirc_dev.o
+rc-core-y := rc-main.o rc-ir-raw.o
+rc-core-$(CONFIG_LIRC) += lirc_dev.o
obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
@@ -13,7 +13,6 @@ obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
obj-$(CONFIG_IR_SANYO_DECODER) += ir-sanyo-decoder.o
obj-$(CONFIG_IR_SHARP_DECODER) += ir-sharp-decoder.o
obj-$(CONFIG_IR_MCE_KBD_DECODER) += ir-mce_kbd-decoder.o
-obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
obj-$(CONFIG_IR_XMP_DECODER) += ir-xmp-decoder.o
# stand-alone IR receivers/transmitters
diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c
index 30e24da67226..7daac8bab83b 100644
--- a/drivers/media/rc/iguanair.c
+++ b/drivers/media/rc/iguanair.c
@@ -347,26 +347,23 @@ 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;
- unsigned i, size, periods, bytes;
+ unsigned int i, size, p, periods;
int rc;
mutex_lock(&ir->lock);
/* convert from us to carrier periods */
- for (i = space = size = 0; i < count; i++) {
+ for (i = 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) {
- rc = -EINVAL;
- goto out;
- }
while (periods) {
- unsigned p = min(periods, 127u);
- ir->packet->payload[size++] = p | space;
+ p = min(periods, 127u);
+ if (size >= ir->bufsize) {
+ rc = -EINVAL;
+ goto out;
+ }
+ ir->packet->payload[size++] = p | ((i & 1) ? 0x80 : 0);
periods -= p;
}
- space ^= 0x80;
}
ir->packet->header.start = 0;
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index eb943e862515..950d068ba806 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -27,6 +27,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel.h>
+#include <linux/ktime.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -37,7 +38,6 @@
#include <linux/usb/input.h>
#include <media/rc-core.h>
-#include <linux/time.h>
#include <linux/timer.h>
#define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
@@ -1168,29 +1168,6 @@ out:
return retval;
}
-static inline int tv2int(const struct timeval *a, const struct timeval *b)
-{
- int usecs = 0;
- int sec = 0;
-
- if (b->tv_usec > a->tv_usec) {
- usecs = 1000000;
- sec--;
- }
-
- usecs += a->tv_usec - b->tv_usec;
-
- sec += a->tv_sec - b->tv_sec;
- sec *= 1000;
- usecs /= 1000;
- sec += usecs;
-
- if (sec < 0)
- sec = 1000;
-
- return sec;
-}
-
/*
* The directional pad behaves a bit differently, depending on whether this is
* one of the older ffdc devices or a newer device. Newer devices appear to
@@ -1201,16 +1178,16 @@ static inline int tv2int(const struct timeval *a, const struct timeval *b)
*/
static int stabilize(int a, int b, u16 timeout, u16 threshold)
{
- struct timeval ct;
- static struct timeval prev_time = {0, 0};
- static struct timeval hit_time = {0, 0};
+ ktime_t ct;
+ static ktime_t prev_time;
+ static ktime_t hit_time;
static int x, y, prev_result, hits;
int result = 0;
- int msec, msec_hit;
+ long msec, msec_hit;
- do_gettimeofday(&ct);
- msec = tv2int(&ct, &prev_time);
- msec_hit = tv2int(&ct, &hit_time);
+ ct = ktime_get();
+ msec = ktime_ms_delta(ct, prev_time);
+ msec_hit = ktime_ms_delta(ct, hit_time);
if (msec > 100) {
x = 0;
@@ -1688,9 +1665,9 @@ static void imon_incoming_scancode(struct imon_context *ictx,
u32 kc;
u64 scancode;
int press_type = 0;
- int msec;
- struct timeval t;
- static struct timeval prev_time = { 0, 0 };
+ long msec;
+ ktime_t t;
+ static ktime_t prev_time;
u8 ktype;
/* filter out junk data on the older 0xffdc imon devices */
@@ -1783,10 +1760,10 @@ static void imon_incoming_scancode(struct imon_context *ictx,
/* Only panel type events left to process now */
spin_lock_irqsave(&ictx->kc_lock, flags);
- do_gettimeofday(&t);
+ t = ktime_get();
/* KEY_MUTE repeats from knob need to be suppressed */
if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) {
- msec = tv2int(&t, &prev_time);
+ msec = ktime_ms_delta(t, prev_time);
if (msec < ictx->idev->rep[REP_DELAY]) {
spin_unlock_irqrestore(&ictx->kc_lock, flags);
return;
@@ -1956,6 +1933,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
break;
/* iMON VFD, iMON IR */
case 0x24:
+ case 0x30:
case 0x85:
dev_info(ictx->dev, "0xffdc iMON VFD, iMON IR");
detected_display_type = IMON_DISPLAY_TYPE_VFD;
@@ -1974,6 +1952,11 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
detected_display_type = IMON_DISPLAY_TYPE_LCD;
allowed_protos = RC_PROTO_BIT_RC6_MCE;
break;
+ /* no display, iMON IR */
+ case 0x26:
+ dev_info(ictx->dev, "0xffdc iMON Inside, iMON IR");
+ ictx->display_supported = false;
+ break;
default:
dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR");
detected_display_type = IMON_DISPLAY_TYPE_VFD;
diff --git a/drivers/media/rc/ir-jvc-decoder.c b/drivers/media/rc/ir-jvc-decoder.c
index 22c8aee3df4f..c03c776cfa54 100644
--- a/drivers/media/rc/ir-jvc-decoder.c
+++ b/drivers/media/rc/ir-jvc-decoder.c
@@ -212,6 +212,7 @@ static struct ir_raw_handler jvc_handler = {
.protocols = RC_PROTO_BIT_JVC,
.decode = ir_jvc_decode,
.encode = ir_jvc_encode,
+ .carrier = 38000,
};
static int __init ir_jvc_decode_init(void)
diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c
deleted file mode 100644
index 4fd4521693d9..000000000000
--- a/drivers/media/rc/ir-lirc-codec.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/* ir-lirc-codec.c - rc-core to classic lirc interface bridge
- *
- * Copyright (C) 2010 by Jarod Wilson <jarod@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 version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/module.h>
-#include <media/lirc.h>
-#include <media/lirc_dev.h>
-#include <media/rc-core.h>
-#include "rc-core-priv.h"
-
-#define LIRCBUF_SIZE 256
-
-/**
- * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
- * lircd userspace daemon for decoding.
- * @dev: the struct rc_dev descriptor of the device
- * @ev: the struct ir_raw_event descriptor of the pulse/space
- *
- * This function returns -EINVAL if the lirc interfaces aren't wired up.
- */
-static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev)
-{
- struct lirc_codec *lirc = &dev->raw->lirc;
- int sample;
-
- if (!dev->raw->lirc.ldev || !dev->raw->lirc.ldev->buf)
- return -EINVAL;
-
- /* Packet start */
- if (ev.reset) {
- /* Userspace expects a long space event before the start of
- * the signal to use as a sync. This may be done with repeat
- * packets and normal samples. But if a reset has been sent
- * then we assume that a long time has passed, so we send a
- * space with the maximum time value. */
- sample = LIRC_SPACE(LIRC_VALUE_MASK);
- IR_dprintk(2, "delivering reset sync space to lirc_dev\n");
-
- /* Carrier reports */
- } else if (ev.carrier_report) {
- sample = LIRC_FREQUENCY(ev.carrier);
- IR_dprintk(2, "carrier report (freq: %d)\n", sample);
-
- /* Packet end */
- } else if (ev.timeout) {
-
- if (lirc->gap)
- return 0;
-
- lirc->gap_start = ktime_get();
- lirc->gap = true;
- lirc->gap_duration = ev.duration;
-
- if (!lirc->send_timeout_reports)
- return 0;
-
- sample = LIRC_TIMEOUT(ev.duration / 1000);
- IR_dprintk(2, "timeout report (duration: %d)\n", sample);
-
- /* Normal sample */
- } else {
-
- if (lirc->gap) {
- int gap_sample;
-
- lirc->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
- lirc->gap_start));
-
- /* Convert to ms and cap by LIRC_VALUE_MASK */
- do_div(lirc->gap_duration, 1000);
- lirc->gap_duration = min(lirc->gap_duration,
- (u64)LIRC_VALUE_MASK);
-
- gap_sample = LIRC_SPACE(lirc->gap_duration);
- lirc_buffer_write(dev->raw->lirc.ldev->buf,
- (unsigned char *)&gap_sample);
- lirc->gap = false;
- }
-
- sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
- LIRC_SPACE(ev.duration / 1000);
- IR_dprintk(2, "delivering %uus %s to lirc_dev\n",
- TO_US(ev.duration), TO_STR(ev.pulse));
- }
-
- lirc_buffer_write(dev->raw->lirc.ldev->buf,
- (unsigned char *) &sample);
- wake_up(&dev->raw->lirc.ldev->buf->wait_poll);
-
- return 0;
-}
-
-static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
- size_t n, loff_t *ppos)
-{
- struct lirc_codec *lirc;
- struct rc_dev *dev;
- unsigned int *txbuf; /* buffer with values to transmit */
- 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)
- return -EFAULT;
-
- if (n < sizeof(unsigned) || n % sizeof(unsigned))
- return -EINVAL;
-
- count = n / sizeof(unsigned);
- if (count > LIRCBUF_SIZE || count % 2 == 0)
- return -EINVAL;
-
- txbuf = memdup_user(buf, n);
- if (IS_ERR(txbuf))
- return PTR_ERR(txbuf);
-
- dev = lirc->dev;
- if (!dev) {
- ret = -EFAULT;
- goto out;
- }
-
- if (!dev->tx_ir) {
- ret = -EINVAL;
- goto out;
- }
-
- for (i = 0; i < count; i++) {
- if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) {
- ret = -EINVAL;
- goto out;
- }
-
- duration += txbuf[i];
- }
-
- ret = dev->tx_ir(dev, txbuf, count);
- if (ret < 0)
- goto out;
-
- for (duration = i = 0; i < ret; i++)
- duration += txbuf[i];
-
- 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);
- return ret;
-}
-
-static long ir_lirc_ioctl(struct file *filep, unsigned int cmd,
- unsigned long arg)
-{
- struct lirc_codec *lirc;
- struct rc_dev *dev;
- u32 __user *argp = (u32 __user *)(arg);
- int ret = 0;
- __u32 val = 0, tmp;
-
- lirc = lirc_get_pdata(filep);
- if (!lirc)
- return -EFAULT;
-
- dev = lirc->dev;
- if (!dev)
- return -EFAULT;
-
- if (_IOC_DIR(cmd) & _IOC_WRITE) {
- ret = get_user(val, argp);
- if (ret)
- return ret;
- }
-
- switch (cmd) {
-
- /* legacy support */
- case LIRC_GET_SEND_MODE:
- if (!dev->tx_ir)
- return -ENOTTY;
-
- val = LIRC_MODE_PULSE;
- break;
-
- case LIRC_SET_SEND_MODE:
- if (!dev->tx_ir)
- return -ENOTTY;
-
- if (val != LIRC_MODE_PULSE)
- return -EINVAL;
- return 0;
-
- /* TX settings */
- case LIRC_SET_TRANSMITTER_MASK:
- if (!dev->s_tx_mask)
- return -ENOTTY;
-
- return dev->s_tx_mask(dev, val);
-
- case LIRC_SET_SEND_CARRIER:
- if (!dev->s_tx_carrier)
- return -ENOTTY;
-
- return dev->s_tx_carrier(dev, val);
-
- case LIRC_SET_SEND_DUTY_CYCLE:
- if (!dev->s_tx_duty_cycle)
- return -ENOTTY;
-
- if (val <= 0 || val >= 100)
- return -EINVAL;
-
- return dev->s_tx_duty_cycle(dev, val);
-
- /* RX settings */
- case LIRC_SET_REC_CARRIER:
- if (!dev->s_rx_carrier_range)
- return -ENOTTY;
-
- if (val <= 0)
- return -EINVAL;
-
- return dev->s_rx_carrier_range(dev,
- dev->raw->lirc.carrier_low,
- val);
-
- case LIRC_SET_REC_CARRIER_RANGE:
- if (!dev->s_rx_carrier_range)
- return -ENOTTY;
-
- if (val <= 0)
- return -EINVAL;
-
- dev->raw->lirc.carrier_low = val;
- return 0;
-
- case LIRC_GET_REC_RESOLUTION:
- if (!dev->rx_resolution)
- return -ENOTTY;
-
- val = dev->rx_resolution / 1000;
- break;
-
- case LIRC_SET_WIDEBAND_RECEIVER:
- if (!dev->s_learning_mode)
- return -ENOTTY;
-
- return dev->s_learning_mode(dev, !!val);
-
- case LIRC_SET_MEASURE_CARRIER_MODE:
- if (!dev->s_carrier_report)
- return -ENOTTY;
-
- return dev->s_carrier_report(dev, !!val);
-
- /* Generic timeout support */
- case LIRC_GET_MIN_TIMEOUT:
- if (!dev->max_timeout)
- return -ENOTTY;
- val = DIV_ROUND_UP(dev->min_timeout, 1000);
- break;
-
- case LIRC_GET_MAX_TIMEOUT:
- if (!dev->max_timeout)
- return -ENOTTY;
- val = dev->max_timeout / 1000;
- break;
-
- case LIRC_SET_REC_TIMEOUT:
- if (!dev->max_timeout)
- return -ENOTTY;
-
- /* Check for multiply overflow */
- if (val > U32_MAX / 1000)
- return -EINVAL;
-
- tmp = val * 1000;
-
- if (tmp < dev->min_timeout || tmp > dev->max_timeout)
- return -EINVAL;
-
- if (dev->s_timeout)
- ret = dev->s_timeout(dev, tmp);
- if (!ret)
- dev->timeout = tmp;
- break;
-
- case LIRC_SET_REC_TIMEOUT_REPORTS:
- if (!dev->timeout)
- return -ENOTTY;
-
- lirc->send_timeout_reports = !!val;
- break;
-
- default:
- return lirc_dev_fop_ioctl(filep, cmd, arg);
- }
-
- if (_IOC_DIR(cmd) & _IOC_READ)
- ret = put_user(val, argp);
-
- return ret;
-}
-
-static const struct file_operations lirc_fops = {
- .owner = THIS_MODULE,
- .write = ir_lirc_transmit_ir,
- .unlocked_ioctl = ir_lirc_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = ir_lirc_ioctl,
-#endif
- .read = lirc_dev_fop_read,
- .poll = lirc_dev_fop_poll,
- .open = lirc_dev_fop_open,
- .release = lirc_dev_fop_close,
- .llseek = no_llseek,
-};
-
-static int ir_lirc_register(struct rc_dev *dev)
-{
- struct lirc_dev *ldev;
- int rc = -ENOMEM;
- unsigned long features = 0;
-
- ldev = lirc_allocate_device();
- if (!ldev)
- return rc;
-
- if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
- features |= LIRC_CAN_REC_MODE2;
- if (dev->rx_resolution)
- features |= LIRC_CAN_GET_REC_RESOLUTION;
- }
-
- if (dev->tx_ir) {
- features |= LIRC_CAN_SEND_PULSE;
- if (dev->s_tx_mask)
- features |= LIRC_CAN_SET_TRANSMITTER_MASK;
- if (dev->s_tx_carrier)
- features |= LIRC_CAN_SET_SEND_CARRIER;
- if (dev->s_tx_duty_cycle)
- features |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
- }
-
- if (dev->s_rx_carrier_range)
- features |= LIRC_CAN_SET_REC_CARRIER |
- LIRC_CAN_SET_REC_CARRIER_RANGE;
-
- if (dev->s_learning_mode)
- features |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
-
- if (dev->s_carrier_report)
- features |= LIRC_CAN_MEASURE_CARRIER;
-
- if (dev->max_timeout)
- features |= LIRC_CAN_SET_REC_TIMEOUT;
-
- snprintf(ldev->name, sizeof(ldev->name), "ir-lirc-codec (%s)",
- dev->driver_name);
- ldev->features = features;
- ldev->data = &dev->raw->lirc;
- ldev->buf = NULL;
- ldev->code_length = sizeof(struct ir_raw_event) * 8;
- ldev->chunk_size = sizeof(int);
- ldev->buffer_size = LIRCBUF_SIZE;
- ldev->fops = &lirc_fops;
- ldev->dev.parent = &dev->dev;
- ldev->rdev = dev;
- ldev->owner = THIS_MODULE;
-
- rc = lirc_register_device(ldev);
- if (rc < 0)
- goto out;
-
- dev->raw->lirc.ldev = ldev;
- dev->raw->lirc.dev = dev;
- return 0;
-
-out:
- lirc_free_device(ldev);
- return rc;
-}
-
-static int ir_lirc_unregister(struct rc_dev *dev)
-{
- struct lirc_codec *lirc = &dev->raw->lirc;
-
- lirc_unregister_device(lirc->ldev);
- lirc->ldev = NULL;
-
- return 0;
-}
-
-static struct ir_raw_handler lirc_handler = {
- .protocols = 0,
- .decode = ir_lirc_decode,
- .raw_register = ir_lirc_register,
- .raw_unregister = ir_lirc_unregister,
-};
-
-static int __init ir_lirc_codec_init(void)
-{
- ir_raw_handler_register(&lirc_handler);
-
- printk(KERN_INFO "IR LIRC bridge handler initialized\n");
- return 0;
-}
-
-static void __exit ir_lirc_codec_exit(void)
-{
- ir_raw_handler_unregister(&lirc_handler);
-}
-
-module_init(ir_lirc_codec_init);
-module_exit(ir_lirc_codec_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
-MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
-MODULE_DESCRIPTION("LIRC IR handler bridge");
diff --git a/drivers/media/rc/ir-mce_kbd-decoder.c b/drivers/media/rc/ir-mce_kbd-decoder.c
index 69d6264d54e6..2c3df02e05ff 100644
--- a/drivers/media/rc/ir-mce_kbd-decoder.c
+++ b/drivers/media/rc/ir-mce_kbd-decoder.c
@@ -215,6 +215,7 @@ static int ir_mce_kbd_decode(struct rc_dev *dev, struct ir_raw_event ev)
struct mce_kbd_dec *data = &dev->raw->mce_kbd;
u32 scancode;
unsigned long delay;
+ struct lirc_scancode lsc = {};
if (!is_timing_event(ev)) {
if (ev.reset)
@@ -326,18 +327,22 @@ again:
mod_timer(&data->rx_timeout, jiffies + delay);
/* Pass data to keyboard buffer parser */
ir_mce_kbd_process_keyboard_data(data->idev, scancode);
+ lsc.rc_proto = RC_PROTO_MCIR2_KBD;
break;
case MCIR2_MOUSE_NBITS:
scancode = data->body & 0x1fffff;
IR_dprintk(1, "mouse data 0x%06x\n", scancode);
/* Pass data to mouse buffer parser */
ir_mce_kbd_process_mouse_data(data->idev, scancode);
+ lsc.rc_proto = RC_PROTO_MCIR2_MSE;
break;
default:
IR_dprintk(1, "not keyboard or mouse data\n");
goto out;
}
+ lsc.scancode = scancode;
+ ir_lirc_scancode_event(dev, &lsc);
data->state = STATE_INACTIVE;
input_event(data->idev, EV_MSC, MSC_SCAN, scancode);
input_sync(data->idev);
@@ -358,9 +363,6 @@ static int ir_mce_kbd_register(struct rc_dev *dev)
struct input_dev *idev;
int i, ret;
- if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
- return 0;
-
idev = input_allocate_device();
if (!idev)
return -ENOMEM;
@@ -415,9 +417,6 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev)
struct mce_kbd_dec *mce_kbd = &dev->raw->mce_kbd;
struct input_dev *idev = mce_kbd->idev;
- if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
- return 0;
-
del_timer_sync(&mce_kbd->rx_timeout);
input_unregister_device(idev);
@@ -425,7 +424,7 @@ static int ir_mce_kbd_unregister(struct rc_dev *dev)
}
static const struct ir_raw_timings_manchester ir_mce_kbd_timings = {
- .leader = MCIR2_PREFIX_PULSE,
+ .leader_pulse = MCIR2_PREFIX_PULSE,
.invert = 1,
.clock = MCIR2_UNIT,
.trailer_space = MCIR2_UNIT * 10,
@@ -453,11 +452,11 @@ static int ir_mce_kbd_encode(enum rc_proto protocol, u32 scancode,
if (protocol == RC_PROTO_MCIR2_KBD) {
raw = scancode |
((u64)MCIR2_KEYBOARD_HEADER << MCIR2_KEYBOARD_NBITS);
- len = MCIR2_KEYBOARD_NBITS + MCIR2_HEADER_NBITS + 1;
+ len = MCIR2_KEYBOARD_NBITS + MCIR2_HEADER_NBITS;
} else {
raw = scancode |
((u64)MCIR2_MOUSE_HEADER << MCIR2_MOUSE_NBITS);
- len = MCIR2_MOUSE_NBITS + MCIR2_HEADER_NBITS + 1;
+ len = MCIR2_MOUSE_NBITS + MCIR2_HEADER_NBITS;
}
ret = ir_raw_gen_manchester(&e, max, &ir_mce_kbd_timings, len, raw);
@@ -473,6 +472,7 @@ static struct ir_raw_handler mce_kbd_handler = {
.encode = ir_mce_kbd_encode,
.raw_register = ir_mce_kbd_register,
.raw_unregister = ir_mce_kbd_unregister,
+ .carrier = 36000,
};
static int __init ir_mce_kbd_decode_init(void)
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 6880c190dcd2..31d7bafe7bda 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -1,16 +1,7 @@
-/* ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
- *
- * Copyright (C) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0
+// ir-nec-decoder.c - handle NEC IR Pulse/Space protocol
+//
+// Copyright (C) 2010 by Mauro Carvalho Chehab
#include <linux/bitrev.h>
#include <linux/module.h>
@@ -263,6 +254,7 @@ static struct ir_raw_handler nec_handler = {
RC_PROTO_BIT_NEC32,
.decode = ir_nec_decode,
.encode = ir_nec_encode,
+ .carrier = 38000,
};
static int __init ir_nec_decode_init(void)
@@ -281,7 +273,7 @@ static void __exit ir_nec_decode_exit(void)
module_init(ir_nec_decode_init);
module_exit(ir_nec_decode_exit);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mauro Carvalho Chehab");
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
MODULE_DESCRIPTION("NEC IR protocol decoder");
diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c
index 1292f534de43..11a28f8772da 100644
--- a/drivers/media/rc/ir-rc5-decoder.c
+++ b/drivers/media/rc/ir-rc5-decoder.c
@@ -1,17 +1,8 @@
-/* ir-rc5-decoder.c - decoder for RC5(x) and StreamZap protocols
- *
- * Copyright (C) 2010 by Mauro Carvalho Chehab
- * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// ir-rc5-decoder.c - decoder for RC5(x) and StreamZap protocols
+//
+// Copyright (C) 2010 by Mauro Carvalho Chehab
+// Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
/*
* This decoder handles the 14 bit RC5 protocol, 15 bit "StreamZap" protocol
@@ -182,16 +173,14 @@ out:
}
static const struct ir_raw_timings_manchester ir_rc5_timings = {
- .leader = RC5_UNIT,
- .pulse_space_start = 0,
+ .leader_pulse = RC5_UNIT,
.clock = RC5_UNIT,
.trailer_space = RC5_UNIT * 10,
};
static const struct ir_raw_timings_manchester ir_rc5x_timings[2] = {
{
- .leader = RC5_UNIT,
- .pulse_space_start = 0,
+ .leader_pulse = RC5_UNIT,
.clock = RC5_UNIT,
.trailer_space = RC5X_SPACE,
},
@@ -202,8 +191,7 @@ static const struct ir_raw_timings_manchester ir_rc5x_timings[2] = {
};
static const struct ir_raw_timings_manchester ir_rc5_sz_timings = {
- .leader = RC5_UNIT,
- .pulse_space_start = 0,
+ .leader_pulse = RC5_UNIT,
.clock = RC5_UNIT,
.trailer_space = RC5_UNIT * 10,
};
@@ -237,9 +225,9 @@ static int ir_rc5_encode(enum rc_proto protocol, u32 scancode,
/* encode data */
data = !commandx << 12 | system << 6 | command;
- /* Modulate the data */
+ /* First bit is encoded by leader_pulse */
ret = ir_raw_gen_manchester(&e, max, &ir_rc5_timings,
- RC5_NBITS, data);
+ RC5_NBITS - 1, data);
if (ret < 0)
return ret;
} else if (protocol == RC_PROTO_RC5X_20) {
@@ -252,10 +240,11 @@ static int ir_rc5_encode(enum rc_proto protocol, u32 scancode,
/* encode data */
data = commandx << 18 | system << 12 | command << 6 | xdata;
- /* Modulate the data */
+ /* First bit is encoded by leader_pulse */
pre_space_data = data >> (RC5X_NBITS - CHECK_RC5X_NBITS);
ret = ir_raw_gen_manchester(&e, max, &ir_rc5x_timings[0],
- CHECK_RC5X_NBITS, pre_space_data);
+ CHECK_RC5X_NBITS - 1,
+ pre_space_data);
if (ret < 0)
return ret;
ret = ir_raw_gen_manchester(&e, max - (e - events),
@@ -266,8 +255,10 @@ static int ir_rc5_encode(enum rc_proto protocol, u32 scancode,
return ret;
} else if (protocol == RC_PROTO_RC5_SZ) {
/* RC5-SZ scancode is raw enough for Manchester as it is */
+ /* First bit is encoded by leader_pulse */
ret = ir_raw_gen_manchester(&e, max, &ir_rc5_sz_timings,
- RC5_SZ_NBITS, scancode & 0x2fff);
+ RC5_SZ_NBITS - 1,
+ scancode & 0x2fff);
if (ret < 0)
return ret;
} else {
@@ -282,6 +273,7 @@ static struct ir_raw_handler rc5_handler = {
RC_PROTO_BIT_RC5_SZ,
.decode = ir_rc5_decode,
.encode = ir_rc5_encode,
+ .carrier = 36000,
};
static int __init ir_rc5_decode_init(void)
@@ -300,7 +292,7 @@ static void __exit ir_rc5_decode_exit(void)
module_init(ir_rc5_decode_init);
module_exit(ir_rc5_decode_exit);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mauro Carvalho Chehab and Jarod Wilson");
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
MODULE_DESCRIPTION("RC5(x/sz) IR protocol decoder");
diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c
index 5d0d2fe3b7a7..55bb19bbd4e9 100644
--- a/drivers/media/rc/ir-rc6-decoder.c
+++ b/drivers/media/rc/ir-rc6-decoder.c
@@ -288,13 +288,8 @@ out:
static const struct ir_raw_timings_manchester ir_rc6_timings[4] = {
{
- .leader = RC6_PREFIX_PULSE,
- .pulse_space_start = 0,
- .clock = RC6_UNIT,
- .invert = 1,
- .trailer_space = RC6_PREFIX_SPACE,
- },
- {
+ .leader_pulse = RC6_PREFIX_PULSE,
+ .leader_space = RC6_PREFIX_SPACE,
.clock = RC6_UNIT,
.invert = 1,
},
@@ -329,27 +324,22 @@ static int ir_rc6_encode(enum rc_proto protocol, u32 scancode,
struct ir_raw_event *e = events;
if (protocol == RC_PROTO_RC6_0) {
- /* Modulate the preamble */
- ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0);
- if (ret < 0)
- return ret;
-
/* Modulate the header (Start Bit & Mode-0) */
ret = ir_raw_gen_manchester(&e, max - (e - events),
- &ir_rc6_timings[1],
+ &ir_rc6_timings[0],
RC6_HEADER_NBITS, (1 << 3));
if (ret < 0)
return ret;
/* Modulate Trailer Bit */
ret = ir_raw_gen_manchester(&e, max - (e - events),
- &ir_rc6_timings[2], 1, 0);
+ &ir_rc6_timings[1], 1, 0);
if (ret < 0)
return ret;
/* Modulate rest of the data */
ret = ir_raw_gen_manchester(&e, max - (e - events),
- &ir_rc6_timings[3], RC6_0_NBITS,
+ &ir_rc6_timings[2], RC6_0_NBITS,
scancode);
if (ret < 0)
return ret;
@@ -372,27 +362,22 @@ static int ir_rc6_encode(enum rc_proto protocol, u32 scancode,
return -EINVAL;
}
- /* Modulate the preamble */
- ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0);
- if (ret < 0)
- return ret;
-
/* Modulate the header (Start Bit & Header-version 6 */
ret = ir_raw_gen_manchester(&e, max - (e - events),
- &ir_rc6_timings[1],
+ &ir_rc6_timings[0],
RC6_HEADER_NBITS, (1 << 3 | 6));
if (ret < 0)
return ret;
/* Modulate Trailer Bit */
ret = ir_raw_gen_manchester(&e, max - (e - events),
- &ir_rc6_timings[2], 1, 0);
+ &ir_rc6_timings[1], 1, 0);
if (ret < 0)
return ret;
/* Modulate rest of the data */
ret = ir_raw_gen_manchester(&e, max - (e - events),
- &ir_rc6_timings[3],
+ &ir_rc6_timings[2],
bits,
scancode);
if (ret < 0)
@@ -408,6 +393,7 @@ static struct ir_raw_handler rc6_handler = {
RC_PROTO_BIT_RC6_MCE,
.decode = ir_rc6_decode,
.encode = ir_rc6_encode,
+ .carrier = 36000,
};
static int __init ir_rc6_decode_init(void)
diff --git a/drivers/media/rc/ir-sanyo-decoder.c b/drivers/media/rc/ir-sanyo-decoder.c
index d94e07b02f3b..ded39cdfc6ef 100644
--- a/drivers/media/rc/ir-sanyo-decoder.c
+++ b/drivers/media/rc/ir-sanyo-decoder.c
@@ -1,25 +1,16 @@
-/* ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol
- *
- * Copyright (C) 2011 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * 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.
- *
- * This protocol uses the NEC protocol timings. However, data is formatted as:
- * 13 bits Custom Code
- * 13 bits NOT(Custom Code)
- * 8 bits Key data
- * 8 bits NOT(Key data)
- *
- * According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
- * Information for this protocol is available at the Sanyo LC7461 datasheet.
- */
+// SPDX-License-Identifier: GPL-2.0
+// ir-sanyo-decoder.c - handle SANYO IR Pulse/Space protocol
+//
+// Copyright (C) 2011 by Mauro Carvalho Chehab
+//
+// This protocol uses the NEC protocol timings. However, data is formatted as:
+// 13 bits Custom Code
+// 13 bits NOT(Custom Code)
+// 8 bits Key data
+// 8 bits NOT(Key data)
+//
+// According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
+// Information for this protocol is available at the Sanyo LC7461 datasheet.
#include <linux/module.h>
#include <linux/bitrev.h>
@@ -218,6 +209,7 @@ static struct ir_raw_handler sanyo_handler = {
.protocols = RC_PROTO_BIT_SANYO,
.decode = ir_sanyo_decode,
.encode = ir_sanyo_encode,
+ .carrier = 38000,
};
static int __init ir_sanyo_decode_init(void)
@@ -236,7 +228,7 @@ static void __exit ir_sanyo_decode_exit(void)
module_init(ir_sanyo_decode_init);
module_exit(ir_sanyo_decode_exit);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mauro Carvalho Chehab");
MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
MODULE_DESCRIPTION("SANYO IR protocol decoder");
diff --git a/drivers/media/rc/ir-sharp-decoder.c b/drivers/media/rc/ir-sharp-decoder.c
index 7140dd6160ee..df296991906c 100644
--- a/drivers/media/rc/ir-sharp-decoder.c
+++ b/drivers/media/rc/ir-sharp-decoder.c
@@ -226,6 +226,7 @@ static struct ir_raw_handler sharp_handler = {
.protocols = RC_PROTO_BIT_SHARP,
.decode = ir_sharp_decode,
.encode = ir_sharp_encode,
+ .carrier = 38000,
};
static int __init ir_sharp_decode_init(void)
diff --git a/drivers/media/rc/ir-sony-decoder.c b/drivers/media/rc/ir-sony-decoder.c
index a47ced763031..e4bcff21c025 100644
--- a/drivers/media/rc/ir-sony-decoder.c
+++ b/drivers/media/rc/ir-sony-decoder.c
@@ -221,6 +221,7 @@ static struct ir_raw_handler sony_handler = {
RC_PROTO_BIT_SONY20,
.decode = ir_sony_decode,
.encode = ir_sony_encode,
+ .carrier = 40000,
};
static int __init ir_sony_decode_init(void)
diff --git a/drivers/media/rc/ir-spi.c b/drivers/media/rc/ir-spi.c
index 29ed0638cb74..a32a84ae2d0b 100644
--- a/drivers/media/rc/ir-spi.c
+++ b/drivers/media/rc/ir-spi.c
@@ -1,13 +1,8 @@
-/*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * Author: Andi Shyti <andi.shyti@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.
- *
- * SPI driven IR LED device driver
- */
+// SPDX-License-Identifier: GPL-2.0
+// SPI driven IR LED device driver
+//
+// Copyright (c) 2016 Samsung Electronics Co., Ltd.
+// Copyright (c) Andi Shyti <andi.shyti@samsung.com>
#include <linux/delay.h>
#include <linux/fs.h>
diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
index 2d303c2cee3b..732687ce0637 100644
--- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
+++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
@@ -1,14 +1,9 @@
-/* adstech-dvb-t-pci.h - Keytable for adstech_dvb_t_pci Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// adstech-dvb-t-pci.h - Keytable for adstech_dvb_t_pci Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-apac-viewcomp.c b/drivers/media/rc/keymaps/rc-apac-viewcomp.c
index 65bc8957d9c3..af2e7fdc7b85 100644
--- a/drivers/media/rc/keymaps/rc-apac-viewcomp.c
+++ b/drivers/media/rc/keymaps/rc-apac-viewcomp.c
@@ -1,14 +1,9 @@
-/* apac-viewcomp.h - Keytable for apac_viewcomp Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// apac-viewcomp.h - Keytable for apac_viewcomp Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-asus-pc39.c b/drivers/media/rc/keymaps/rc-asus-pc39.c
index 530e1d1158d1..13a935c3ac59 100644
--- a/drivers/media/rc/keymaps/rc-asus-pc39.c
+++ b/drivers/media/rc/keymaps/rc-asus-pc39.c
@@ -1,14 +1,9 @@
-/* asus-pc39.h - Keytable for asus_pc39 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// asus-pc39.h - Keytable for asus_pc39 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-asus-ps3-100.c b/drivers/media/rc/keymaps/rc-asus-ps3-100.c
index c91ba332984c..7f836fcc68ac 100644
--- a/drivers/media/rc/keymaps/rc-asus-ps3-100.c
+++ b/drivers/media/rc/keymaps/rc-asus-ps3-100.c
@@ -1,14 +1,9 @@
-/* asus-ps3-100.h - Keytable for asus_ps3_100 Remote Controller
- *
- * Copyright (c) 2012 by Mauro Carvalho Chehab
- *
- * Based on a previous patch from Remi Schwartz <remi.schwartz@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.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// asus-ps3-100.h - Keytable for asus_ps3_100 Remote Controller
+//
+// Copyright (c) 2012 by Mauro Carvalho Chehab
+//
+// Based on a previous patch from Remi Schwartz <remi.schwartz@gmail.com>
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
index 11b4bdd2392b..b4b7932c0c5a 100644
--- a/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
+++ b/drivers/media/rc/keymaps/rc-ati-tv-wonder-hd-600.c
@@ -1,14 +1,9 @@
-/* ati-tv-wonder-hd-600.h - Keytable for ati_tv_wonder_hd_600 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// ati-tv-wonder-hd-600.h - Keytable for ati_tv_wonder_hd_600 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avermedia-a16d.c b/drivers/media/rc/keymaps/rc-avermedia-a16d.c
index 510dc90ebf49..5549c043cfe4 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-a16d.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-a16d.c
@@ -1,14 +1,9 @@
-/* avermedia-a16d.h - Keytable for avermedia_a16d Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avermedia-a16d.h - Keytable for avermedia_a16d Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
index 4bbc1e68d1b8..74edcd82e685 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
@@ -1,14 +1,9 @@
-/* avermedia-cardbus.h - Keytable for avermedia_cardbus Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avermedia-cardbus.h - Keytable for avermedia_cardbus Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
index f6b8547dbad3..796184160a48 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
@@ -1,14 +1,9 @@
-/* avermedia-dvbt.h - Keytable for avermedia_dvbt Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avermedia-dvbt.h - Keytable for avermedia_dvbt Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
index 6d5a73b7ccec..f6977df1a75b 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
@@ -1,13 +1,8 @@
-/* avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- * Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avermedia-m135a.c - Keytable for Avermedia M135A Remote Controllers
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
+// Copyright (c) 2010 by Herton Ronaldo Krzesinski <herton@mandriva.com.br>
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avermedia.c b/drivers/media/rc/keymaps/rc-avermedia.c
index 6503f11c7df5..631ff52564f0 100644
--- a/drivers/media/rc/keymaps/rc-avermedia.c
+++ b/drivers/media/rc/keymaps/rc-avermedia.c
@@ -1,14 +1,9 @@
-/* avermedia.h - Keytable for avermedia Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avermedia.h - Keytable for avermedia Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-avertv-303.c b/drivers/media/rc/keymaps/rc-avertv-303.c
index fbdd7ada57ce..47ca8b7ea532 100644
--- a/drivers/media/rc/keymaps/rc-avertv-303.c
+++ b/drivers/media/rc/keymaps/rc-avertv-303.c
@@ -1,14 +1,9 @@
-/* avertv-303.h - Keytable for avertv_303 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// avertv-303.h - Keytable for avertv_303 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c
index d256743be998..e73057945bd1 100644
--- a/drivers/media/rc/keymaps/rc-behold-columbus.c
+++ b/drivers/media/rc/keymaps/rc-behold-columbus.c
@@ -1,14 +1,9 @@
-/* behold-columbus.h - Keytable for behold_columbus Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// behold-columbus.h - Keytable for behold_columbus Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
@@ -35,12 +30,12 @@ static struct rc_map_table behold_columbus[] = {
/* 0x01 0x02 0x03 0x0D *
* 1 2 3 Stereo *
- * *
+ * *
* 0x04 0x05 0x06 0x19 *
* 4 5 6 Snapshot *
- * *
+ * *
* 0x07 0x08 0x09 0x10 *
- * 7 8 9 Zoom *
+ * 7 8 9 Zoom *
* */
{ 0x01, KEY_1 },
{ 0x02, KEY_2 },
diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c
index 93dc795adc67..9b1b57e3c875 100644
--- a/drivers/media/rc/keymaps/rc-behold.c
+++ b/drivers/media/rc/keymaps/rc-behold.c
@@ -1,14 +1,9 @@
-/* behold.h - Keytable for behold Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// behold.h - Keytable for behold Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c
index 81ea1424d9e5..56f051af6154 100644
--- a/drivers/media/rc/keymaps/rc-budget-ci-old.c
+++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c
@@ -1,14 +1,9 @@
-/* budget-ci-old.h - Keytable for budget_ci_old Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// budget-ci-old.h - Keytable for budget_ci_old Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-cinergy-1400.c b/drivers/media/rc/keymaps/rc-cinergy-1400.c
index bcb96b3dda85..dacb13c53bb4 100644
--- a/drivers/media/rc/keymaps/rc-cinergy-1400.c
+++ b/drivers/media/rc/keymaps/rc-cinergy-1400.c
@@ -1,14 +1,9 @@
-/* cinergy-1400.h - Keytable for cinergy_1400 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// cinergy-1400.h - Keytable for cinergy_1400 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c
index fd56c402aae5..6ab2e51b764d 100644
--- a/drivers/media/rc/keymaps/rc-cinergy.c
+++ b/drivers/media/rc/keymaps/rc-cinergy.c
@@ -1,14 +1,9 @@
-/* cinergy.h - Keytable for cinergy Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// cinergy.h - Keytable for cinergy Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-dib0700-nec.c b/drivers/media/rc/keymaps/rc-dib0700-nec.c
index 1b4df106b7b5..4ee801acb089 100644
--- a/drivers/media/rc/keymaps/rc-dib0700-nec.c
+++ b/drivers/media/rc/keymaps/rc-dib0700-nec.c
@@ -1,19 +1,14 @@
-/* rc-dvb0700-big.c - Keytable for devices in dvb0700
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * TODO: This table is a real mess, as it merges RC codes from several
- * devices into a big table. It also has both RC-5 and NEC codes inside.
- * It should be broken into small tables, and the protocols should properly
- * be identificated.
- *
- * The table were imported from dib0700_devices.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// rc-dvb0700-big.c - Keytable for devices in dvb0700
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
+//
+// TODO: This table is a real mess, as it merges RC codes from several
+// devices into a big table. It also has both RC-5 and NEC codes inside.
+// It should be broken into small tables, and the protocols should properly
+// be identificated.
+//
+// The table were imported from dib0700_devices.c.
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-dib0700-rc5.c b/drivers/media/rc/keymaps/rc-dib0700-rc5.c
index b0f8151bb824..ef4085a0fda3 100644
--- a/drivers/media/rc/keymaps/rc-dib0700-rc5.c
+++ b/drivers/media/rc/keymaps/rc-dib0700-rc5.c
@@ -1,19 +1,14 @@
-/* rc-dvb0700-big.c - Keytable for devices in dvb0700
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * TODO: This table is a real mess, as it merges RC codes from several
- * devices into a big table. It also has both RC-5 and NEC codes inside.
- * It should be broken into small tables, and the protocols should properly
- * be identificated.
- *
- * The table were imported from dib0700_devices.c.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// rc-dvb0700-big.c - Keytable for devices in dvb0700
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
+//
+// TODO: This table is a real mess, as it merges RC codes from several
+// devices into a big table. It also has both RC-5 and NEC codes inside.
+// It should be broken into small tables, and the protocols should properly
+// be identificated.
+//
+// The table were imported from dib0700_devices.c.
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-dm1105-nec.c b/drivers/media/rc/keymaps/rc-dm1105-nec.c
index c353445d10ed..d853cd9a0936 100644
--- a/drivers/media/rc/keymaps/rc-dm1105-nec.c
+++ b/drivers/media/rc/keymaps/rc-dm1105-nec.c
@@ -1,14 +1,9 @@
-/* dm1105-nec.h - Keytable for dm1105_nec Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// dm1105-nec.h - Keytable for dm1105_nec Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
index 5bafd5b70f5e..cdc1d8c990cb 100644
--- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
@@ -1,14 +1,9 @@
-/* dntv-live-dvb-t.h - Keytable for dntv_live_dvb_t Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// dntv-live-dvb-t.h - Keytable for dntv_live_dvb_t Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
index 360167c8829b..38e1d1b837da 100644
--- a/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvbt-pro.c
@@ -1,14 +1,9 @@
-/* dntv-live-dvbt-pro.h - Keytable for dntv_live_dvbt_pro Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// dntv-live-dvbt-pro.h - Keytable for dntv_live_dvbt_pro Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-em-terratec.c b/drivers/media/rc/keymaps/rc-em-terratec.c
index 18e1a2679c20..cbbba21484fb 100644
--- a/drivers/media/rc/keymaps/rc-em-terratec.c
+++ b/drivers/media/rc/keymaps/rc-em-terratec.c
@@ -1,14 +1,9 @@
-/* em-terratec.h - Keytable for em_terratec Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// em-terratec.h - Keytable for em_terratec Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
index 72ffd5cb0108..e4e78c1f4123 100644
--- a/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv-fm53.c
@@ -1,14 +1,9 @@
-/* encore-enltv-fm53.h - Keytable for encore_enltv_fm53 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// encore-enltv-fm53.h - Keytable for encore_enltv_fm53 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c
index e0381e7aa964..5b4e832d5fac 100644
--- a/drivers/media/rc/keymaps/rc-encore-enltv.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv.c
@@ -1,14 +1,9 @@
-/* encore-enltv.h - Keytable for encore_enltv Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// encore-enltv.h - Keytable for encore_enltv Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c
index e9b0bfba319c..c3d4437a6fda 100644
--- a/drivers/media/rc/keymaps/rc-encore-enltv2.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c
@@ -1,14 +1,9 @@
-/* encore-enltv2.h - Keytable for encore_enltv2 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// encore-enltv2.h - Keytable for encore_enltv2 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-evga-indtube.c b/drivers/media/rc/keymaps/rc-evga-indtube.c
index b77c5e908668..f4398444330b 100644
--- a/drivers/media/rc/keymaps/rc-evga-indtube.c
+++ b/drivers/media/rc/keymaps/rc-evga-indtube.c
@@ -1,14 +1,9 @@
-/* evga-indtube.h - Keytable for evga_indtube Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// evga-indtube.h - Keytable for evga_indtube Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-eztv.c b/drivers/media/rc/keymaps/rc-eztv.c
index 5013b3b2aa93..0e481d51fcb5 100644
--- a/drivers/media/rc/keymaps/rc-eztv.c
+++ b/drivers/media/rc/keymaps/rc-eztv.c
@@ -1,14 +1,9 @@
-/* eztv.h - Keytable for eztv Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// eztv.h - Keytable for eztv Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c
index 418b32521273..45940d7c92d0 100644
--- a/drivers/media/rc/keymaps/rc-flydvb.c
+++ b/drivers/media/rc/keymaps/rc-flydvb.c
@@ -1,14 +1,9 @@
-/* flydvb.h - Keytable for flydvb Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// flydvb.h - Keytable for flydvb Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-flyvideo.c b/drivers/media/rc/keymaps/rc-flyvideo.c
index 93fb87ecf061..b2d4e4c7b192 100644
--- a/drivers/media/rc/keymaps/rc-flyvideo.c
+++ b/drivers/media/rc/keymaps/rc-flyvideo.c
@@ -1,14 +1,9 @@
-/* flyvideo.h - Keytable for flyvideo Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// flyvideo.h - Keytable for flyvideo Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
index 9ed3f749262b..1c63fc7d4576 100644
--- a/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
+++ b/drivers/media/rc/keymaps/rc-fusionhdtv-mce.c
@@ -1,14 +1,9 @@
-/* fusionhdtv-mce.h - Keytable for fusionhdtv_mce Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// fusionhdtv-mce.h - Keytable for fusionhdtv_mce Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c
index 3443b721d092..4a0a9786914f 100644
--- a/drivers/media/rc/keymaps/rc-gadmei-rm008z.c
+++ b/drivers/media/rc/keymaps/rc-gadmei-rm008z.c
@@ -1,14 +1,9 @@
-/* gadmei-rm008z.h - Keytable for gadmei_rm008z Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// gadmei-rm008z.h - Keytable for gadmei_rm008z Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
index d140e8d45bcc..cc876a85cc31 100644
--- a/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
+++ b/drivers/media/rc/keymaps/rc-genius-tvgo-a11mce.c
@@ -1,14 +1,9 @@
-/* genius-tvgo-a11mce.h - Keytable for genius_tvgo_a11mce Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// genius-tvgo-a11mce.h - Keytable for genius_tvgo_a11mce Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-gotview7135.c b/drivers/media/rc/keymaps/rc-gotview7135.c
index 51230fbb52ba..6b94bd39d977 100644
--- a/drivers/media/rc/keymaps/rc-gotview7135.c
+++ b/drivers/media/rc/keymaps/rc-gotview7135.c
@@ -1,14 +1,9 @@
-/* gotview7135.h - Keytable for gotview7135 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// gotview7135.h - Keytable for gotview7135 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-hauppauge.c b/drivers/media/rc/keymaps/rc-hauppauge.c
index 890164b68d64..582aa9012443 100644
--- a/drivers/media/rc/keymaps/rc-hauppauge.c
+++ b/drivers/media/rc/keymaps/rc-hauppauge.c
@@ -1,20 +1,15 @@
-/* rc-hauppauge.c - Keytable for Hauppauge Remote Controllers
- *
- * keymap imported from ir-keymaps.c
- *
- * This map currently contains the code for four different RCs:
- * - New Hauppauge Gray;
- * - Old Hauppauge Gray (with a golden screen for media keys);
- * - Hauppauge Black;
- * - DSR-0112 remote bundled with Haupauge MiniStick.
- *
- * Copyright (c) 2010-2011 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// rc-hauppauge.c - Keytable for Hauppauge Remote Controllers
+//
+// keymap imported from ir-keymaps.c
+//
+// This map currently contains the code for four different RCs:
+// - New Hauppauge Gray;
+// - Old Hauppauge Gray (with a golden screen for media keys);
+// - Hauppauge Black;
+// - DSR-0112 remote bundled with Haupauge MiniStick.
+//
+// Copyright (c) 2010-2011 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c
index 8cf87a15c4f2..6ced43458f2a 100644
--- a/drivers/media/rc/keymaps/rc-iodata-bctv7e.c
+++ b/drivers/media/rc/keymaps/rc-iodata-bctv7e.c
@@ -1,14 +1,9 @@
-/* iodata-bctv7e.h - Keytable for iodata_bctv7e Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// iodata-bctv7e.h - Keytable for iodata_bctv7e Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-kaiomy.c b/drivers/media/rc/keymaps/rc-kaiomy.c
index e791f1e1b43b..f0f88df18606 100644
--- a/drivers/media/rc/keymaps/rc-kaiomy.c
+++ b/drivers/media/rc/keymaps/rc-kaiomy.c
@@ -1,14 +1,9 @@
-/* kaiomy.h - Keytable for kaiomy Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// kaiomy.h - Keytable for kaiomy Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c
index 71dce0138f0e..ed0e0586dea2 100644
--- a/drivers/media/rc/keymaps/rc-kworld-315u.c
+++ b/drivers/media/rc/keymaps/rc-kworld-315u.c
@@ -1,14 +1,9 @@
-/* kworld-315u.h - Keytable for kworld_315u Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// kworld-315u.h - Keytable for kworld_315u Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
index e0322ed16c94..453e04377de7 100644
--- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
@@ -1,14 +1,9 @@
-/* kworld-plus-tv-analog.h - Keytable for kworld_plus_tv_analog Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// kworld-plus-tv-analog.h - Keytable for kworld_plus_tv_analog Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-manli.c b/drivers/media/rc/keymaps/rc-manli.c
index da566902a4dd..29c9feaf413b 100644
--- a/drivers/media/rc/keymaps/rc-manli.c
+++ b/drivers/media/rc/keymaps/rc-manli.c
@@ -1,14 +1,9 @@
-/* manli.h - Keytable for manli Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// manli.h - Keytable for manli Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
index dfa0ed1d7667..78cf2c286083 100644
--- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
@@ -1,14 +1,9 @@
-/* msi-tvanywhere-plus.h - Keytable for msi_tvanywhere_plus Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// msi-tvanywhere-plus.h - Keytable for msi_tvanywhere_plus Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c
index 2111816a3f59..359a57be3a66 100644
--- a/drivers/media/rc/keymaps/rc-msi-tvanywhere.c
+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere.c
@@ -1,14 +1,9 @@
-/* msi-tvanywhere.h - Keytable for msi_tvanywhere Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// msi-tvanywhere.h - Keytable for msi_tvanywhere Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c
index 109b6e1a8b1a..17d7c1b324da 100644
--- a/drivers/media/rc/keymaps/rc-nebula.c
+++ b/drivers/media/rc/keymaps/rc-nebula.c
@@ -1,14 +1,9 @@
-/* nebula.h - Keytable for nebula Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// nebula.h - Keytable for nebula Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
index bb2d3a2962c0..76beef44a8d7 100644
--- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
+++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c
@@ -1,14 +1,9 @@
-/* nec-terratec-cinergy-xs.h - Keytable for nec_terratec_cinergy_xs Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// nec-terratec-cinergy-xs.h - Keytable for nec_terratec_cinergy_xs Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c
index cd25df336749..3765705c5549 100644
--- a/drivers/media/rc/keymaps/rc-norwood.c
+++ b/drivers/media/rc/keymaps/rc-norwood.c
@@ -1,14 +1,9 @@
-/* norwood.h - Keytable for norwood Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// norwood.h - Keytable for norwood Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-npgtech.c b/drivers/media/rc/keymaps/rc-npgtech.c
index 140bbc20a764..abaf7f6d4cb7 100644
--- a/drivers/media/rc/keymaps/rc-npgtech.c
+++ b/drivers/media/rc/keymaps/rc-npgtech.c
@@ -1,14 +1,9 @@
-/* npgtech.h - Keytable for npgtech Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// npgtech.h - Keytable for npgtech Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c
index 52b4558b7bd0..e3462c5c8984 100644
--- a/drivers/media/rc/keymaps/rc-pctv-sedna.c
+++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c
@@ -1,14 +1,9 @@
-/* pctv-sedna.h - Keytable for pctv_sedna Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pctv-sedna.h - Keytable for pctv_sedna Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pinnacle-color.c b/drivers/media/rc/keymaps/rc-pinnacle-color.c
index 973c9c34e304..63c2851e9dfe 100644
--- a/drivers/media/rc/keymaps/rc-pinnacle-color.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-color.c
@@ -1,14 +1,9 @@
-/* pinnacle-color.h - Keytable for pinnacle_color Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pinnacle-color.h - Keytable for pinnacle_color Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pinnacle-grey.c b/drivers/media/rc/keymaps/rc-pinnacle-grey.c
index 22e44b0d2a93..31794d4180db 100644
--- a/drivers/media/rc/keymaps/rc-pinnacle-grey.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-grey.c
@@ -1,14 +1,9 @@
-/* pinnacle-grey.h - Keytable for pinnacle_grey Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pinnacle-grey.h - Keytable for pinnacle_grey Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
index 186dcf8e0491..876aeb6e1d9c 100644
--- a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
+++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
@@ -1,14 +1,9 @@
-/* pinnacle-pctv-hd.h - Keytable for pinnacle_pctv_hd Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pinnacle-pctv-hd.h - Keytable for pinnacle_pctv_hd Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pixelview-002t.c b/drivers/media/rc/keymaps/rc-pixelview-002t.c
index b235ada2e28f..4ed85f61d0ee 100644
--- a/drivers/media/rc/keymaps/rc-pixelview-002t.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-002t.c
@@ -1,14 +1,9 @@
-/* rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
index 453d52d663fe..6ded64b732a5 100644
--- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
@@ -1,14 +1,9 @@
-/* rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// rc-pixelview-mk12.h - Keytable for pixelview Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c
index ef97095ec8f1..791130f108ff 100644
--- a/drivers/media/rc/keymaps/rc-pixelview-new.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-new.c
@@ -1,14 +1,9 @@
-/* pixelview-new.h - Keytable for pixelview_new Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pixelview-new.h - Keytable for pixelview_new Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c
index cfd8f80d3617..988919735165 100644
--- a/drivers/media/rc/keymaps/rc-pixelview.c
+++ b/drivers/media/rc/keymaps/rc-pixelview.c
@@ -1,14 +1,9 @@
-/* pixelview.h - Keytable for pixelview Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pixelview.h - Keytable for pixelview Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c
index b63f82bcf29a..4988e71c524c 100644
--- a/drivers/media/rc/keymaps/rc-powercolor-real-angel.c
+++ b/drivers/media/rc/keymaps/rc-powercolor-real-angel.c
@@ -1,14 +1,9 @@
-/* powercolor-real-angel.h - Keytable for powercolor_real_angel Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// powercolor-real-angel.h - Keytable for powercolor_real_angel Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-proteus-2309.c b/drivers/media/rc/keymaps/rc-proteus-2309.c
index be34c517e4e1..d2c13d0e7bff 100644
--- a/drivers/media/rc/keymaps/rc-proteus-2309.c
+++ b/drivers/media/rc/keymaps/rc-proteus-2309.c
@@ -1,14 +1,9 @@
-/* proteus-2309.h - Keytable for proteus_2309 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// proteus-2309.h - Keytable for proteus_2309 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-purpletv.c b/drivers/media/rc/keymaps/rc-purpletv.c
index 84c40b97ee00..c8011f4d96ea 100644
--- a/drivers/media/rc/keymaps/rc-purpletv.c
+++ b/drivers/media/rc/keymaps/rc-purpletv.c
@@ -1,14 +1,9 @@
-/* purpletv.h - Keytable for purpletv Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// purpletv.h - Keytable for purpletv Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c
index be190ddebfc4..5235ee899c30 100644
--- a/drivers/media/rc/keymaps/rc-pv951.c
+++ b/drivers/media/rc/keymaps/rc-pv951.c
@@ -1,14 +1,9 @@
-/* pv951.h - Keytable for pv951 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// pv951.h - Keytable for pv951 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
index 957fa21747ea..1cf786649675 100644
--- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
+++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
@@ -1,14 +1,9 @@
-/* real-audio-220-32-keys.h - Keytable for real_audio_220_32_keys Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// real-audio-220-32-keys.h - Keytable for real_audio_220_32_keys Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-tbs-nec.c b/drivers/media/rc/keymaps/rc-tbs-nec.c
index 05facc043272..42766cb877c3 100644
--- a/drivers/media/rc/keymaps/rc-tbs-nec.c
+++ b/drivers/media/rc/keymaps/rc-tbs-nec.c
@@ -1,14 +1,9 @@
-/* tbs-nec.h - Keytable for tbs_nec Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// tbs-nec.h - Keytable for tbs_nec Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
index 3d0f6f7e5bea..6cf53a56bce4 100644
--- a/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
+++ b/drivers/media/rc/keymaps/rc-terratec-cinergy-xs.c
@@ -1,14 +1,9 @@
-/* terratec-cinergy-xs.h - Keytable for terratec_cinergy_xs Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// terratec-cinergy-xs.h - Keytable for terratec_cinergy_xs Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-tevii-nec.c b/drivers/media/rc/keymaps/rc-tevii-nec.c
index 31f8a0fd1f2c..58fcc72f528e 100644
--- a/drivers/media/rc/keymaps/rc-tevii-nec.c
+++ b/drivers/media/rc/keymaps/rc-tevii-nec.c
@@ -1,14 +1,9 @@
-/* tevii-nec.h - Keytable for tevii_nec Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// tevii-nec.h - Keytable for tevii_nec Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-tt-1500.c b/drivers/media/rc/keymaps/rc-tt-1500.c
index 374c230705d2..52f239d2c025 100644
--- a/drivers/media/rc/keymaps/rc-tt-1500.c
+++ b/drivers/media/rc/keymaps/rc-tt-1500.c
@@ -1,14 +1,9 @@
-/* tt-1500.h - Keytable for tt_1500 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// tt-1500.h - Keytable for tt_1500 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-videomate-s350.c b/drivers/media/rc/keymaps/rc-videomate-s350.c
index b4f103269872..e4d4dff06a24 100644
--- a/drivers/media/rc/keymaps/rc-videomate-s350.c
+++ b/drivers/media/rc/keymaps/rc-videomate-s350.c
@@ -1,14 +1,9 @@
-/* videomate-s350.h - Keytable for videomate_s350 Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// videomate-s350.h - Keytable for videomate_s350 Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
index c431fdf44057..7c4890944407 100644
--- a/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
+++ b/drivers/media/rc/keymaps/rc-videomate-tv-pvr.c
@@ -1,14 +1,9 @@
-/* videomate-tv-pvr.h - Keytable for videomate_tv_pvr Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// videomate-tv-pvr.h - Keytable for videomate_tv_pvr Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
index 5a437e61bd5d..e443192dbe14 100644
--- a/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
+++ b/drivers/media/rc/keymaps/rc-winfast-usbii-deluxe.c
@@ -1,14 +1,9 @@
-/* winfast-usbii-deluxe.h - Keytable for winfast_usbii_deluxe Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// winfast-usbii-deluxe.h - Keytable for winfast_usbii_deluxe Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
@@ -42,7 +37,7 @@ static struct rc_map_table winfast_usbii_deluxe[] = {
{ 0x60, KEY_CHANNELDOWN}, /* CHANNELDOWN */
{ 0x61, KEY_LAST}, /* LAST CHANNEL (RECALL) */
- { 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */
+ { 0x72, KEY_VIDEO}, /* INPUT MODES (TV/FM) */
{ 0x70, KEY_POWER2}, /* TV ON/OFF */
diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c
index 53685d1f9a47..ee7f4c349fd6 100644
--- a/drivers/media/rc/keymaps/rc-winfast.c
+++ b/drivers/media/rc/keymaps/rc-winfast.c
@@ -1,14 +1,9 @@
-/* winfast.h - Keytable for winfast Remote Controller
- *
- * keymap imported from ir-keymaps.c
- *
- * Copyright (c) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// winfast.h - Keytable for winfast Remote Controller
+//
+// keymap imported from ir-keymaps.c
+//
+// Copyright (c) 2010 by Mauro Carvalho Chehab
#include <media/rc-map.h>
#include <linux/module.h>
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index aab53641838b..b3544988586e 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -18,466 +18,775 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
-#include <linux/sched/signal.h>
-#include <linux/ioctl.h>
-#include <linux/poll.h>
#include <linux/mutex.h>
#include <linux/device.h>
-#include <linux/cdev.h>
#include <linux/idr.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
-#include <media/rc-core.h>
-#include <media/lirc.h>
-#include <media/lirc_dev.h>
+#include "rc-core-priv.h"
+#include <uapi/linux/lirc.h>
-#define LOGHEAD "lirc_dev (%s[%d]): "
+#define LIRCBUF_SIZE 256
static dev_t lirc_base_dev;
/* Used to keep track of allocated lirc devices */
-#define LIRC_MAX_DEVICES 256
static DEFINE_IDA(lirc_ida);
/* Only used for sysfs but defined to void otherwise */
static struct class *lirc_class;
-static void lirc_release_device(struct device *ld)
+/**
+ * ir_lirc_raw_event() - Send raw IR data to lirc to be relayed to userspace
+ *
+ * @dev: the struct rc_dev descriptor of the device
+ * @ev: the struct ir_raw_event descriptor of the pulse/space
+ */
+void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev)
{
- struct lirc_dev *d = container_of(ld, struct lirc_dev, dev);
-
- put_device(d->dev.parent);
+ unsigned long flags;
+ struct lirc_fh *fh;
+ int sample;
- if (d->buf_internal) {
- lirc_buffer_free(d->buf);
- kfree(d->buf);
- d->buf = NULL;
- }
- kfree(d);
- module_put(THIS_MODULE);
-}
+ /* Packet start */
+ if (ev.reset) {
+ /*
+ * Userspace expects a long space event before the start of
+ * the signal to use as a sync. This may be done with repeat
+ * packets and normal samples. But if a reset has been sent
+ * then we assume that a long time has passed, so we send a
+ * space with the maximum time value.
+ */
+ sample = LIRC_SPACE(LIRC_VALUE_MASK);
+ IR_dprintk(2, "delivering reset sync space to lirc_dev\n");
-static int lirc_allocate_buffer(struct lirc_dev *d)
-{
- int err;
+ /* Carrier reports */
+ } else if (ev.carrier_report) {
+ sample = LIRC_FREQUENCY(ev.carrier);
+ IR_dprintk(2, "carrier report (freq: %d)\n", sample);
- if (d->buf) {
- d->buf_internal = false;
- return 0;
- }
+ /* Packet end */
+ } else if (ev.timeout) {
+ if (dev->gap)
+ return;
- d->buf = kmalloc(sizeof(*d->buf), GFP_KERNEL);
- if (!d->buf)
- return -ENOMEM;
+ dev->gap_start = ktime_get();
+ dev->gap = true;
+ dev->gap_duration = ev.duration;
- err = lirc_buffer_init(d->buf, d->chunk_size, d->buffer_size);
- if (err) {
- kfree(d->buf);
- d->buf = NULL;
- return err;
- }
+ sample = LIRC_TIMEOUT(ev.duration / 1000);
+ IR_dprintk(2, "timeout report (duration: %d)\n", sample);
- d->buf_internal = true;
- return 0;
-}
+ /* Normal sample */
+ } else {
+ if (dev->gap) {
+ dev->gap_duration += ktime_to_ns(ktime_sub(ktime_get(),
+ dev->gap_start));
+
+ /* Convert to ms and cap by LIRC_VALUE_MASK */
+ do_div(dev->gap_duration, 1000);
+ dev->gap_duration = min_t(u64, dev->gap_duration,
+ LIRC_VALUE_MASK);
+
+ spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+ list_for_each_entry(fh, &dev->lirc_fh, list)
+ kfifo_put(&fh->rawir,
+ LIRC_SPACE(dev->gap_duration));
+ spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
+ dev->gap = false;
+ }
-struct lirc_dev *
-lirc_allocate_device(void)
-{
- struct lirc_dev *d;
-
- d = kzalloc(sizeof(*d), GFP_KERNEL);
- if (d) {
- mutex_init(&d->mutex);
- device_initialize(&d->dev);
- d->dev.class = lirc_class;
- d->dev.release = lirc_release_device;
- __module_get(THIS_MODULE);
+ sample = ev.pulse ? LIRC_PULSE(ev.duration / 1000) :
+ LIRC_SPACE(ev.duration / 1000);
+ IR_dprintk(2, "delivering %uus %s to lirc_dev\n",
+ TO_US(ev.duration), TO_STR(ev.pulse));
}
- return d;
-}
-EXPORT_SYMBOL(lirc_allocate_device);
-
-void lirc_free_device(struct lirc_dev *d)
-{
- if (!d)
- return;
-
- put_device(&d->dev);
+ spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+ list_for_each_entry(fh, &dev->lirc_fh, list) {
+ if (LIRC_IS_TIMEOUT(sample) && !fh->send_timeout_reports)
+ continue;
+ if (kfifo_put(&fh->rawir, sample))
+ wake_up_poll(&fh->wait_poll, POLLIN | POLLRDNORM);
+ }
+ spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
}
-EXPORT_SYMBOL(lirc_free_device);
-int lirc_register_device(struct lirc_dev *d)
+/**
+ * ir_lirc_scancode_event() - Send scancode data to lirc to be relayed to
+ * userspace. This can be called in atomic context.
+ * @dev: the struct rc_dev descriptor of the device
+ * @lsc: the struct lirc_scancode describing the decoded scancode
+ */
+void ir_lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc)
{
- int minor;
- int err;
+ unsigned long flags;
+ struct lirc_fh *fh;
- if (!d) {
- pr_err("driver pointer must be not NULL!\n");
- return -EBADRQC;
- }
+ lsc->timestamp = ktime_get_ns();
- if (!d->dev.parent) {
- pr_err("dev parent pointer not filled in!\n");
- return -EINVAL;
+ spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+ list_for_each_entry(fh, &dev->lirc_fh, list) {
+ if (kfifo_put(&fh->scancodes, *lsc))
+ wake_up_poll(&fh->wait_poll, POLLIN | POLLRDNORM);
}
+ spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ir_lirc_scancode_event);
- if (!d->fops) {
- pr_err("fops pointer not filled in!\n");
- return -EINVAL;
- }
+static int ir_lirc_open(struct inode *inode, struct file *file)
+{
+ struct rc_dev *dev = container_of(inode->i_cdev, struct rc_dev,
+ lirc_cdev);
+ struct lirc_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+ unsigned long flags;
+ int retval;
- if (!d->buf && d->chunk_size < 1) {
- pr_err("chunk_size must be set!\n");
- return -EINVAL;
- }
+ if (!fh)
+ return -ENOMEM;
- if (!d->buf && d->buffer_size < 1) {
- pr_err("buffer_size must be set!\n");
- return -EINVAL;
- }
+ get_device(&dev->dev);
- if (d->code_length < 1 || d->code_length > (BUFLEN * 8)) {
- dev_err(&d->dev, "code length must be less than %d bits\n",
- BUFLEN * 8);
- return -EBADRQC;
+ if (!dev->registered) {
+ retval = -ENODEV;
+ goto out_fh;
}
- if (!d->buf && !(d->fops && d->fops->read &&
- d->fops->poll && d->fops->unlocked_ioctl)) {
- dev_err(&d->dev, "undefined read, poll, ioctl\n");
- return -EBADRQC;
+ if (dev->driver_type == RC_DRIVER_IR_RAW) {
+ if (kfifo_alloc(&fh->rawir, MAX_IR_EVENT_SIZE, GFP_KERNEL)) {
+ retval = -ENOMEM;
+ goto out_fh;
+ }
}
- /* some safety check 8-) */
- d->name[sizeof(d->name) - 1] = '\0';
-
- if (d->features == 0)
- d->features = LIRC_CAN_REC_LIRCCODE;
-
- if (LIRC_CAN_REC(d->features)) {
- err = lirc_allocate_buffer(d);
- if (err)
- return err;
+ if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
+ if (kfifo_alloc(&fh->scancodes, 32, GFP_KERNEL)) {
+ retval = -ENOMEM;
+ goto out_rawir;
+ }
}
- minor = ida_simple_get(&lirc_ida, 0, LIRC_MAX_DEVICES, GFP_KERNEL);
- if (minor < 0)
- return minor;
+ fh->send_mode = LIRC_MODE_PULSE;
+ fh->rc = dev;
+ fh->send_timeout_reports = true;
- d->minor = minor;
- d->dev.devt = MKDEV(MAJOR(lirc_base_dev), d->minor);
- dev_set_name(&d->dev, "lirc%d", d->minor);
+ if (dev->driver_type == RC_DRIVER_SCANCODE)
+ fh->rec_mode = LIRC_MODE_SCANCODE;
+ else
+ fh->rec_mode = LIRC_MODE_MODE2;
- cdev_init(&d->cdev, d->fops);
- d->cdev.owner = d->owner;
- d->attached = true;
+ retval = rc_open(dev);
+ if (retval)
+ goto out_kfifo;
- err = cdev_device_add(&d->cdev, &d->dev);
- if (err) {
- ida_simple_remove(&lirc_ida, minor);
- return err;
- }
+ init_waitqueue_head(&fh->wait_poll);
- get_device(d->dev.parent);
+ file->private_data = fh;
+ spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+ list_add(&fh->list, &dev->lirc_fh);
+ spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
- dev_info(&d->dev, "lirc_dev: driver %s registered at minor = %d\n",
- d->name, d->minor);
+ nonseekable_open(inode, file);
return 0;
+out_kfifo:
+ if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
+ kfifo_free(&fh->scancodes);
+out_rawir:
+ if (dev->driver_type == RC_DRIVER_IR_RAW)
+ kfifo_free(&fh->rawir);
+out_fh:
+ kfree(fh);
+ put_device(&dev->dev);
+
+ return retval;
}
-EXPORT_SYMBOL(lirc_register_device);
-void lirc_unregister_device(struct lirc_dev *d)
+static int ir_lirc_close(struct inode *inode, struct file *file)
{
- if (!d)
- return;
-
- dev_dbg(&d->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
- d->name, d->minor);
+ struct lirc_fh *fh = file->private_data;
+ struct rc_dev *dev = fh->rc;
+ unsigned long flags;
- mutex_lock(&d->mutex);
+ spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+ list_del(&fh->list);
+ spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
- d->attached = false;
- if (d->open) {
- dev_dbg(&d->dev, LOGHEAD "releasing opened driver\n",
- d->name, d->minor);
- wake_up_interruptible(&d->buf->wait_poll);
- }
+ if (dev->driver_type == RC_DRIVER_IR_RAW)
+ kfifo_free(&fh->rawir);
+ if (dev->driver_type != RC_DRIVER_IR_RAW_TX)
+ kfifo_free(&fh->scancodes);
+ kfree(fh);
- mutex_unlock(&d->mutex);
+ rc_close(dev);
+ put_device(&dev->dev);
- cdev_device_del(&d->cdev, &d->dev);
- ida_simple_remove(&lirc_ida, d->minor);
- put_device(&d->dev);
+ return 0;
}
-EXPORT_SYMBOL(lirc_unregister_device);
-int lirc_dev_fop_open(struct inode *inode, struct file *file)
+static ssize_t ir_lirc_transmit_ir(struct file *file, const char __user *buf,
+ size_t n, loff_t *ppos)
{
- struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
- int retval;
+ struct lirc_fh *fh = file->private_data;
+ struct rc_dev *dev = fh->rc;
+ unsigned int *txbuf;
+ struct ir_raw_event *raw = NULL;
+ ssize_t ret;
+ size_t count;
+ ktime_t start;
+ s64 towait;
+ unsigned int duration = 0; /* signal duration in us */
+ int i;
+
+ ret = mutex_lock_interruptible(&dev->lock);
+ if (ret)
+ return ret;
- dev_dbg(&d->dev, LOGHEAD "open called\n", d->name, d->minor);
+ if (!dev->registered) {
+ ret = -ENODEV;
+ goto out_unlock;
+ }
- retval = mutex_lock_interruptible(&d->mutex);
- if (retval)
- return retval;
+ start = ktime_get();
- if (!d->attached) {
- retval = -ENODEV;
- goto out;
+ if (!dev->tx_ir) {
+ ret = -EINVAL;
+ goto out_unlock;
}
- if (d->open) {
- retval = -EBUSY;
- goto out;
- }
+ if (fh->send_mode == LIRC_MODE_SCANCODE) {
+ struct lirc_scancode scan;
- if (d->rdev) {
- retval = rc_open(d->rdev);
- if (retval)
- goto out;
- }
+ if (n != sizeof(scan)) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
- if (d->buf)
- lirc_buffer_clear(d->buf);
+ if (copy_from_user(&scan, buf, sizeof(scan))) {
+ ret = -EFAULT;
+ goto out_unlock;
+ }
- d->open++;
+ if (scan.flags || scan.keycode || scan.timestamp) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
- lirc_init_pdata(inode, file);
- nonseekable_open(inode, file);
- mutex_unlock(&d->mutex);
+ /*
+ * The scancode field in lirc_scancode is 64-bit simply
+ * to future-proof it, since there are IR protocols encode
+ * use more than 32 bits. For now only 32-bit protocols
+ * are supported.
+ */
+ if (scan.scancode > U32_MAX ||
+ !rc_validate_scancode(scan.rc_proto, scan.scancode)) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
- return 0;
+ raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL);
+ if (!raw) {
+ ret = -ENOMEM;
+ goto out_unlock;
+ }
-out:
- mutex_unlock(&d->mutex);
- return retval;
-}
-EXPORT_SYMBOL(lirc_dev_fop_open);
+ ret = ir_raw_encode_scancode(scan.rc_proto, scan.scancode,
+ raw, LIRCBUF_SIZE);
+ if (ret < 0)
+ goto out_kfree_raw;
-int lirc_dev_fop_close(struct inode *inode, struct file *file)
-{
- struct lirc_dev *d = file->private_data;
+ count = ret;
- mutex_lock(&d->mutex);
+ txbuf = kmalloc_array(count, sizeof(unsigned int), GFP_KERNEL);
+ if (!txbuf) {
+ ret = -ENOMEM;
+ goto out_kfree_raw;
+ }
- rc_close(d->rdev);
- d->open--;
+ for (i = 0; i < count; i++)
+ /* Convert from NS to US */
+ txbuf[i] = DIV_ROUND_UP(raw[i].duration, 1000);
- mutex_unlock(&d->mutex);
+ if (dev->s_tx_carrier) {
+ int carrier = ir_raw_encode_carrier(scan.rc_proto);
- return 0;
-}
-EXPORT_SYMBOL(lirc_dev_fop_close);
+ if (carrier > 0)
+ dev->s_tx_carrier(dev, carrier);
+ }
+ } else {
+ if (n < sizeof(unsigned int) || n % sizeof(unsigned int)) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
-__poll_t lirc_dev_fop_poll(struct file *file, poll_table *wait)
-{
- struct lirc_dev *d = file->private_data;
- __poll_t ret;
+ count = n / sizeof(unsigned int);
+ if (count > LIRCBUF_SIZE || count % 2 == 0) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
- if (!d->attached)
- return POLLHUP | POLLERR;
+ txbuf = memdup_user(buf, n);
+ if (IS_ERR(txbuf)) {
+ ret = PTR_ERR(txbuf);
+ goto out_unlock;
+ }
+ }
- if (d->buf) {
- poll_wait(file, &d->buf->wait_poll, wait);
+ for (i = 0; i < count; i++) {
+ if (txbuf[i] > IR_MAX_DURATION / 1000 - duration || !txbuf[i]) {
+ ret = -EINVAL;
+ goto out_kfree;
+ }
- if (lirc_buffer_empty(d->buf))
- ret = 0;
- else
- ret = POLLIN | POLLRDNORM;
- } else {
- ret = POLLERR;
+ duration += txbuf[i];
}
- dev_dbg(&d->dev, LOGHEAD "poll result = %d\n", d->name, d->minor, ret);
+ ret = dev->tx_ir(dev, txbuf, count);
+ if (ret < 0)
+ goto out_kfree;
+
+ kfree(txbuf);
+ kfree(raw);
+ mutex_unlock(&dev->lock);
+
+ /*
+ * 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));
+ }
+ return n;
+out_kfree:
+ kfree(txbuf);
+out_kfree_raw:
+ kfree(raw);
+out_unlock:
+ mutex_unlock(&dev->lock);
return ret;
}
-EXPORT_SYMBOL(lirc_dev_fop_poll);
-long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long ir_lirc_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
- struct lirc_dev *d = file->private_data;
- __u32 mode;
- int result;
-
- dev_dbg(&d->dev, LOGHEAD "ioctl called (0x%x)\n",
- d->name, d->minor, cmd);
+ struct lirc_fh *fh = file->private_data;
+ struct rc_dev *dev = fh->rc;
+ u32 __user *argp = (u32 __user *)(arg);
+ u32 val = 0;
+ int ret;
+
+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ ret = get_user(val, argp);
+ if (ret)
+ return ret;
+ }
- result = mutex_lock_interruptible(&d->mutex);
- if (result)
- return result;
+ ret = mutex_lock_interruptible(&dev->lock);
+ if (ret)
+ return ret;
- if (!d->attached) {
- result = -ENODEV;
+ if (!dev->registered) {
+ ret = -ENODEV;
goto out;
}
switch (cmd) {
case LIRC_GET_FEATURES:
- result = put_user(d->features, (__u32 __user *)arg);
- break;
- case LIRC_GET_REC_MODE:
- if (!LIRC_CAN_REC(d->features)) {
- result = -ENOTTY;
- break;
+ if (dev->driver_type == RC_DRIVER_SCANCODE)
+ val |= LIRC_CAN_REC_SCANCODE;
+
+ if (dev->driver_type == RC_DRIVER_IR_RAW) {
+ val |= LIRC_CAN_REC_MODE2;
+ if (dev->rx_resolution)
+ val |= LIRC_CAN_GET_REC_RESOLUTION;
+ }
+
+ if (dev->tx_ir) {
+ val |= LIRC_CAN_SEND_PULSE;
+ if (dev->s_tx_mask)
+ val |= LIRC_CAN_SET_TRANSMITTER_MASK;
+ if (dev->s_tx_carrier)
+ val |= LIRC_CAN_SET_SEND_CARRIER;
+ if (dev->s_tx_duty_cycle)
+ val |= LIRC_CAN_SET_SEND_DUTY_CYCLE;
}
- result = put_user(LIRC_REC2MODE
- (d->features & LIRC_CAN_REC_MASK),
- (__u32 __user *)arg);
+ if (dev->s_rx_carrier_range)
+ val |= LIRC_CAN_SET_REC_CARRIER |
+ LIRC_CAN_SET_REC_CARRIER_RANGE;
+
+ if (dev->s_learning_mode)
+ val |= LIRC_CAN_USE_WIDEBAND_RECEIVER;
+
+ if (dev->s_carrier_report)
+ val |= LIRC_CAN_MEASURE_CARRIER;
+
+ if (dev->max_timeout)
+ val |= LIRC_CAN_SET_REC_TIMEOUT;
+
break;
+
+ /* mode support */
+ case LIRC_GET_REC_MODE:
+ if (dev->driver_type == RC_DRIVER_IR_RAW_TX)
+ ret = -ENOTTY;
+ else
+ val = fh->rec_mode;
+ break;
+
case LIRC_SET_REC_MODE:
- if (!LIRC_CAN_REC(d->features)) {
- result = -ENOTTY;
+ switch (dev->driver_type) {
+ case RC_DRIVER_IR_RAW_TX:
+ ret = -ENOTTY;
+ break;
+ case RC_DRIVER_SCANCODE:
+ if (val != LIRC_MODE_SCANCODE)
+ ret = -EINVAL;
+ break;
+ case RC_DRIVER_IR_RAW:
+ if (!(val == LIRC_MODE_MODE2 ||
+ val == LIRC_MODE_SCANCODE))
+ ret = -EINVAL;
break;
}
- result = get_user(mode, (__u32 __user *)arg);
- if (!result && !(LIRC_MODE2REC(mode) & d->features))
- result = -EINVAL;
- /*
- * FIXME: We should actually set the mode somehow but
- * for now, lirc_serial doesn't support mode changing either
- */
+ if (!ret)
+ fh->rec_mode = val;
+ break;
+
+ case LIRC_GET_SEND_MODE:
+ if (!dev->tx_ir)
+ ret = -ENOTTY;
+ else
+ val = fh->send_mode;
+ break;
+
+ case LIRC_SET_SEND_MODE:
+ if (!dev->tx_ir)
+ ret = -ENOTTY;
+ else if (!(val == LIRC_MODE_PULSE || val == LIRC_MODE_SCANCODE))
+ ret = -EINVAL;
+ else
+ fh->send_mode = val;
+ break;
+
+ /* TX settings */
+ case LIRC_SET_TRANSMITTER_MASK:
+ if (!dev->s_tx_mask)
+ ret = -ENOTTY;
+ else
+ ret = dev->s_tx_mask(dev, val);
+ break;
+
+ case LIRC_SET_SEND_CARRIER:
+ if (!dev->s_tx_carrier)
+ ret = -ENOTTY;
+ else
+ ret = dev->s_tx_carrier(dev, val);
+ break;
+
+ case LIRC_SET_SEND_DUTY_CYCLE:
+ if (!dev->s_tx_duty_cycle)
+ ret = -ENOTTY;
+ else if (val <= 0 || val >= 100)
+ ret = -EINVAL;
+ else
+ ret = dev->s_tx_duty_cycle(dev, val);
+ break;
+
+ /* RX settings */
+ case LIRC_SET_REC_CARRIER:
+ if (!dev->s_rx_carrier_range)
+ ret = -ENOTTY;
+ else if (val <= 0)
+ ret = -EINVAL;
+ else
+ ret = dev->s_rx_carrier_range(dev, fh->carrier_low,
+ val);
+ break;
+
+ case LIRC_SET_REC_CARRIER_RANGE:
+ if (!dev->s_rx_carrier_range)
+ ret = -ENOTTY;
+ else if (val <= 0)
+ ret = -EINVAL;
+ else
+ fh->carrier_low = val;
+ break;
+
+ case LIRC_GET_REC_RESOLUTION:
+ if (!dev->rx_resolution)
+ ret = -ENOTTY;
+ else
+ val = dev->rx_resolution / 1000;
break;
- case LIRC_GET_LENGTH:
- result = put_user(d->code_length, (__u32 __user *)arg);
+
+ case LIRC_SET_WIDEBAND_RECEIVER:
+ if (!dev->s_learning_mode)
+ ret = -ENOTTY;
+ else
+ ret = dev->s_learning_mode(dev, !!val);
break;
+
+ case LIRC_SET_MEASURE_CARRIER_MODE:
+ if (!dev->s_carrier_report)
+ ret = -ENOTTY;
+ else
+ ret = dev->s_carrier_report(dev, !!val);
+ break;
+
+ /* Generic timeout support */
+ case LIRC_GET_MIN_TIMEOUT:
+ if (!dev->max_timeout)
+ ret = -ENOTTY;
+ else
+ val = DIV_ROUND_UP(dev->min_timeout, 1000);
+ break;
+
+ case LIRC_GET_MAX_TIMEOUT:
+ if (!dev->max_timeout)
+ ret = -ENOTTY;
+ else
+ val = dev->max_timeout / 1000;
+ break;
+
+ case LIRC_SET_REC_TIMEOUT:
+ if (!dev->max_timeout) {
+ ret = -ENOTTY;
+ } else if (val > U32_MAX / 1000) {
+ /* Check for multiply overflow */
+ ret = -EINVAL;
+ } else {
+ u32 tmp = val * 1000;
+
+ if (tmp < dev->min_timeout || tmp > dev->max_timeout)
+ ret = -EINVAL;
+ else if (dev->s_timeout)
+ ret = dev->s_timeout(dev, tmp);
+ else if (!ret)
+ dev->timeout = tmp;
+ }
+ break;
+
+ case LIRC_SET_REC_TIMEOUT_REPORTS:
+ if (!dev->timeout)
+ ret = -ENOTTY;
+ else
+ fh->send_timeout_reports = !!val;
+ break;
+
default:
- result = -ENOTTY;
+ ret = -ENOTTY;
}
+ if (!ret && _IOC_DIR(cmd) & _IOC_READ)
+ ret = put_user(val, argp);
+
out:
- mutex_unlock(&d->mutex);
- return result;
+ mutex_unlock(&dev->lock);
+ return ret;
}
-EXPORT_SYMBOL(lirc_dev_fop_ioctl);
-ssize_t lirc_dev_fop_read(struct file *file,
- char __user *buffer,
- size_t length,
- loff_t *ppos)
+static __poll_t ir_lirc_poll(struct file *file, struct poll_table_struct *wait)
{
- struct lirc_dev *d = file->private_data;
- unsigned char *buf;
- int ret, written = 0;
- DECLARE_WAITQUEUE(wait, current);
+ struct lirc_fh *fh = file->private_data;
+ struct rc_dev *rcdev = fh->rc;
+ __poll_t events = 0;
+
+ poll_wait(file, &fh->wait_poll, wait);
+
+ if (!rcdev->registered) {
+ events = POLLHUP | POLLERR;
+ } else if (rcdev->driver_type != RC_DRIVER_IR_RAW_TX) {
+ if (fh->rec_mode == LIRC_MODE_SCANCODE &&
+ !kfifo_is_empty(&fh->scancodes))
+ events = POLLIN | POLLRDNORM;
+
+ if (fh->rec_mode == LIRC_MODE_MODE2 &&
+ !kfifo_is_empty(&fh->rawir))
+ events = POLLIN | POLLRDNORM;
+ }
- buf = kzalloc(d->buf->chunk_size, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
+ return events;
+}
- dev_dbg(&d->dev, LOGHEAD "read called\n", d->name, d->minor);
+static ssize_t ir_lirc_read_mode2(struct file *file, char __user *buffer,
+ size_t length)
+{
+ struct lirc_fh *fh = file->private_data;
+ struct rc_dev *rcdev = fh->rc;
+ unsigned int copied;
+ int ret;
- ret = mutex_lock_interruptible(&d->mutex);
- if (ret) {
- kfree(buf);
- return ret;
- }
+ if (length < sizeof(unsigned int) || length % sizeof(unsigned int))
+ return -EINVAL;
- if (!d->attached) {
- ret = -ENODEV;
- goto out_locked;
- }
+ do {
+ if (kfifo_is_empty(&fh->rawir)) {
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
- if (!LIRC_CAN_REC(d->features)) {
- ret = -EINVAL;
- goto out_locked;
- }
+ ret = wait_event_interruptible(fh->wait_poll,
+ !kfifo_is_empty(&fh->rawir) ||
+ !rcdev->registered);
+ if (ret)
+ return ret;
+ }
- if (length % d->buf->chunk_size) {
- ret = -EINVAL;
- goto out_locked;
- }
+ if (!rcdev->registered)
+ return -ENODEV;
- /*
- * we add ourselves to the task queue before buffer check
- * to avoid losing scan code (in case when queue is awaken somewhere
- * between while condition checking and scheduling)
- */
- add_wait_queue(&d->buf->wait_poll, &wait);
+ ret = mutex_lock_interruptible(&rcdev->lock);
+ if (ret)
+ return ret;
+ ret = kfifo_to_user(&fh->rawir, buffer, length, &copied);
+ mutex_unlock(&rcdev->lock);
+ if (ret)
+ return ret;
+ } while (copied == 0);
- /*
- * while we didn't provide 'length' bytes, device is opened in blocking
- * mode and 'copy_to_user' is happy, wait for data.
- */
- while (written < length && ret == 0) {
- if (lirc_buffer_empty(d->buf)) {
- /* According to the read(2) man page, 'written' can be
- * returned as less than 'length', instead of blocking
- * again, returning -EWOULDBLOCK, or returning
- * -ERESTARTSYS
- */
- if (written)
- break;
- if (file->f_flags & O_NONBLOCK) {
- ret = -EWOULDBLOCK;
- break;
- }
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
-
- mutex_unlock(&d->mutex);
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- set_current_state(TASK_RUNNING);
-
- ret = mutex_lock_interruptible(&d->mutex);
- if (ret) {
- remove_wait_queue(&d->buf->wait_poll, &wait);
- goto out_unlocked;
- }
-
- if (!d->attached) {
- ret = -ENODEV;
- goto out_locked;
- }
- } else {
- lirc_buffer_read(d->buf, buf);
- ret = copy_to_user((void __user *)buffer+written, buf,
- d->buf->chunk_size);
- if (!ret)
- written += d->buf->chunk_size;
- else
- ret = -EFAULT;
+ return copied;
+}
+
+static ssize_t ir_lirc_read_scancode(struct file *file, char __user *buffer,
+ size_t length)
+{
+ struct lirc_fh *fh = file->private_data;
+ struct rc_dev *rcdev = fh->rc;
+ unsigned int copied;
+ int ret;
+
+ if (length < sizeof(struct lirc_scancode) ||
+ length % sizeof(struct lirc_scancode))
+ return -EINVAL;
+
+ do {
+ if (kfifo_is_empty(&fh->scancodes)) {
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ ret = wait_event_interruptible(fh->wait_poll,
+ !kfifo_is_empty(&fh->scancodes) ||
+ !rcdev->registered);
+ if (ret)
+ return ret;
}
- }
- remove_wait_queue(&d->buf->wait_poll, &wait);
+ if (!rcdev->registered)
+ return -ENODEV;
+
+ ret = mutex_lock_interruptible(&rcdev->lock);
+ if (ret)
+ return ret;
+ ret = kfifo_to_user(&fh->scancodes, buffer, length, &copied);
+ mutex_unlock(&rcdev->lock);
+ if (ret)
+ return ret;
+ } while (copied == 0);
+
+ return copied;
+}
-out_locked:
- mutex_unlock(&d->mutex);
+static ssize_t ir_lirc_read(struct file *file, char __user *buffer,
+ size_t length, loff_t *ppos)
+{
+ struct lirc_fh *fh = file->private_data;
+ struct rc_dev *rcdev = fh->rc;
+
+ if (rcdev->driver_type == RC_DRIVER_IR_RAW_TX)
+ return -EINVAL;
-out_unlocked:
- kfree(buf);
+ if (!rcdev->registered)
+ return -ENODEV;
- return ret ? ret : written;
+ if (fh->rec_mode == LIRC_MODE_MODE2)
+ return ir_lirc_read_mode2(file, buffer, length);
+ else /* LIRC_MODE_SCANCODE */
+ return ir_lirc_read_scancode(file, buffer, length);
}
-EXPORT_SYMBOL(lirc_dev_fop_read);
-void lirc_init_pdata(struct inode *inode, struct file *file)
+static const struct file_operations lirc_fops = {
+ .owner = THIS_MODULE,
+ .write = ir_lirc_transmit_ir,
+ .unlocked_ioctl = ir_lirc_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ir_lirc_ioctl,
+#endif
+ .read = ir_lirc_read,
+ .poll = ir_lirc_poll,
+ .open = ir_lirc_open,
+ .release = ir_lirc_close,
+ .llseek = no_llseek,
+};
+
+static void lirc_release_device(struct device *ld)
{
- struct lirc_dev *d = container_of(inode->i_cdev, struct lirc_dev, cdev);
+ struct rc_dev *rcdev = container_of(ld, struct rc_dev, lirc_dev);
- file->private_data = d;
+ put_device(&rcdev->dev);
}
-EXPORT_SYMBOL(lirc_init_pdata);
-void *lirc_get_pdata(struct file *file)
+int ir_lirc_register(struct rc_dev *dev)
{
- struct lirc_dev *d = file->private_data;
+ int err, minor;
+
+ minor = ida_simple_get(&lirc_ida, 0, RC_DEV_MAX, GFP_KERNEL);
+ if (minor < 0)
+ return minor;
+
+ device_initialize(&dev->lirc_dev);
+ dev->lirc_dev.class = lirc_class;
+ dev->lirc_dev.parent = &dev->dev;
+ dev->lirc_dev.release = lirc_release_device;
+ dev->lirc_dev.devt = MKDEV(MAJOR(lirc_base_dev), minor);
+ dev_set_name(&dev->lirc_dev, "lirc%d", minor);
- return d->data;
+ INIT_LIST_HEAD(&dev->lirc_fh);
+ spin_lock_init(&dev->lirc_fh_lock);
+
+ cdev_init(&dev->lirc_cdev, &lirc_fops);
+
+ err = cdev_device_add(&dev->lirc_cdev, &dev->lirc_dev);
+ if (err)
+ goto out_ida;
+
+ get_device(&dev->dev);
+
+ dev_info(&dev->dev, "lirc_dev: driver %s registered at minor = %d",
+ dev->driver_name, minor);
+
+ return 0;
+
+out_ida:
+ ida_simple_remove(&lirc_ida, minor);
+ return err;
}
-EXPORT_SYMBOL(lirc_get_pdata);
+void ir_lirc_unregister(struct rc_dev *dev)
+{
+ unsigned long flags;
+ struct lirc_fh *fh;
+
+ dev_dbg(&dev->dev, "lirc_dev: driver %s unregistered from minor = %d\n",
+ dev->driver_name, MINOR(dev->lirc_dev.devt));
+
+ spin_lock_irqsave(&dev->lirc_fh_lock, flags);
+ list_for_each_entry(fh, &dev->lirc_fh, list)
+ wake_up_poll(&fh->wait_poll, POLLHUP | POLLERR);
+ spin_unlock_irqrestore(&dev->lirc_fh_lock, flags);
-static int __init lirc_dev_init(void)
+ cdev_device_del(&dev->lirc_cdev, &dev->lirc_dev);
+ ida_simple_remove(&lirc_ida, MINOR(dev->lirc_dev.devt));
+}
+
+int __init lirc_dev_init(void)
{
int retval;
@@ -487,7 +796,7 @@ static int __init lirc_dev_init(void)
return PTR_ERR(lirc_class);
}
- retval = alloc_chrdev_region(&lirc_base_dev, 0, LIRC_MAX_DEVICES,
+ retval = alloc_chrdev_region(&lirc_base_dev, 0, RC_DEV_MAX,
"BaseRemoteCtl");
if (retval) {
class_destroy(lirc_class);
@@ -501,16 +810,10 @@ static int __init lirc_dev_init(void)
return 0;
}
-static void __exit lirc_dev_exit(void)
+void __exit lirc_dev_exit(void)
{
class_destroy(lirc_class);
- unregister_chrdev_region(lirc_base_dev, LIRC_MAX_DEVICES);
- pr_info("module unloaded\n");
+ unregister_chrdev_region(lirc_base_dev, RC_DEV_MAX);
}
-module_init(lirc_dev_init);
-module_exit(lirc_dev_exit);
-
-MODULE_DESCRIPTION("LIRC base driver module");
-MODULE_AUTHOR("Artur Lipowski");
-MODULE_LICENSE("GPL");
+MODULE_ALIAS("lirc_dev");
diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h
index ae4dd0c27731..458e9eb2d6a9 100644
--- a/drivers/media/rc/rc-core-priv.h
+++ b/drivers/media/rc/rc-core-priv.h
@@ -1,27 +1,34 @@
/*
+ * SPDX-License-Identifier: GPL-2.0
* Remote Controller core raw events header
*
* Copyright (C) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#ifndef _RC_CORE_PRIV
#define _RC_CORE_PRIV
+#define RC_DEV_MAX 256
/* Define the max number of pulse/space transitions to buffer */
#define MAX_IR_EVENT_SIZE 512
#include <linux/slab.h>
#include <media/rc-core.h>
+/**
+ * rc_open - Opens a RC device
+ *
+ * @rdev: pointer to struct rc_dev.
+ */
+int rc_open(struct rc_dev *rdev);
+
+/**
+ * rc_close - Closes a RC device
+ *
+ * @rdev: pointer to struct rc_dev.
+ */
+void rc_close(struct rc_dev *rdev);
+
struct ir_raw_handler {
struct list_head list;
@@ -29,8 +36,9 @@ struct ir_raw_handler {
int (*decode)(struct rc_dev *dev, struct ir_raw_event event);
int (*encode)(enum rc_proto protocol, u32 scancode,
struct ir_raw_event *events, unsigned int max);
+ u32 carrier;
- /* These two should only be used by the lirc decoder */
+ /* These two should only be used by the mce kbd decoder */
int (*raw_register)(struct rc_dev *dev);
int (*raw_unregister)(struct rc_dev *dev);
};
@@ -104,17 +112,6 @@ struct ir_raw_event_ctrl {
unsigned count;
unsigned wanted_bits;
} mce_kbd;
- struct lirc_codec {
- struct rc_dev *dev;
- struct lirc_dev *ldev;
- int carrier_low;
-
- ktime_t gap_start;
- u64 gap_duration;
- bool gap;
- bool send_timeout_reports;
-
- } lirc;
struct xmp_dec {
int state;
unsigned count;
@@ -156,6 +153,7 @@ static inline bool is_timing_event(struct ir_raw_event ev)
#define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space")
/* functions for IR encoders */
+bool rc_validate_scancode(enum rc_proto proto, u32 scancode);
static inline void init_ir_raw_event_duration(struct ir_raw_event *ev,
unsigned int pulse,
@@ -168,17 +166,17 @@ static inline void init_ir_raw_event_duration(struct ir_raw_event *ev,
/**
* struct ir_raw_timings_manchester - Manchester coding timings
- * @leader: duration of leader pulse (if any) 0 if continuing
- * existing signal (see @pulse_space_start)
- * @pulse_space_start: 1 for starting with pulse (0 for starting with space)
+ * @leader_pulse: duration of leader pulse (if any) 0 if continuing
+ * existing signal
+ * @leader_space: duration of leader space (if any)
* @clock: duration of each pulse/space in ns
* @invert: if set clock logic is inverted
* (0 = space + pulse, 1 = pulse + space)
* @trailer_space: duration of trailer space in ns
*/
struct ir_raw_timings_manchester {
- unsigned int leader;
- unsigned int pulse_space_start:1;
+ unsigned int leader_pulse;
+ unsigned int leader_space;
unsigned int clock;
unsigned int invert:1;
unsigned int trailer_space;
@@ -270,9 +268,31 @@ void ir_raw_event_free(struct rc_dev *dev);
void ir_raw_event_unregister(struct rc_dev *dev);
int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler);
+void ir_raw_load_modules(u64 *protocols);
void ir_raw_init(void);
/*
+ * lirc interface
+ */
+#ifdef CONFIG_LIRC
+int lirc_dev_init(void);
+void lirc_dev_exit(void);
+void ir_lirc_raw_event(struct rc_dev *dev, struct ir_raw_event ev);
+void ir_lirc_scancode_event(struct rc_dev *dev, struct lirc_scancode *lsc);
+int ir_lirc_register(struct rc_dev *dev);
+void ir_lirc_unregister(struct rc_dev *dev);
+#else
+static inline int lirc_dev_init(void) { return 0; }
+static inline void lirc_dev_exit(void) {}
+static inline void ir_lirc_raw_event(struct rc_dev *dev,
+ struct ir_raw_event ev) { }
+static inline void ir_lirc_scancode_event(struct rc_dev *dev,
+ struct lirc_scancode *lsc) { }
+static inline int ir_lirc_register(struct rc_dev *dev) { return 0; }
+static inline void ir_lirc_unregister(struct rc_dev *dev) { }
+#endif
+
+/*
* Decoder initialization code
*
* Those load logic are called during ir-core init, and automatically
diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c
index d78483a504c9..18504870b9f0 100644
--- a/drivers/media/rc/rc-ir-raw.c
+++ b/drivers/media/rc/rc-ir-raw.c
@@ -1,16 +1,7 @@
-/* rc-ir-raw.c - handle IR pulse/space events
- *
- * Copyright (C) 2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0
+// rc-ir-raw.c - handle IR pulse/space events
+//
+// Copyright (C) 2010 by Mauro Carvalho Chehab
#include <linux/export.h>
#include <linux/kthread.h>
@@ -40,6 +31,7 @@ static int ir_raw_event_thread(void *data)
if (raw->dev->enabled_protocols &
handler->protocols || !handler->protocols)
handler->decode(raw->dev, ev);
+ ir_lirc_raw_event(raw->dev, ev);
raw->prev_ev = ev;
}
mutex_unlock(&ir_raw_handler_lock);
@@ -254,19 +246,16 @@ int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max,
i = BIT_ULL(n - 1);
- if (timings->leader) {
+ if (timings->leader_pulse) {
if (!max--)
return ret;
- if (timings->pulse_space_start) {
- init_ir_raw_event_duration((*ev)++, 1, timings->leader);
-
+ init_ir_raw_event_duration((*ev), 1, timings->leader_pulse);
+ if (timings->leader_space) {
if (!max--)
return ret;
- init_ir_raw_event_duration((*ev), 0, timings->leader);
- } else {
- init_ir_raw_event_duration((*ev), 1, timings->leader);
+ init_ir_raw_event_duration(++(*ev), 0,
+ timings->leader_space);
}
- i >>= 1;
} else {
/* continue existing signal */
--(*ev);
@@ -457,6 +446,8 @@ int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode,
int ret = -EINVAL;
u64 mask = 1ULL << protocol;
+ ir_raw_load_modules(&mask);
+
mutex_lock(&ir_raw_handler_lock);
list_for_each_entry(handler, &ir_raw_handler_list, list) {
if (handler->protocols & mask && handler->encode) {
@@ -493,21 +484,44 @@ static void edge_handle(struct timer_list *t)
ir_raw_event_handle(dev);
}
+/**
+ * ir_raw_encode_carrier() - Get carrier used for protocol
+ *
+ * @protocol: protocol
+ *
+ * Attempts to find the carrier for the specified protocol
+ *
+ * Returns: The carrier in Hz
+ * -EINVAL if the protocol is invalid, or if no
+ * compatible encoder was found.
+ */
+int ir_raw_encode_carrier(enum rc_proto protocol)
+{
+ struct ir_raw_handler *handler;
+ int ret = -EINVAL;
+ u64 mask = BIT_ULL(protocol);
+
+ mutex_lock(&ir_raw_handler_lock);
+ list_for_each_entry(handler, &ir_raw_handler_list, list) {
+ if (handler->protocols & mask && handler->encode) {
+ ret = handler->carrier;
+ break;
+ }
+ }
+ mutex_unlock(&ir_raw_handler_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(ir_raw_encode_carrier);
+
/*
* Used to (un)register raw event clients
*/
int ir_raw_event_prepare(struct rc_dev *dev)
{
- static bool raw_init; /* 'false' default value, raw decoders loaded? */
-
if (!dev)
return -EINVAL;
- if (!raw_init) {
- request_module("ir-lirc-codec");
- raw_init = true;
- }
-
dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL);
if (!dev->raw)
return -ENOMEM;
@@ -525,19 +539,11 @@ int ir_raw_event_register(struct rc_dev *dev)
struct ir_raw_handler *handler;
struct task_struct *thread;
- /*
- * raw transmitters do not need any event registration
- * because the event is coming from userspace
- */
- if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
- thread = kthread_run(ir_raw_event_thread, dev->raw, "rc%u",
- dev->minor);
+ thread = kthread_run(ir_raw_event_thread, dev->raw, "rc%u", dev->minor);
+ if (IS_ERR(thread))
+ return PTR_ERR(thread);
- if (IS_ERR(thread))
- return PTR_ERR(thread);
-
- dev->raw->thread = thread;
- }
+ dev->raw->thread = thread;
mutex_lock(&ir_raw_handler_lock);
list_add_tail(&dev->raw->list, &ir_raw_client_list);
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c
index c144b77eac98..1db8d38fed7c 100644
--- a/drivers/media/rc/rc-main.c
+++ b/drivers/media/rc/rc-main.c
@@ -1,16 +1,7 @@
-/* rc-main.c - Remote Controller core module
- *
- * Copyright (C) 2009-2010 by Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// rc-main.c - Remote Controller core module
+//
+// Copyright (C) 2009-2010 by Mauro Carvalho Chehab
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -29,7 +20,6 @@
/* Sizes are in bytes, 256 bytes allows for 32 entries on x64 */
#define IR_TAB_MIN_SIZE 256
#define IR_TAB_MAX_SIZE 8192
-#define RC_DEV_MAX 256
static const struct {
const char *name;
@@ -607,6 +597,7 @@ static void ir_do_keyup(struct rc_dev *dev, bool sync)
return;
IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
+ del_timer(&dev->timer_repeat);
input_report_key(dev->input_dev, dev->last_keycode, 0);
led_trigger_event(led_feedback, LED_OFF);
if (sync)
@@ -661,6 +652,31 @@ static void ir_timer_keyup(struct timer_list *t)
}
/**
+ * ir_timer_repeat() - generates a repeat event after a timeout
+ *
+ * @t: a pointer to the struct timer_list
+ *
+ * This routine will generate a soft repeat event every REP_PERIOD
+ * milliseconds.
+ */
+static void ir_timer_repeat(struct timer_list *t)
+{
+ struct rc_dev *dev = from_timer(dev, t, timer_repeat);
+ struct input_dev *input = dev->input_dev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->keylock, flags);
+ if (dev->keypressed) {
+ input_event(input, EV_KEY, dev->last_keycode, 2);
+ input_sync(input);
+ if (input->rep[REP_PERIOD])
+ mod_timer(&dev->timer_repeat, jiffies +
+ msecs_to_jiffies(input->rep[REP_PERIOD]));
+ }
+ spin_unlock_irqrestore(&dev->keylock, flags);
+}
+
+/**
* rc_repeat() - signals that a key is still pressed
* @dev: the struct rc_dev descriptor of the device
*
@@ -672,19 +688,25 @@ void rc_repeat(struct rc_dev *dev)
{
unsigned long flags;
unsigned int timeout = protocols[dev->last_protocol].repeat_period;
+ struct lirc_scancode sc = {
+ .scancode = dev->last_scancode, .rc_proto = dev->last_protocol,
+ .keycode = dev->keypressed ? dev->last_keycode : KEY_RESERVED,
+ .flags = LIRC_SCANCODE_FLAG_REPEAT |
+ (dev->last_toggle ? LIRC_SCANCODE_FLAG_TOGGLE : 0)
+ };
- spin_lock_irqsave(&dev->keylock, flags);
+ ir_lirc_scancode_event(dev, &sc);
- if (!dev->keypressed)
- goto out;
+ spin_lock_irqsave(&dev->keylock, flags);
input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
input_sync(dev->input_dev);
- dev->keyup_jiffies = jiffies + msecs_to_jiffies(timeout);
- mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
+ if (dev->keypressed) {
+ dev->keyup_jiffies = jiffies + msecs_to_jiffies(timeout);
+ mod_timer(&dev->timer_keyup, dev->keyup_jiffies);
+ }
-out:
spin_unlock_irqrestore(&dev->keylock, flags);
}
EXPORT_SYMBOL_GPL(rc_repeat);
@@ -707,19 +729,27 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
dev->last_protocol != protocol ||
dev->last_scancode != scancode ||
dev->last_toggle != toggle);
+ struct lirc_scancode sc = {
+ .scancode = scancode, .rc_proto = protocol,
+ .flags = toggle ? LIRC_SCANCODE_FLAG_TOGGLE : 0,
+ .keycode = keycode
+ };
+
+ ir_lirc_scancode_event(dev, &sc);
if (new_event && dev->keypressed)
ir_do_keyup(dev, false);
input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
+ dev->last_protocol = protocol;
+ dev->last_scancode = scancode;
+ dev->last_toggle = toggle;
+ dev->last_keycode = keycode;
+
if (new_event && keycode != KEY_RESERVED) {
/* Register a keypress */
dev->keypressed = true;
- dev->last_protocol = protocol;
- dev->last_scancode = scancode;
- dev->last_toggle = toggle;
- dev->last_keycode = keycode;
IR_dprintk(1, "%s: key down event, key 0x%04x, protocol 0x%04x, scancode 0x%08x\n",
dev->device_name, keycode, protocol, scancode);
@@ -728,6 +758,22 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
led_trigger_event(led_feedback, LED_FULL);
}
+ /*
+ * For CEC, start sending repeat messages as soon as the first
+ * repeated message is sent, as long as REP_DELAY = 0 and REP_PERIOD
+ * is non-zero. Otherwise, the input layer will generate repeat
+ * messages.
+ */
+ if (!new_event && keycode != KEY_RESERVED &&
+ dev->allowed_protocols == RC_PROTO_BIT_CEC &&
+ !timer_pending(&dev->timer_repeat) &&
+ dev->input_dev->rep[REP_PERIOD] &&
+ !dev->input_dev->rep[REP_DELAY]) {
+ input_event(dev->input_dev, EV_KEY, keycode, 2);
+ mod_timer(&dev->timer_repeat, jiffies +
+ msecs_to_jiffies(dev->input_dev->rep[REP_PERIOD]));
+ }
+
input_sync(dev->input_dev);
}
@@ -785,6 +831,51 @@ void rc_keydown_notimeout(struct rc_dev *dev, enum rc_proto protocol,
EXPORT_SYMBOL_GPL(rc_keydown_notimeout);
/**
+ * rc_validate_scancode() - checks that a scancode is valid for a protocol.
+ * For nec, it should do the opposite of ir_nec_bytes_to_scancode()
+ * @proto: protocol
+ * @scancode: scancode
+ */
+bool rc_validate_scancode(enum rc_proto proto, u32 scancode)
+{
+ switch (proto) {
+ /*
+ * NECX has a 16-bit address; if the lower 8 bits match the upper
+ * 8 bits inverted, then the address would match regular nec.
+ */
+ case RC_PROTO_NECX:
+ if ((((scancode >> 16) ^ ~(scancode >> 8)) & 0xff) == 0)
+ return false;
+ break;
+ /*
+ * NEC32 has a 16 bit address and 16 bit command. If the lower 8 bits
+ * of the command match the upper 8 bits inverted, then it would
+ * be either NEC or NECX.
+ */
+ case RC_PROTO_NEC32:
+ if ((((scancode >> 8) ^ ~scancode) & 0xff) == 0)
+ return false;
+ break;
+ /*
+ * If the customer code (top 32-bit) is 0x800f, it is MCE else it
+ * is regular mode-6a 32 bit
+ */
+ case RC_PROTO_RC6_MCE:
+ if ((scancode & 0xffff0000) != 0x800f0000)
+ return false;
+ break;
+ case RC_PROTO_RC6_6A_32:
+ if ((scancode & 0xffff0000) == 0x800f0000)
+ return false;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/**
* rc_validate_filter() - checks that the scancode and mask are valid and
* provides sensible defaults
* @dev: the struct rc_dev descriptor of the device
@@ -803,26 +894,8 @@ static int rc_validate_filter(struct rc_dev *dev,
mask = protocols[protocol].scancode_bits;
- switch (protocol) {
- case RC_PROTO_NECX:
- if ((((s >> 16) ^ ~(s >> 8)) & 0xff) == 0)
- return -EINVAL;
- break;
- case RC_PROTO_NEC32:
- if ((((s >> 24) ^ ~(s >> 16)) & 0xff) == 0)
- return -EINVAL;
- break;
- case RC_PROTO_RC6_MCE:
- if ((s & 0xffff0000) != 0x800f0000)
- return -EINVAL;
- break;
- case RC_PROTO_RC6_6A_32:
- if ((s & 0xffff0000) == 0x800f0000)
- return -EINVAL;
- break;
- default:
- break;
- }
+ if (!rc_validate_scancode(protocol, s))
+ return -EINVAL;
filter->data &= mask;
filter->mask &= mask;
@@ -845,17 +918,20 @@ int rc_open(struct rc_dev *rdev)
mutex_lock(&rdev->lock);
- if (!rdev->users++ && rdev->open != NULL)
- rval = rdev->open(rdev);
+ if (!rdev->registered) {
+ rval = -ENODEV;
+ } else {
+ if (!rdev->users++ && rdev->open)
+ rval = rdev->open(rdev);
- if (rval)
- rdev->users--;
+ if (rval)
+ rdev->users--;
+ }
mutex_unlock(&rdev->lock);
return rval;
}
-EXPORT_SYMBOL_GPL(rc_open);
static int ir_open(struct input_dev *idev)
{
@@ -869,13 +945,12 @@ void rc_close(struct rc_dev *rdev)
if (rdev) {
mutex_lock(&rdev->lock);
- if (!--rdev->users && rdev->close != NULL)
+ if (!--rdev->users && rdev->close && rdev->registered)
rdev->close(rdev);
mutex_unlock(&rdev->lock);
}
}
-EXPORT_SYMBOL_GPL(rc_close);
static void ir_close(struct input_dev *idev)
{
@@ -950,23 +1025,6 @@ struct rc_filter_attribute {
.mask = (_mask), \
}
-static bool lirc_is_present(void)
-{
-#if defined(CONFIG_LIRC_MODULE)
- struct module *lirc;
-
- mutex_lock(&module_mutex);
- lirc = find_module("lirc_dev");
- mutex_unlock(&module_mutex);
-
- return lirc ? true : false;
-#elif defined(CONFIG_LIRC)
- return true;
-#else
- return false;
-#endif
-}
-
/**
* show_protocols() - shows the current IR protocol(s)
* @device: the device descriptor
@@ -1011,8 +1069,10 @@ static ssize_t show_protocols(struct device *device,
allowed &= ~proto_names[i].type;
}
- if (dev->driver_type == RC_DRIVER_IR_RAW && lirc_is_present())
+#ifdef CONFIG_LIRC
+ if (dev->driver_type == RC_DRIVER_IR_RAW)
tmp += sprintf(tmp, "[lirc] ");
+#endif
if (tmp != buf)
tmp--;
@@ -1091,7 +1151,7 @@ static int parse_protocol_change(u64 *protocols, const char *buf)
return count;
}
-static void ir_raw_load_modules(u64 *protocols)
+void ir_raw_load_modules(u64 *protocols)
{
u64 available;
int i, ret;
@@ -1581,6 +1641,7 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type)
input_set_drvdata(dev->input_dev, dev);
timer_setup(&dev->timer_keyup, ir_timer_keyup, 0);
+ timer_setup(&dev->timer_repeat, ir_timer_repeat, 0);
spin_lock_init(&dev->rc_map.lock);
spin_lock_init(&dev->keylock);
@@ -1714,7 +1775,10 @@ static int rc_setup_rx_device(struct rc_dev *dev)
* to avoid wrong repetition of the keycodes. Note that this must be
* set after the call to input_register_device().
*/
- dev->input_dev->rep[REP_DELAY] = 500;
+ if (dev->allowed_protocols == RC_PROTO_BIT_CEC)
+ dev->input_dev->rep[REP_DELAY] = 0;
+ else
+ dev->input_dev->rep[REP_DELAY] = 500;
/*
* As a repeat event on protocols like RC-5 and NEC take as long as
@@ -1768,8 +1832,7 @@ int rc_register_device(struct rc_dev *dev)
dev->sysfs_groups[attr++] = &rc_dev_wakeup_filter_attr_grp;
dev->sysfs_groups[attr++] = NULL;
- if (dev->driver_type == RC_DRIVER_IR_RAW ||
- dev->driver_type == RC_DRIVER_IR_RAW_TX) {
+ if (dev->driver_type == RC_DRIVER_IR_RAW) {
rc = ir_raw_event_prepare(dev);
if (rc < 0)
goto out_minor;
@@ -1796,19 +1859,30 @@ int rc_register_device(struct rc_dev *dev)
goto out_dev;
}
- if (dev->driver_type == RC_DRIVER_IR_RAW ||
- dev->driver_type == RC_DRIVER_IR_RAW_TX) {
- rc = ir_raw_event_register(dev);
+ /* Ensure that the lirc kfifo is setup before we start the thread */
+ if (dev->allowed_protocols != RC_PROTO_BIT_CEC) {
+ rc = ir_lirc_register(dev);
if (rc < 0)
goto out_rx;
}
+ if (dev->driver_type == RC_DRIVER_IR_RAW) {
+ rc = ir_raw_event_register(dev);
+ if (rc < 0)
+ goto out_lirc;
+ }
+
+ dev->registered = true;
+
IR_dprintk(1, "Registered rc%u (driver: %s)\n",
dev->minor,
dev->driver_name ? dev->driver_name : "unknown");
return 0;
+out_lirc:
+ if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
+ ir_lirc_unregister(dev);
out_rx:
rc_free_rx_device(dev);
out_dev:
@@ -1856,12 +1930,24 @@ void rc_unregister_device(struct rc_dev *dev)
return;
del_timer_sync(&dev->timer_keyup);
+ del_timer_sync(&dev->timer_repeat);
if (dev->driver_type == RC_DRIVER_IR_RAW)
ir_raw_event_unregister(dev);
rc_free_rx_device(dev);
+ mutex_lock(&dev->lock);
+ dev->registered = false;
+ mutex_unlock(&dev->lock);
+
+ /*
+ * lirc device should be freed with dev->registered = false, so
+ * that userspace polling will get notified.
+ */
+ if (dev->allowed_protocols != RC_PROTO_BIT_CEC)
+ ir_lirc_unregister(dev);
+
device_del(&dev->dev);
ida_simple_remove(&rc_ida, dev->minor);
@@ -1884,6 +1970,13 @@ static int __init rc_core_init(void)
return rc;
}
+ rc = lirc_dev_init();
+ if (rc) {
+ pr_err("rc_core: unable to init lirc\n");
+ class_unregister(&rc_class);
+ return 0;
+ }
+
led_trigger_register_simple("rc-feedback", &led_feedback);
rc_map_register(&empty_map);
@@ -1892,6 +1985,7 @@ static int __init rc_core_init(void)
static void __exit rc_core_exit(void)
{
+ lirc_dev_exit();
class_unregister(&rc_class);
led_trigger_unregister_simple(led_feedback);
rc_map_unregister(&empty_map);
@@ -1905,4 +1999,4 @@ EXPORT_SYMBOL_GPL(rc_core_debug);
module_param_named(debug, rc_core_debug, int, 0644);
MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 3ca7ab48293d..0adf0991f5ab 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -1044,7 +1044,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
data->irq = pnp_irq(device, 0);
if (data->wbase == 0 || data->ebase == 0 ||
- data->sbase == 0 || data->irq == 0) {
+ data->sbase == 0 || data->irq == -1) {
err = -ENODEV;
dev_err(dev, "Invalid resources\n");
goto exit_free_data;
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
index 05998f0254c6..6687514df97f 100644
--- a/drivers/media/tuners/Kconfig
+++ b/drivers/media/tuners/Kconfig
@@ -26,6 +26,13 @@ config MEDIA_TUNER_SIMPLE
help
Say Y here to include support for various simple tuners.
+config MEDIA_TUNER_TDA18250
+ tristate "NXP TDA18250 silicon tuner"
+ depends on MEDIA_SUPPORT && I2C
+ default m if !MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to include support for TDA18250 tuner.
+
config MEDIA_TUNER_TDA8290
tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
depends on MEDIA_SUPPORT && I2C
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile
index 7be96511532d..0ff21f1c7eed 100644
--- a/drivers/media/tuners/Makefile
+++ b/drivers/media/tuners/Makefile
@@ -42,6 +42,6 @@ obj-$(CONFIG_MEDIA_TUNER_R820T) += r820t.o
obj-$(CONFIG_MEDIA_TUNER_MXL301RF) += mxl301rf.o
obj-$(CONFIG_MEDIA_TUNER_QM1D1C0042) += qm1d1c0042.o
obj-$(CONFIG_MEDIA_TUNER_M88RS6000T) += m88rs6000t.o
+obj-$(CONFIG_MEDIA_TUNER_TDA18250) += tda18250.o
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/tuners/e4000.h b/drivers/media/tuners/e4000.h
index aa9340c05b43..9a65208c5bc3 100644
--- a/drivers/media/tuners/e4000.h
+++ b/drivers/media/tuners/e4000.h
@@ -21,7 +21,7 @@
#ifndef E4000_H
#define E4000_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/*
* I2C address
diff --git a/drivers/media/tuners/fc0011.h b/drivers/media/tuners/fc0011.h
index a36871c44c8c..ebae37cc6f5f 100644
--- a/drivers/media/tuners/fc0011.h
+++ b/drivers/media/tuners/fc0011.h
@@ -2,7 +2,7 @@
#ifndef LINUX_FC0011_H_
#define LINUX_FC0011_H_
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/** struct fc0011_config - fc0011 hardware config
diff --git a/drivers/media/tuners/fc0012.h b/drivers/media/tuners/fc0012.h
index 64d07a2adb2e..29e84c434de1 100644
--- a/drivers/media/tuners/fc0012.h
+++ b/drivers/media/tuners/fc0012.h
@@ -17,7 +17,7 @@
#ifndef _FC0012_H_
#define _FC0012_H_
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "fc001x-common.h"
struct fc0012_config {
diff --git a/drivers/media/tuners/fc0013.h b/drivers/media/tuners/fc0013.h
index 4431e7ceb43d..2d039250c783 100644
--- a/drivers/media/tuners/fc0013.h
+++ b/drivers/media/tuners/fc0013.h
@@ -18,7 +18,7 @@
#ifndef _FC0013_H_
#define _FC0013_H_
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "fc001x-common.h"
#if IS_REACHABLE(CONFIG_MEDIA_TUNER_FC0013)
diff --git a/drivers/media/tuners/fc2580.h b/drivers/media/tuners/fc2580.h
index 862ea46995d7..a04fba6b0b8a 100644
--- a/drivers/media/tuners/fc2580.h
+++ b/drivers/media/tuners/fc2580.h
@@ -21,7 +21,7 @@
#ifndef FC2580_H
#define FC2580_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include <media/v4l2-subdev.h>
#include <linux/i2c.h>
diff --git a/drivers/media/tuners/it913x.h b/drivers/media/tuners/it913x.h
index 226f657228fb..3cb219a4a645 100644
--- a/drivers/media/tuners/it913x.h
+++ b/drivers/media/tuners/it913x.h
@@ -19,7 +19,7 @@
#ifndef IT913X_H
#define IT913X_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/**
* struct it913x_platform_data - Platform data for the it913x driver
diff --git a/drivers/media/tuners/m88rs6000t.h b/drivers/media/tuners/m88rs6000t.h
index 264c13e2cd39..318b48c8f843 100644
--- a/drivers/media/tuners/m88rs6000t.h
+++ b/drivers/media/tuners/m88rs6000t.h
@@ -17,7 +17,7 @@
#ifndef _M88RS6000T_H_
#define _M88RS6000T_H_
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct m88rs6000t_config {
/*
diff --git a/drivers/media/tuners/max2165.c b/drivers/media/tuners/max2165.c
index a86c08114915..20ceb72e530b 100644
--- a/drivers/media/tuners/max2165.c
+++ b/drivers/media/tuners/max2165.c
@@ -23,7 +23,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "max2165.h"
#include "max2165_priv.h"
diff --git a/drivers/media/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c
index 12f545ef1243..403c6b2aa53b 100644
--- a/drivers/media/tuners/mc44s803.c
+++ b/drivers/media/tuners/mc44s803.c
@@ -21,7 +21,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mc44s803.h"
#include "mc44s803_priv.h"
diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c
index 4983eeb39f36..3d3c6815b6a7 100644
--- a/drivers/media/tuners/mt2060.c
+++ b/drivers/media/tuners/mt2060.c
@@ -23,7 +23,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mt2060.h"
#include "mt2060_priv.h"
diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c
index 5c87c5c6a455..80dc3e241b4a 100644
--- a/drivers/media/tuners/mt2063.c
+++ b/drivers/media/tuners/mt2063.c
@@ -1168,7 +1168,7 @@ static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
/*
* MT2063_SetReceiverMode() - Set the MT2063 receiver mode, according with
- * the selected enum mt2063_delivery_sys type.
+ * the selected enum mt2063_delivery_sys type.
*
* (DNC1GC & DNC2GC are the values, which are used, when the specific
* DNC Output is selected, the other is always off)
@@ -1544,7 +1544,7 @@ static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
* Save original LO1 and LO2 register values
*/
ofLO1 = state->AS_Data.f_LO1;
- ofLO2 = state->AS_Data.f_LO2;
+ ofLO2 = state->AS_Data.f_LO2;
/*
* Find and set RF Band setting
diff --git a/drivers/media/tuners/mt2063.h b/drivers/media/tuners/mt2063.h
index 0e3e3b0525bb..30d03cd76061 100644
--- a/drivers/media/tuners/mt2063.h
+++ b/drivers/media/tuners/mt2063.h
@@ -2,7 +2,7 @@
#ifndef __MT2063_H__
#define __MT2063_H__
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct mt2063_config {
u8 tuner_address;
diff --git a/drivers/media/tuners/mt20xx.h b/drivers/media/tuners/mt20xx.h
index 9912362b415e..3cc41a57dca9 100644
--- a/drivers/media/tuners/mt20xx.h
+++ b/drivers/media/tuners/mt20xx.h
@@ -18,7 +18,7 @@
#define __MT20XX_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#if IS_REACHABLE(CONFIG_MEDIA_TUNER_MT20XX)
extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/tuners/mt2131.c b/drivers/media/tuners/mt2131.c
index dd85d58fa8d0..659bf19dc434 100644
--- a/drivers/media/tuners/mt2131.c
+++ b/drivers/media/tuners/mt2131.c
@@ -21,7 +21,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mt2131.h"
#include "mt2131_priv.h"
diff --git a/drivers/media/tuners/mt2266.c b/drivers/media/tuners/mt2266.c
index 88edcc031e3c..f4545b7f5da2 100644
--- a/drivers/media/tuners/mt2266.c
+++ b/drivers/media/tuners/mt2266.c
@@ -20,7 +20,7 @@
#include <linux/i2c.h>
#include <linux/slab.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mt2266.h"
#define I2C_ADDRESS 0x60
diff --git a/drivers/media/tuners/mxl301rf.h b/drivers/media/tuners/mxl301rf.h
index 19e68405f00d..d32d4e8dc448 100644
--- a/drivers/media/tuners/mxl301rf.h
+++ b/drivers/media/tuners/mxl301rf.h
@@ -17,7 +17,7 @@
#ifndef MXL301RF_H
#define MXL301RF_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct mxl301rf_config {
struct dvb_frontend *fe;
diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c
index dd59c2c0e4a5..355ef2959b7d 100644
--- a/drivers/media/tuners/mxl5005s.c
+++ b/drivers/media/tuners/mxl5005s.c
@@ -63,7 +63,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mxl5005s.h"
static int debug;
@@ -1677,10 +1677,10 @@ static u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
u8 AGC_Mode, /* AGC Mode - Dual AGC: 0, Single AGC: 1 */
u16 TOP, /* 0: Dual AGC; Value: take over point */
u16 IF_OUT_LOAD, /* IF Out Load Resistor (200 / 300 Ohms) */
- u8 CLOCK_OUT, /* 0: turn off clk out; 1: turn on clock out */
+ u8 CLOCK_OUT, /* 0: turn off clk out; 1: turn on clock out */
u8 DIV_OUT, /* 0: Div-1; 1: Div-4 */
- u8 CAPSELECT, /* 0: disable On-Chip pulling cap; 1: enable */
- u8 EN_RSSI, /* 0: disable RSSI; 1: enable RSSI */
+ u8 CAPSELECT, /* 0: disable On-Chip pulling cap; 1: enable */
+ u8 EN_RSSI, /* 0: disable RSSI; 1: enable RSSI */
/* Modulation Type; */
/* 0 - Default; 1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
@@ -3591,10 +3591,11 @@ static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
u16 status = 0;
int i ;
- u8 RegAddr[] = {
+ static const u8 RegAddr[] = {
11, 12, 13, 22, 32, 43, 44, 53, 56, 59, 73,
76, 77, 91, 134, 135, 137, 147,
- 156, 166, 167, 168, 25 };
+ 156, 166, 167, 168, 25
+ };
*count = ARRAY_SIZE(RegAddr);
@@ -3616,11 +3617,15 @@ static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal,
/* add 77, 166, 167, 168 register for 2.6.12 */
#ifdef _MXL_PRODUCTION
- u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 65, 68, 69, 70, 73, 92, 93, 106,
- 107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
+ static const u8 RegAddr[] = {
+ 14, 15, 16, 17, 22, 43, 65, 68, 69, 70, 73, 92, 93, 106,
+ 107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168
+ };
#else
- u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 68, 69, 70, 73, 92, 93, 106,
- 107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
+ static const u8 RegAddr[] = {
+ 14, 15, 16, 17, 22, 43, 68, 69, 70, 73, 92, 93, 106,
+ 107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168
+ };
/*
u8 RegAddr[171];
for (i = 0; i <= 170; i++)
diff --git a/drivers/media/tuners/mxl5005s.h b/drivers/media/tuners/mxl5005s.h
index d842734f2dcd..9ac0811a162e 100644
--- a/drivers/media/tuners/mxl5005s.h
+++ b/drivers/media/tuners/mxl5005s.h
@@ -24,7 +24,7 @@
#define __MXL5005S_H
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct mxl5005s_config {
diff --git a/drivers/media/tuners/mxl5007t.h b/drivers/media/tuners/mxl5007t.h
index 273f61aeb8be..f7f16b86fcae 100644
--- a/drivers/media/tuners/mxl5007t.h
+++ b/drivers/media/tuners/mxl5007t.h
@@ -17,7 +17,7 @@
#ifndef __MXL5007T_H__
#define __MXL5007T_H__
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/* ------------------------------------------------------------------------- */
diff --git a/drivers/media/tuners/qm1d1c0042.h b/drivers/media/tuners/qm1d1c0042.h
index 4f5c18816c44..8331f8baa094 100644
--- a/drivers/media/tuners/qm1d1c0042.h
+++ b/drivers/media/tuners/qm1d1c0042.h
@@ -17,7 +17,7 @@
#ifndef QM1D1C0042_H
#define QM1D1C0042_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct qm1d1c0042_config {
diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c
index ee33b7cc7682..b92be882ab3c 100644
--- a/drivers/media/tuners/qt1010.c
+++ b/drivers/media/tuners/qt1010.c
@@ -224,7 +224,7 @@ static int qt1010_set_params(struct dvb_frontend *fe)
static int qt1010_init_meas1(struct qt1010_priv *priv,
u8 oper, u8 reg, u8 reg_init_val, u8 *retval)
{
- u8 i, val1, val2;
+ u8 i, val1, uninitialized_var(val2);
int err;
qt1010_i2c_oper_t i2c_data[] = {
@@ -259,7 +259,7 @@ static int qt1010_init_meas1(struct qt1010_priv *priv,
static int qt1010_init_meas2(struct qt1010_priv *priv,
u8 reg_init_val, u8 *retval)
{
- u8 i, val;
+ u8 i, uninitialized_var(val);
int err;
qt1010_i2c_oper_t i2c_data[] = {
{ QT1010_WR, 0x07, reg_init_val },
diff --git a/drivers/media/tuners/qt1010.h b/drivers/media/tuners/qt1010.h
index 276e59e85032..24216c2a8154 100644
--- a/drivers/media/tuners/qt1010.h
+++ b/drivers/media/tuners/qt1010.h
@@ -18,7 +18,7 @@
#ifndef QT1010_H
#define QT1010_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct qt1010_config {
u8 i2c_address;
diff --git a/drivers/media/tuners/r820t.c b/drivers/media/tuners/r820t.c
index ba80376a3b86..bc9299059f48 100644
--- a/drivers/media/tuners/r820t.c
+++ b/drivers/media/tuners/r820t.c
@@ -1,36 +1,24 @@
-/*
- * Rafael Micro R820T driver
- *
- * Copyright (C) 2013 Mauro Carvalho Chehab
- *
- * This driver was written from scratch, based on an existing driver
- * that it is part of rtl-sdr git tree, released under GPLv2:
- * https://groups.google.com/forum/#!topic/ultra-cheap-sdr/Y3rBEOFtHug
- * https://github.com/n1gp/gr-baz
- *
- * From what I understood from the threads, the original driver was converted
- * to userspace from a Realtek tree. I couldn't find the original tree.
- * However, the original driver look awkward on my eyes. So, I decided to
- * write a new version from it from the scratch, while trying to reproduce
- * everything found there.
- *
- * TODO:
- * After locking, the original driver seems to have some routines to
- * improve reception. This was not implemented here yet.
- *
- * RF Gain set/get is not implemented.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
+// SPDX-License-Identifier: GPL-2.0
+// Rafael Micro R820T driver
+//
+// Copyright (C) 2013 Mauro Carvalho Chehab
+//
+// This driver was written from scratch, based on an existing driver
+// that it is part of rtl-sdr git tree, released under GPLv2:
+// https://groups.google.com/forum/#!topic/ultra-cheap-sdr/Y3rBEOFtHug
+// https://github.com/n1gp/gr-baz
+//
+// From what I understood from the threads, the original driver was converted
+// to userspace from a Realtek tree. I couldn't find the original tree.
+// However, the original driver look awkward on my eyes. So, I decided to
+// write a new version from it from the scratch, while trying to reproduce
+// everything found there.
+//
+// TODO:
+// After locking, the original driver seems to have some routines to
+// improve reception. This was not implemented here yet.
+//
+// RF Gain set/get is not implemented.
#include <linux/videodev2.h>
#include <linux/mutex.h>
@@ -396,9 +384,11 @@ static int r820t_write(struct r820t_priv *priv, u8 reg, const u8 *val,
return 0;
}
-static int r820t_write_reg(struct r820t_priv *priv, u8 reg, u8 val)
+static inline int r820t_write_reg(struct r820t_priv *priv, u8 reg, u8 val)
{
- return r820t_write(priv, reg, &val, 1);
+ u8 tmp = val; /* work around GCC PR81715 with asan-stack=1 */
+
+ return r820t_write(priv, reg, &tmp, 1);
}
static int r820t_read_cache_reg(struct r820t_priv *priv, int reg)
@@ -411,17 +401,18 @@ static int r820t_read_cache_reg(struct r820t_priv *priv, int reg)
return -EINVAL;
}
-static int r820t_write_reg_mask(struct r820t_priv *priv, u8 reg, u8 val,
+static inline int r820t_write_reg_mask(struct r820t_priv *priv, u8 reg, u8 val,
u8 bit_mask)
{
+ u8 tmp = val;
int rc = r820t_read_cache_reg(priv, reg);
if (rc < 0)
return rc;
- val = (rc & ~bit_mask) | (val & bit_mask);
+ tmp = (rc & ~bit_mask) | (tmp & bit_mask);
- return r820t_write(priv, reg, &val, 1);
+ return r820t_write(priv, reg, &tmp, 1);
}
static int r820t_read(struct r820t_priv *priv, u8 reg, u8 *val, int len)
@@ -2388,4 +2379,4 @@ EXPORT_SYMBOL_GPL(r820t_attach);
MODULE_DESCRIPTION("Rafael Micro r820t silicon tuner driver");
MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/tuners/r820t.h b/drivers/media/tuners/r820t.h
index fdcab91405de..4f91dbb29c3a 100644
--- a/drivers/media/tuners/r820t.h
+++ b/drivers/media/tuners/r820t.h
@@ -21,7 +21,7 @@
#ifndef R820T_H
#define R820T_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
enum r820t_chip {
CHIP_R820T,
diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c
index e35b1faf0ddc..9e34d31d724d 100644
--- a/drivers/media/tuners/si2157.c
+++ b/drivers/media/tuners/si2157.c
@@ -532,7 +532,7 @@ MODULE_DEVICE_TABLE(i2c, si2157_id_table);
static struct i2c_driver si2157_driver = {
.driver = {
- .name = "si2157",
+ .name = "si2157",
.suppress_bind_attrs = true,
},
.probe = si2157_probe,
diff --git a/drivers/media/tuners/si2157.h b/drivers/media/tuners/si2157.h
index 76807f5b3cf8..de597fa47db6 100644
--- a/drivers/media/tuners/si2157.h
+++ b/drivers/media/tuners/si2157.h
@@ -18,7 +18,7 @@
#define SI2157_H
#include <media/media-device.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/*
* I2C address
diff --git a/drivers/media/tuners/tda18212.h b/drivers/media/tuners/tda18212.h
index 6391dafd0c9d..9ed4367c21fc 100644
--- a/drivers/media/tuners/tda18212.h
+++ b/drivers/media/tuners/tda18212.h
@@ -21,7 +21,7 @@
#ifndef TDA18212_H
#define TDA18212_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct tda18212_config {
u16 if_dvbt_6;
diff --git a/drivers/media/tuners/tda18218.h b/drivers/media/tuners/tda18218.h
index 9c0e3fd7ed7f..0427c6f34c40 100644
--- a/drivers/media/tuners/tda18218.h
+++ b/drivers/media/tuners/tda18218.h
@@ -17,7 +17,7 @@
#ifndef TDA18218_H
#define TDA18218_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct tda18218_config {
u8 i2c_address;
diff --git a/drivers/media/tuners/tda18250.c b/drivers/media/tuners/tda18250.c
new file mode 100644
index 000000000000..20d12b063380
--- /dev/null
+++ b/drivers/media/tuners/tda18250.c
@@ -0,0 +1,902 @@
+/*
+ * NXP TDA18250 silicon tuner driver
+ *
+ * Copyright (C) 2017 Olli Salonen <olli.salonen@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "tda18250_priv.h"
+#include <linux/regmap.h>
+
+static const struct dvb_tuner_ops tda18250_ops;
+
+static int tda18250_power_control(struct dvb_frontend *fe,
+ unsigned int power_state)
+{
+ struct i2c_client *client = fe->tuner_priv;
+ struct tda18250_dev *dev = i2c_get_clientdata(client);
+ int ret;
+ unsigned int utmp;
+
+ dev_dbg(&client->dev, "power state: %d", power_state);
+
+ switch (power_state) {
+ case TDA18250_POWER_NORMAL:
+ ret = regmap_write_bits(dev->regmap, R06_POWER2, 0x07, 0x00);
+ if (ret)
+ goto err;
+ ret = regmap_write_bits(dev->regmap, R25_REF, 0xc0, 0xc0);
+ if (ret)
+ goto err;
+ break;
+ case TDA18250_POWER_STANDBY:
+ if (dev->loopthrough) {
+ ret = regmap_write_bits(dev->regmap,
+ R25_REF, 0xc0, 0x80);
+ if (ret)
+ goto err;
+ ret = regmap_write_bits(dev->regmap,
+ R06_POWER2, 0x07, 0x02);
+ if (ret)
+ goto err;
+ ret = regmap_write_bits(dev->regmap,
+ R10_LT1, 0x80, 0x00);
+ if (ret)
+ goto err;
+ } else {
+ ret = regmap_write_bits(dev->regmap,
+ R25_REF, 0xc0, 0x80);
+ if (ret)
+ goto err;
+ ret = regmap_write_bits(dev->regmap,
+ R06_POWER2, 0x07, 0x01);
+ if (ret)
+ goto err;
+ ret = regmap_read(dev->regmap,
+ R0D_AGC12, &utmp);
+ if (ret)
+ goto err;
+ ret = regmap_write_bits(dev->regmap,
+ R0D_AGC12, 0x03, 0x03);
+ if (ret)
+ goto err;
+ ret = regmap_write_bits(dev->regmap,
+ R10_LT1, 0x80, 0x80);
+ if (ret)
+ goto err;
+ ret = regmap_write_bits(dev->regmap,
+ R0D_AGC12, 0x03, utmp & 0x03);
+ if (ret)
+ goto err;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ goto err;
+ }
+
+ return 0;
+err:
+ return ret;
+}
+
+static int tda18250_wait_for_irq(struct dvb_frontend *fe,
+ int maxwait, int step, u8 irq)
+{
+ struct i2c_client *client = fe->tuner_priv;
+ struct tda18250_dev *dev = i2c_get_clientdata(client);
+ int ret;
+ unsigned long timeout;
+ bool triggered;
+ unsigned int utmp;
+
+ triggered = false;
+ timeout = jiffies + msecs_to_jiffies(maxwait);
+ while (!time_after(jiffies, timeout)) {
+ // check for the IRQ
+ ret = regmap_read(dev->regmap, R08_IRQ1, &utmp);
+ if (ret)
+ goto err;
+ if ((utmp & irq) == irq) {
+ triggered = true;
+ break;
+ }
+ msleep(step);
+ }
+
+ dev_dbg(&client->dev, "waited IRQ (0x%02x) %d ms, triggered: %s", irq,
+ jiffies_to_msecs(jiffies) -
+ (jiffies_to_msecs(timeout) - maxwait),
+ triggered ? "true" : "false");
+
+ if (!triggered)
+ return -ETIMEDOUT;
+
+ return 0;
+err:
+ return ret;
+}
+
+static int tda18250_init(struct dvb_frontend *fe)
+{
+ struct i2c_client *client = fe->tuner_priv;
+ struct tda18250_dev *dev = i2c_get_clientdata(client);
+ int ret, i;
+
+ /* default values for various regs */
+ static const u8 init_regs[][2] = {
+ { R0C_AGC11, 0xc7 },
+ { R0D_AGC12, 0x5d },
+ { R0E_AGC13, 0x40 },
+ { R0F_AGC14, 0x0e },
+ { R10_LT1, 0x47 },
+ { R11_LT2, 0x4e },
+ { R12_AGC21, 0x26 },
+ { R13_AGC22, 0x60 },
+ { R18_AGC32, 0x37 },
+ { R19_AGC33, 0x09 },
+ { R1A_AGCK, 0x00 },
+ { R1E_WI_FI, 0x29 },
+ { R1F_RF_BPF, 0x06 },
+ { R20_IR_MIX, 0xc6 },
+ { R21_IF_AGC, 0x00 },
+ { R2C_PS1, 0x75 },
+ { R2D_PS2, 0x06 },
+ { R2E_PS3, 0x07 },
+ { R30_RSSI2, 0x0e },
+ { R31_IRQ_CTRL, 0x00 },
+ { R39_SD5, 0x00 },
+ { R3B_REGU, 0x55 },
+ { R3C_RCCAL1, 0xa7 },
+ { R3F_IRCAL2, 0x85 },
+ { R40_IRCAL3, 0x87 },
+ { R41_IRCAL4, 0xc0 },
+ { R43_PD1, 0x40 },
+ { R44_PD2, 0xc0 },
+ { R46_CPUMP, 0x0c },
+ { R47_LNAPOL, 0x64 },
+ { R4B_XTALOSC1, 0x30 },
+ { R59_AGC2_UP2, 0x05 },
+ { R5B_AGC_AUTO, 0x07 },
+ { R5C_AGC_DEBUG, 0x00 },
+ };
+
+ /* crystal related regs depend on frequency */
+ static const u8 xtal_regs[][5] = {
+ /* reg: 4d 4e 4f 50 51 */
+ [TDA18250_XTAL_FREQ_16MHZ] = { 0x3e, 0x80, 0x50, 0x00, 0x20 },
+ [TDA18250_XTAL_FREQ_24MHZ] = { 0x5d, 0xc0, 0xec, 0x00, 0x18 },
+ [TDA18250_XTAL_FREQ_25MHZ] = { 0x61, 0xa8, 0xec, 0x80, 0x19 },
+ [TDA18250_XTAL_FREQ_27MHZ] = { 0x69, 0x78, 0x8d, 0x80, 0x1b },
+ [TDA18250_XTAL_FREQ_30MHZ] = { 0x75, 0x30, 0x8f, 0x00, 0x1e },
+ };
+
+ dev_dbg(&client->dev, "\n");
+
+ ret = tda18250_power_control(fe, TDA18250_POWER_NORMAL);
+ if (ret)
+ goto err;
+
+ msleep(20);
+
+ if (dev->warm)
+ goto warm;
+
+ /* set initial register values */
+ for (i = 0; i < ARRAY_SIZE(init_regs); i++) {
+ ret = regmap_write(dev->regmap, init_regs[i][0],
+ init_regs[i][1]);
+ if (ret)
+ goto err;
+ }
+
+ /* set xtal related regs */
+ ret = regmap_bulk_write(dev->regmap, R4D_XTALFLX1,
+ xtal_regs[dev->xtal_freq], 5);
+ if (ret)
+ goto err;
+
+ ret = regmap_write_bits(dev->regmap, R10_LT1, 0x80,
+ dev->loopthrough ? 0x00 : 0x80);
+ if (ret)
+ goto err;
+
+ /* clear IRQ */
+ ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_HW_INIT);
+ if (ret)
+ goto err;
+
+ /* start HW init */
+ ret = regmap_write(dev->regmap, R2A_MSM1, 0x70);
+ if (ret)
+ goto err;
+
+ ret = regmap_write(dev->regmap, R2B_MSM2, 0x01);
+ if (ret)
+ goto err;
+
+ ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_HW_INIT);
+ if (ret)
+ goto err;
+
+ /* tuner calibration */
+ ret = regmap_write(dev->regmap, R2A_MSM1, 0x02);
+ if (ret)
+ goto err;
+
+ ret = regmap_write(dev->regmap, R2B_MSM2, 0x01);
+ if (ret)
+ goto err;
+
+ ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_CAL);
+ if (ret)
+ goto err;
+
+ dev->warm = true;
+
+warm:
+ /* power up LNA */
+ ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x80, 0x00);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ dev_dbg(&client->dev, "failed=%d", ret);
+ return ret;
+}
+
+static int tda18250_set_agc(struct dvb_frontend *fe)
+{
+ struct i2c_client *client = fe->tuner_priv;
+ struct tda18250_dev *dev = i2c_get_clientdata(client);
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int ret;
+ u8 utmp, utmp2;
+
+ dev_dbg(&client->dev, "\n");
+
+ ret = regmap_write_bits(dev->regmap, R1F_RF_BPF, 0x87, 0x06);
+ if (ret)
+ goto err;
+
+ utmp = ((c->frequency < 100000000) &&
+ ((c->delivery_system == SYS_DVBC_ANNEX_A) ||
+ (c->delivery_system == SYS_DVBC_ANNEX_C)) &&
+ (c->bandwidth_hz == 6000000)) ? 0x80 : 0x00;
+ ret = regmap_write(dev->regmap, R5A_H3H5, utmp);
+ if (ret)
+ goto err;
+
+ /* AGC1 */
+ switch (c->delivery_system) {
+ case SYS_ATSC:
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ utmp = 4;
+ break;
+ default: /* DVB-C/QAM */
+ switch (c->bandwidth_hz) {
+ case 6000000:
+ utmp = (c->frequency < 800000000) ? 6 : 4;
+ break;
+ default: /* 7.935 and 8 MHz */
+ utmp = (c->frequency < 100000000) ? 2 : 3;
+ break;
+ }
+ break;
+ }
+
+ ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x07, utmp);
+ if (ret)
+ goto err;
+
+ /* AGC2 */
+ switch (c->delivery_system) {
+ case SYS_ATSC:
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ utmp = (c->frequency < 320000000) ? 20 : 16;
+ utmp2 = (c->frequency < 320000000) ? 22 : 18;
+ break;
+ default: /* DVB-C/QAM */
+ switch (c->bandwidth_hz) {
+ case 6000000:
+ if (c->frequency < 600000000) {
+ utmp = 18;
+ utmp2 = 22;
+ } else if (c->frequency < 800000000) {
+ utmp = 16;
+ utmp2 = 20;
+ } else {
+ utmp = 14;
+ utmp2 = 16;
+ }
+ break;
+ default: /* 7.935 and 8 MHz */
+ utmp = (c->frequency < 320000000) ? 16 : 18;
+ utmp2 = (c->frequency < 320000000) ? 18 : 20;
+ break;
+ }
+ break;
+ }
+ ret = regmap_write_bits(dev->regmap, R58_AGC2_UP1, 0x1f, utmp2+8);
+ if (ret)
+ goto err;
+ ret = regmap_write_bits(dev->regmap, R13_AGC22, 0x1f, utmp);
+ if (ret)
+ goto err;
+ ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x1f, utmp2);
+ if (ret)
+ goto err;
+
+ switch (c->delivery_system) {
+ case SYS_ATSC:
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ utmp = 98;
+ break;
+ default: /* DVB-C/QAM */
+ utmp = 90;
+ break;
+ }
+ ret = regmap_write_bits(dev->regmap, R16_AGC25, 0xf8, utmp);
+ if (ret)
+ goto err;
+
+ ret = regmap_write_bits(dev->regmap, R12_AGC21, 0x60,
+ (c->frequency > 800000000) ? 0x40 : 0x20);
+ if (ret)
+ goto err;
+
+ /* AGC3 */
+ switch (c->delivery_system) {
+ case SYS_ATSC:
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ utmp = (c->frequency < 320000000) ? 5 : 7;
+ utmp2 = (c->frequency < 320000000) ? 10 : 12;
+ break;
+ default: /* DVB-C/QAM */
+ utmp = 7;
+ utmp2 = 12;
+ break;
+ }
+ ret = regmap_write(dev->regmap, R17_AGC31, (utmp << 4) | utmp2);
+ if (ret)
+ goto err;
+
+ /* S2D */
+ switch (c->delivery_system) {
+ case SYS_ATSC:
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ if (c->bandwidth_hz == 8000000)
+ utmp = 0x04;
+ else
+ utmp = (c->frequency < 320000000) ? 0x04 : 0x02;
+ break;
+ default: /* DVB-C/QAM */
+ if (c->bandwidth_hz == 6000000)
+ utmp = ((c->frequency > 172544000) &&
+ (c->frequency < 320000000)) ? 0x04 : 0x02;
+ else /* 7.935 and 8 MHz */
+ utmp = ((c->frequency > 320000000) &&
+ (c->frequency < 600000000)) ? 0x02 : 0x04;
+ break;
+ }
+ ret = regmap_write_bits(dev->regmap, R20_IR_MIX, 0x06, utmp);
+ if (ret)
+ goto err;
+
+ switch (c->delivery_system) {
+ case SYS_ATSC:
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ utmp = 0;
+ break;
+ default: /* DVB-C/QAM */
+ utmp = (c->frequency < 600000000) ? 0 : 3;
+ break;
+ }
+ ret = regmap_write_bits(dev->regmap, R16_AGC25, 0x03, utmp);
+ if (ret)
+ goto err;
+
+ utmp = 0x09;
+ switch (c->delivery_system) {
+ case SYS_ATSC:
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ if (c->bandwidth_hz == 8000000)
+ utmp = 0x0c;
+ break;
+ default: /* DVB-C/QAM */
+ utmp = 0x0c;
+ break;
+ }
+ ret = regmap_write_bits(dev->regmap, R0F_AGC14, 0x3f, utmp);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ dev_dbg(&client->dev, "failed=%d", ret);
+ return ret;
+}
+
+static int tda18250_pll_calc(struct dvb_frontend *fe, u8 *rdiv,
+ u8 *ndiv, u8 *icp)
+{
+ struct i2c_client *client = fe->tuner_priv;
+ struct tda18250_dev *dev = i2c_get_clientdata(client);
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ int ret;
+ unsigned int uval, exp, lopd, scale;
+ unsigned long fvco;
+
+ ret = regmap_read(dev->regmap, R34_MD1, &uval);
+ if (ret)
+ goto err;
+
+ exp = (uval & 0x70) >> 4;
+ if (exp > 5)
+ exp = 0;
+ lopd = 1 << (exp - 1);
+ scale = uval & 0x0f;
+ fvco = lopd * scale * ((c->frequency / 1000) + dev->if_frequency);
+
+ switch (dev->xtal_freq) {
+ case TDA18250_XTAL_FREQ_16MHZ:
+ *rdiv = 1;
+ *ndiv = 0;
+ *icp = (fvco < 6622000) ? 0x05 : 0x02;
+ break;
+ case TDA18250_XTAL_FREQ_24MHZ:
+ case TDA18250_XTAL_FREQ_25MHZ:
+ *rdiv = 3;
+ *ndiv = 1;
+ *icp = (fvco < 6622000) ? 0x05 : 0x02;
+ break;
+ case TDA18250_XTAL_FREQ_27MHZ:
+ if (fvco < 6643000) {
+ *rdiv = 2;
+ *ndiv = 0;
+ *icp = 0x05;
+ } else if (fvco < 6811000) {
+ *rdiv = 2;
+ *ndiv = 0;
+ *icp = 0x06;
+ } else {
+ *rdiv = 3;
+ *ndiv = 1;
+ *icp = 0x02;
+ }
+ break;
+ case TDA18250_XTAL_FREQ_30MHZ:
+ *rdiv = 2;
+ *ndiv = 0;
+ *icp = (fvco < 6811000) ? 0x05 : 0x02;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ dev_dbg(&client->dev,
+ "lopd=%d scale=%u fvco=%lu, rdiv=%d ndiv=%d icp=%d",
+ lopd, scale, fvco, *rdiv, *ndiv, *icp);
+ return 0;
+err:
+ return ret;
+}
+
+static int tda18250_set_params(struct dvb_frontend *fe)
+{
+ struct i2c_client *client = fe->tuner_priv;
+ struct tda18250_dev *dev = i2c_get_clientdata(client);
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u32 if_khz;
+ int ret;
+ unsigned int i, j;
+ u8 utmp;
+ u8 buf[3];
+
+ #define REG 0
+ #define MASK 1
+ #define DVBT_6 2
+ #define DVBT_7 3
+ #define DVBT_8 4
+ #define DVBC_6 5
+ #define DVBC_8 6
+ #define ATSC 7
+
+ static const u8 delsys_params[][16] = {
+ [REG] = { 0x22, 0x23, 0x24, 0x21, 0x0d, 0x0c, 0x0f, 0x14,
+ 0x0e, 0x12, 0x58, 0x59, 0x1a, 0x19, 0x1e, 0x30 },
+ [MASK] = { 0x77, 0xff, 0xff, 0x87, 0xf0, 0x78, 0x07, 0xe0,
+ 0x60, 0x0f, 0x60, 0x0f, 0x33, 0x30, 0x80, 0x06 },
+ [DVBT_6] = { 0x51, 0x03, 0x83, 0x82, 0x40, 0x48, 0x01, 0xe0,
+ 0x60, 0x0f, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 },
+ [DVBT_7] = { 0x52, 0x03, 0x85, 0x82, 0x40, 0x48, 0x01, 0xe0,
+ 0x60, 0x0f, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 },
+ [DVBT_8] = { 0x53, 0x03, 0x87, 0x82, 0x40, 0x48, 0x06, 0xe0,
+ 0x60, 0x07, 0x60, 0x05, 0x03, 0x10, 0x00, 0x04 },
+ [DVBC_6] = { 0x32, 0x05, 0x86, 0x82, 0x50, 0x00, 0x06, 0x60,
+ 0x40, 0x0e, 0x60, 0x05, 0x33, 0x10, 0x00, 0x04 },
+ [DVBC_8] = { 0x53, 0x03, 0x88, 0x82, 0x50, 0x00, 0x06, 0x60,
+ 0x40, 0x0e, 0x60, 0x05, 0x33, 0x10, 0x00, 0x04 },
+ [ATSC] = { 0x51, 0x03, 0x83, 0x82, 0x40, 0x48, 0x01, 0xe0,
+ 0x40, 0x0e, 0x60, 0x05, 0x03, 0x00, 0x80, 0x04 },
+ };
+
+ dev_dbg(&client->dev,
+ "delivery_system=%d frequency=%u bandwidth_hz=%u",
+ c->delivery_system, c->frequency, c->bandwidth_hz);
+
+
+ switch (c->delivery_system) {
+ case SYS_ATSC:
+ j = ATSC;
+ if_khz = dev->if_atsc;
+ break;
+ case SYS_DVBT:
+ case SYS_DVBT2:
+ if (c->bandwidth_hz == 0) {
+ ret = -EINVAL;
+ goto err;
+ } else if (c->bandwidth_hz <= 6000000) {
+ j = DVBT_6;
+ if_khz = dev->if_dvbt_6;
+ } else if (c->bandwidth_hz <= 7000000) {
+ j = DVBT_7;
+ if_khz = dev->if_dvbt_7;
+ } else if (c->bandwidth_hz <= 8000000) {
+ j = DVBT_8;
+ if_khz = dev->if_dvbt_8;
+ } else {
+ ret = -EINVAL;
+ goto err;
+ }
+ break;
+ case SYS_DVBC_ANNEX_A:
+ case SYS_DVBC_ANNEX_C:
+ if (c->bandwidth_hz == 0) {
+ ret = -EINVAL;
+ goto err;
+ } else if (c->bandwidth_hz <= 6000000) {
+ j = DVBC_6;
+ if_khz = dev->if_dvbc_6;
+ } else if (c->bandwidth_hz <= 8000000) {
+ j = DVBC_8;
+ if_khz = dev->if_dvbc_8;
+ } else {
+ ret = -EINVAL;
+ goto err;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ dev_err(&client->dev, "unsupported delivery system=%d",
+ c->delivery_system);
+ goto err;
+ }
+
+ /* set delivery system dependent registers */
+ for (i = 0; i < 16; i++) {
+ ret = regmap_write_bits(dev->regmap, delsys_params[REG][i],
+ delsys_params[MASK][i], delsys_params[j][i]);
+ if (ret)
+ goto err;
+ }
+
+ /* set IF if needed */
+ if (dev->if_frequency != if_khz) {
+ utmp = DIV_ROUND_CLOSEST(if_khz, 50);
+ ret = regmap_write(dev->regmap, R26_IF, utmp);
+ if (ret)
+ goto err;
+ dev->if_frequency = if_khz;
+ dev_dbg(&client->dev, "set IF=%u kHz", if_khz);
+
+ }
+
+ ret = tda18250_set_agc(fe);
+ if (ret)
+ goto err;
+
+ ret = regmap_write_bits(dev->regmap, R1A_AGCK, 0x03, 0x01);
+ if (ret)
+ goto err;
+
+ ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x40, 0x00);
+ if (ret)
+ goto err;
+
+ /* set frequency */
+ buf[0] = ((c->frequency / 1000) >> 16) & 0xff;
+ buf[1] = ((c->frequency / 1000) >> 8) & 0xff;
+ buf[2] = ((c->frequency / 1000) >> 0) & 0xff;
+ ret = regmap_bulk_write(dev->regmap, R27_RF1, buf, 3);
+ if (ret)
+ goto err;
+
+ ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_TUNE);
+ if (ret)
+ goto err;
+
+ /* initial tune */
+ ret = regmap_write(dev->regmap, R2A_MSM1, 0x01);
+ if (ret)
+ goto err;
+
+ ret = regmap_write(dev->regmap, R2B_MSM2, 0x01);
+ if (ret)
+ goto err;
+
+ ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_TUNE);
+ if (ret)
+ goto err;
+
+ /* calc ndiv and rdiv */
+ ret = tda18250_pll_calc(fe, &buf[0], &buf[1], &buf[2]);
+ if (ret)
+ goto err;
+
+ ret = regmap_write_bits(dev->regmap, R4F_XTALFLX3, 0xe0,
+ (buf[0] << 6) | (buf[1] << 5));
+ if (ret)
+ goto err;
+
+ /* clear IRQ */
+ ret = regmap_write(dev->regmap, R0A_IRQ3, TDA18250_IRQ_TUNE);
+ if (ret)
+ goto err;
+
+ ret = regmap_write_bits(dev->regmap, R46_CPUMP, 0x07, 0x00);
+ if (ret)
+ goto err;
+
+ ret = regmap_write_bits(dev->regmap, R39_SD5, 0x03, 0x00);
+ if (ret)
+ goto err;
+
+ /* tune again */
+ ret = regmap_write(dev->regmap, R2A_MSM1, 0x01); /* tune */
+ if (ret)
+ goto err;
+
+ ret = regmap_write(dev->regmap, R2B_MSM2, 0x01); /* go */
+ if (ret)
+ goto err;
+
+ ret = tda18250_wait_for_irq(fe, 500, 10, TDA18250_IRQ_TUNE);
+ if (ret)
+ goto err;
+
+ /* pll locking */
+ msleep(20);
+
+ ret = regmap_write_bits(dev->regmap, R2B_MSM2, 0x04, 0x04);
+ if (ret)
+ goto err;
+
+ msleep(20);
+
+ /* restore AGCK */
+ ret = regmap_write_bits(dev->regmap, R1A_AGCK, 0x03, 0x03);
+ if (ret)
+ goto err;
+
+ ret = regmap_write_bits(dev->regmap, R14_AGC23, 0x40, 0x40);
+ if (ret)
+ goto err;
+
+ /* charge pump */
+ ret = regmap_write_bits(dev->regmap, R46_CPUMP, 0x07, buf[2]);
+
+ return 0;
+err:
+ return ret;
+}
+
+static int tda18250_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct i2c_client *client = fe->tuner_priv;
+ struct tda18250_dev *dev = i2c_get_clientdata(client);
+
+ *frequency = dev->if_frequency * 1000;
+ return 0;
+}
+
+static int tda18250_sleep(struct dvb_frontend *fe)
+{
+ struct i2c_client *client = fe->tuner_priv;
+ struct tda18250_dev *dev = i2c_get_clientdata(client);
+ int ret;
+
+ dev_dbg(&client->dev, "\n");
+
+ /* power down LNA */
+ ret = regmap_write_bits(dev->regmap, R0C_AGC11, 0x80, 0x00);
+ if (ret)
+ return ret;
+
+ /* set if freq to 0 in order to make sure it's set after wake up */
+ dev->if_frequency = 0;
+
+ ret = tda18250_power_control(fe, TDA18250_POWER_STANDBY);
+ return ret;
+}
+
+static const struct dvb_tuner_ops tda18250_ops = {
+ .info = {
+ .name = "NXP TDA18250",
+ .frequency_min = 42000000,
+ .frequency_max = 870000000,
+ },
+
+ .init = tda18250_init,
+ .set_params = tda18250_set_params,
+ .get_if_frequency = tda18250_get_if_frequency,
+ .sleep = tda18250_sleep,
+};
+
+static int tda18250_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct tda18250_config *cfg = client->dev.platform_data;
+ struct dvb_frontend *fe = cfg->fe;
+ struct tda18250_dev *dev;
+ int ret;
+ unsigned char chip_id[3];
+
+ /* some registers are always read from HW */
+ static const struct regmap_range tda18250_yes_ranges[] = {
+ regmap_reg_range(R05_POWER1, R0B_IRQ4),
+ regmap_reg_range(R21_IF_AGC, R21_IF_AGC),
+ regmap_reg_range(R2A_MSM1, R2B_MSM2),
+ regmap_reg_range(R2F_RSSI1, R31_IRQ_CTRL),
+ };
+
+ static const struct regmap_access_table tda18250_volatile_table = {
+ .yes_ranges = tda18250_yes_ranges,
+ .n_yes_ranges = ARRAY_SIZE(tda18250_yes_ranges),
+ };
+
+ static const struct regmap_config tda18250_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = TDA18250_NUM_REGS - 1,
+ .volatile_table = &tda18250_volatile_table,
+ };
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ i2c_set_clientdata(client, dev);
+
+ dev->fe = cfg->fe;
+ dev->loopthrough = cfg->loopthrough;
+ if (cfg->xtal_freq < TDA18250_XTAL_FREQ_MAX) {
+ dev->xtal_freq = cfg->xtal_freq;
+ } else {
+ ret = -EINVAL;
+ dev_err(&client->dev, "xtal_freq invalid=%d", cfg->xtal_freq);
+ goto err_kfree;
+ }
+ dev->if_dvbt_6 = cfg->if_dvbt_6;
+ dev->if_dvbt_7 = cfg->if_dvbt_7;
+ dev->if_dvbt_8 = cfg->if_dvbt_8;
+ dev->if_dvbc_6 = cfg->if_dvbc_6;
+ dev->if_dvbc_8 = cfg->if_dvbc_8;
+ dev->if_atsc = cfg->if_atsc;
+
+ dev->if_frequency = 0;
+ dev->warm = false;
+
+ dev->regmap = devm_regmap_init_i2c(client, &tda18250_regmap_config);
+ if (IS_ERR(dev->regmap)) {
+ ret = PTR_ERR(dev->regmap);
+ goto err_kfree;
+ }
+
+ /* read the three chip ID registers */
+ regmap_bulk_read(dev->regmap, R00_ID1, &chip_id, 3);
+ dev_dbg(&client->dev, "chip_id=%02x:%02x:%02x",
+ chip_id[0], chip_id[1], chip_id[2]);
+
+ switch (chip_id[0]) {
+ case 0xc7:
+ dev->slave = false;
+ break;
+ case 0x47:
+ dev->slave = true;
+ break;
+ default:
+ ret = -ENODEV;
+ goto err_kfree;
+ }
+
+ if (chip_id[1] != 0x4a) {
+ ret = -ENODEV;
+ goto err_kfree;
+ }
+
+ switch (chip_id[2]) {
+ case 0x20:
+ dev_info(&client->dev,
+ "NXP TDA18250AHN/%s successfully identified",
+ dev->slave ? "S" : "M");
+ break;
+ case 0x21:
+ dev_info(&client->dev,
+ "NXP TDA18250BHN/%s successfully identified",
+ dev->slave ? "S" : "M");
+ break;
+ default:
+ ret = -ENODEV;
+ goto err_kfree;
+ }
+
+ fe->tuner_priv = client;
+ memcpy(&fe->ops.tuner_ops, &tda18250_ops,
+ sizeof(struct dvb_tuner_ops));
+
+ /* put the tuner in standby */
+ tda18250_power_control(fe, TDA18250_POWER_STANDBY);
+
+ return 0;
+err_kfree:
+ kfree(dev);
+err:
+ dev_dbg(&client->dev, "failed=%d", ret);
+ return ret;
+}
+
+static int tda18250_remove(struct i2c_client *client)
+{
+ struct tda18250_dev *dev = i2c_get_clientdata(client);
+ struct dvb_frontend *fe = dev->fe;
+
+ dev_dbg(&client->dev, "\n");
+
+ memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
+ fe->tuner_priv = NULL;
+ kfree(dev);
+
+ return 0;
+}
+
+static const struct i2c_device_id tda18250_id_table[] = {
+ {"tda18250", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, tda18250_id_table);
+
+static struct i2c_driver tda18250_driver = {
+ .driver = {
+ .name = "tda18250",
+ },
+ .probe = tda18250_probe,
+ .remove = tda18250_remove,
+ .id_table = tda18250_id_table,
+};
+
+module_i2c_driver(tda18250_driver);
+
+MODULE_DESCRIPTION("NXP TDA18250 silicon tuner driver");
+MODULE_AUTHOR("Olli Salonen <olli.salonen@iki.fi>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tda18250.h b/drivers/media/tuners/tda18250.h
new file mode 100644
index 000000000000..961806a81f9f
--- /dev/null
+++ b/drivers/media/tuners/tda18250.h
@@ -0,0 +1,51 @@
+/*
+ * NXP TDA18250BHN silicon tuner driver
+ *
+ * Copyright (C) 2017 Olli Salonen <olli.salonen@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.
+ */
+
+#ifndef TDA18250_H
+#define TDA18250_H
+
+#include <linux/kconfig.h>
+#include <media/media-device.h>
+#include <media/dvb_frontend.h>
+
+#define TDA18250_XTAL_FREQ_16MHZ 0
+#define TDA18250_XTAL_FREQ_24MHZ 1
+#define TDA18250_XTAL_FREQ_25MHZ 2
+#define TDA18250_XTAL_FREQ_27MHZ 3
+#define TDA18250_XTAL_FREQ_30MHZ 4
+#define TDA18250_XTAL_FREQ_MAX 5
+
+struct tda18250_config {
+ u16 if_dvbt_6;
+ u16 if_dvbt_7;
+ u16 if_dvbt_8;
+ u16 if_dvbc_6;
+ u16 if_dvbc_8;
+ u16 if_atsc;
+ u8 xtal_freq;
+ bool loopthrough;
+
+ /*
+ * frontend
+ */
+ struct dvb_frontend *fe;
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ struct media_device *mdev;
+#endif
+};
+
+#endif
diff --git a/drivers/media/tuners/tda18250_priv.h b/drivers/media/tuners/tda18250_priv.h
new file mode 100644
index 000000000000..4a6f801701a7
--- /dev/null
+++ b/drivers/media/tuners/tda18250_priv.h
@@ -0,0 +1,145 @@
+/*
+ * NXP TDA18250BHN silicon tuner driver
+ *
+ * Copyright (C) 2017 Olli Salonen <olli.salonen@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.
+ */
+
+#ifndef TDA18250_PRIV_H
+#define TDA18250_PRIV_H
+
+#include "tda18250.h"
+
+#define R00_ID1 0x00 /* ID byte 1 */
+#define R01_ID2 0x01 /* ID byte 2 */
+#define R02_ID3 0x02 /* ID byte 3 */
+#define R03_THERMO1 0x03 /* Thermo byte 1 */
+#define R04_THERMO2 0x04 /* Thermo byte 2 */
+#define R05_POWER1 0x05 /* Power byte 1 */
+#define R06_POWER2 0x06 /* Power byte 2 */
+#define R07_GPIO 0x07 /* GPIO */
+#define R08_IRQ1 0x08 /* IRQ */
+#define R09_IRQ2 0x09 /* IRQ */
+#define R0A_IRQ3 0x0a /* IRQ */
+#define R0B_IRQ4 0x0b /* IRQ */
+#define R0C_AGC11 0x0c /* AGC1 byte 1 */
+#define R0D_AGC12 0x0d /* AGC1 byte 2 */
+#define R0E_AGC13 0x0e /* AGC1 byte 3 */
+#define R0F_AGC14 0x0f /* AGC1 byte 4 */
+#define R10_LT1 0x10 /* LT byte 1 */
+#define R11_LT2 0x11 /* LT byte 2 */
+#define R12_AGC21 0x12 /* AGC2 byte 1 */
+#define R13_AGC22 0x13 /* AGC2 byte 2 */
+#define R14_AGC23 0x14 /* AGC2 byte 3 */
+#define R15_AGC24 0x15 /* AGC2 byte 4 */
+#define R16_AGC25 0x16 /* AGC2 byte 5 */
+#define R17_AGC31 0x17 /* AGC3 byte 1 */
+#define R18_AGC32 0x18 /* AGC3 byte 2 */
+#define R19_AGC33 0x19 /* AGC3 byte 3 */
+#define R1A_AGCK 0x1a
+#define R1B_GAIN1 0x1b
+#define R1C_GAIN2 0x1c
+#define R1D_GAIN3 0x1d
+#define R1E_WI_FI 0x1e /* Wireless Filter */
+#define R1F_RF_BPF 0x1f /* RF Band Pass Filter */
+#define R20_IR_MIX 0x20 /* IR Mixer */
+#define R21_IF_AGC 0x21
+#define R22_IF1 0x22 /* IF byte 1 */
+#define R23_IF2 0x23 /* IF byte 2 */
+#define R24_IF3 0x24 /* IF byte 3 */
+#define R25_REF 0x25 /* reference byte */
+#define R26_IF 0x26 /* IF frequency */
+#define R27_RF1 0x27 /* RF frequency byte 1 */
+#define R28_RF2 0x28 /* RF frequency byte 2 */
+#define R29_RF3 0x29 /* RF frequency byte 3 */
+#define R2A_MSM1 0x2a
+#define R2B_MSM2 0x2b
+#define R2C_PS1 0x2c /* power saving mode byte 1 */
+#define R2D_PS2 0x2d /* power saving mode byte 2 */
+#define R2E_PS3 0x2e /* power saving mode byte 3 */
+#define R2F_RSSI1 0x2f
+#define R30_RSSI2 0x30
+#define R31_IRQ_CTRL 0x31
+#define R32_DUMMY 0x32
+#define R33_TEST 0x33
+#define R34_MD1 0x34
+#define R35_SD1 0x35
+#define R36_SD2 0x36
+#define R37_SD3 0x37
+#define R38_SD4 0x38
+#define R39_SD5 0x39
+#define R3A_SD_TEST 0x3a
+#define R3B_REGU 0x3b
+#define R3C_RCCAL1 0x3c
+#define R3D_RCCAL2 0x3d
+#define R3E_IRCAL1 0x3e
+#define R3F_IRCAL2 0x3f
+#define R40_IRCAL3 0x40
+#define R41_IRCAL4 0x41
+#define R42_IRCAL5 0x42
+#define R43_PD1 0x43 /* power down byte 1 */
+#define R44_PD2 0x44 /* power down byte 2 */
+#define R45_PD 0x45 /* power down */
+#define R46_CPUMP 0x46 /* charge pump */
+#define R47_LNAPOL 0x47 /* LNA polar casc */
+#define R48_SMOOTH1 0x48 /* smooth test byte 1 */
+#define R49_SMOOTH2 0x49 /* smooth test byte 2 */
+#define R4A_SMOOTH3 0x4a /* smooth test byte 3 */
+#define R4B_XTALOSC1 0x4b
+#define R4C_XTALOSC2 0x4c
+#define R4D_XTALFLX1 0x4d
+#define R4E_XTALFLX2 0x4e
+#define R4F_XTALFLX3 0x4f
+#define R50_XTALFLX4 0x50
+#define R51_XTALFLX5 0x51
+#define R52_IRLOOP0 0x52
+#define R53_IRLOOP1 0x53
+#define R54_IRLOOP2 0x54
+#define R55_IRLOOP3 0x55
+#define R56_IRLOOP4 0x56
+#define R57_PLL_LOG 0x57
+#define R58_AGC2_UP1 0x58
+#define R59_AGC2_UP2 0x59
+#define R5A_H3H5 0x5a
+#define R5B_AGC_AUTO 0x5b
+#define R5C_AGC_DEBUG 0x5c
+
+#define TDA18250_NUM_REGS 93
+
+#define TDA18250_POWER_STANDBY 0
+#define TDA18250_POWER_NORMAL 1
+
+#define TDA18250_IRQ_CAL 0x81
+#define TDA18250_IRQ_HW_INIT 0x82
+#define TDA18250_IRQ_TUNE 0x88
+
+struct tda18250_dev {
+ struct mutex i2c_mutex;
+ struct dvb_frontend *fe;
+ struct i2c_adapter *i2c;
+ struct regmap *regmap;
+ u8 xtal_freq;
+ /* IF in kHz */
+ u16 if_dvbt_6;
+ u16 if_dvbt_7;
+ u16 if_dvbt_8;
+ u16 if_dvbc_6;
+ u16 if_dvbc_8;
+ u16 if_atsc;
+ u16 if_frequency;
+ bool slave;
+ bool loopthrough;
+ bool warm;
+ u8 regs[TDA18250_NUM_REGS];
+};
+
+#endif
diff --git a/drivers/media/tuners/tda18271.h b/drivers/media/tuners/tda18271.h
index 0a846333ce57..7e07966c5ace 100644
--- a/drivers/media/tuners/tda18271.h
+++ b/drivers/media/tuners/tda18271.h
@@ -22,7 +22,7 @@
#define __TDA18271_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
struct tda18271_std_map_item {
u16 if_freq;
diff --git a/drivers/media/tuners/tda827x.h b/drivers/media/tuners/tda827x.h
index abf2e2fe5350..a08d3f9fcea1 100644
--- a/drivers/media/tuners/tda827x.h
+++ b/drivers/media/tuners/tda827x.h
@@ -25,7 +25,7 @@
#define __DVB_TDA827X_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda8290.h"
struct tda827x_config
@@ -36,7 +36,7 @@ struct tda827x_config
/* interface to tda829x driver */
enum tda8290_lna config;
- int switch_addr;
+ int switch_addr;
void (*agcf)(struct dvb_frontend *fe);
};
diff --git a/drivers/media/tuners/tda8290.c b/drivers/media/tuners/tda8290.c
index a59c567c55d6..9f1f1d2b8bdc 100644
--- a/drivers/media/tuners/tda8290.c
+++ b/drivers/media/tuners/tda8290.c
@@ -63,8 +63,8 @@ static int tda8290_i2c_bridge(struct dvb_frontend *fe, int close)
{
struct tda8290_priv *priv = fe->analog_demod_priv;
- unsigned char enable[2] = { 0x21, 0xC0 };
- unsigned char disable[2] = { 0x21, 0x00 };
+ static unsigned char enable[2] = { 0x21, 0xC0 };
+ static unsigned char disable[2] = { 0x21, 0x00 };
unsigned char *msg;
if (close) {
@@ -84,9 +84,9 @@ static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close)
{
struct tda8290_priv *priv = fe->analog_demod_priv;
- unsigned char enable[2] = { 0x45, 0xc1 };
- unsigned char disable[2] = { 0x46, 0x00 };
- unsigned char buf[3] = { 0x45, 0x01, 0x00 };
+ static unsigned char enable[2] = { 0x45, 0xc1 };
+ static unsigned char disable[2] = { 0x46, 0x00 };
+ static unsigned char buf[3] = { 0x45, 0x01, 0x00 };
unsigned char *msg;
if (close) {
@@ -178,25 +178,25 @@ static void tda8290_set_params(struct dvb_frontend *fe,
{
struct tda8290_priv *priv = fe->analog_demod_priv;
- unsigned char soft_reset[] = { 0x00, 0x00 };
+ static unsigned char soft_reset[] = { 0x00, 0x00 };
unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode };
- unsigned char expert_mode[] = { 0x01, 0x80 };
- unsigned char agc_out_on[] = { 0x02, 0x00 };
- unsigned char gainset_off[] = { 0x28, 0x14 };
- unsigned char if_agc_spd[] = { 0x0f, 0x88 };
- unsigned char adc_head_6[] = { 0x05, 0x04 };
- unsigned char adc_head_9[] = { 0x05, 0x02 };
- unsigned char adc_head_12[] = { 0x05, 0x01 };
- unsigned char pll_bw_nom[] = { 0x0d, 0x47 };
- unsigned char pll_bw_low[] = { 0x0d, 0x27 };
- unsigned char gainset_2[] = { 0x28, 0x64 };
- unsigned char agc_rst_on[] = { 0x0e, 0x0b };
- unsigned char agc_rst_off[] = { 0x0e, 0x09 };
- unsigned char if_agc_set[] = { 0x0f, 0x81 };
- unsigned char addr_adc_sat = 0x1a;
- unsigned char addr_agc_stat = 0x1d;
- unsigned char addr_pll_stat = 0x1b;
- unsigned char adc_sat, agc_stat,
+ static unsigned char expert_mode[] = { 0x01, 0x80 };
+ static unsigned char agc_out_on[] = { 0x02, 0x00 };
+ static unsigned char gainset_off[] = { 0x28, 0x14 };
+ static unsigned char if_agc_spd[] = { 0x0f, 0x88 };
+ static unsigned char adc_head_6[] = { 0x05, 0x04 };
+ static unsigned char adc_head_9[] = { 0x05, 0x02 };
+ static unsigned char adc_head_12[] = { 0x05, 0x01 };
+ static unsigned char pll_bw_nom[] = { 0x0d, 0x47 };
+ static unsigned char pll_bw_low[] = { 0x0d, 0x27 };
+ static unsigned char gainset_2[] = { 0x28, 0x64 };
+ static unsigned char agc_rst_on[] = { 0x0e, 0x0b };
+ static unsigned char agc_rst_off[] = { 0x0e, 0x09 };
+ static unsigned char if_agc_set[] = { 0x0f, 0x81 };
+ static unsigned char addr_adc_sat = 0x1a;
+ static unsigned char addr_agc_stat = 0x1d;
+ static unsigned char addr_pll_stat = 0x1b;
+ static unsigned char adc_sat = 0, agc_stat = 0,
pll_stat;
int i;
@@ -468,9 +468,9 @@ static void tda8290_standby(struct dvb_frontend *fe)
{
struct tda8290_priv *priv = fe->analog_demod_priv;
- unsigned char cb1[] = { 0x30, 0xD0 };
- unsigned char tda8290_standby[] = { 0x00, 0x02 };
- unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
+ static unsigned char cb1[] = { 0x30, 0xD0 };
+ static unsigned char tda8290_standby[] = { 0x00, 0x02 };
+ static unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
if (fe->ops.analog_ops.i2c_gate_ctrl)
@@ -495,9 +495,9 @@ static void tda8290_init_if(struct dvb_frontend *fe)
{
struct tda8290_priv *priv = fe->analog_demod_priv;
- unsigned char set_VS[] = { 0x30, 0x6F };
- unsigned char set_GP00_CF[] = { 0x20, 0x01 };
- unsigned char set_GP01_CF[] = { 0x20, 0x0B };
+ static unsigned char set_VS[] = { 0x30, 0x6F };
+ static unsigned char set_GP00_CF[] = { 0x20, 0x01 };
+ static unsigned char set_GP01_CF[] = { 0x20, 0x0B };
if ((priv->cfg.config == TDA8290_LNA_GP0_HIGH_ON) ||
(priv->cfg.config == TDA8290_LNA_GP0_HIGH_OFF))
@@ -539,10 +539,12 @@ static void tda8295_init_if(struct dvb_frontend *fe)
static void tda8290_init_tuner(struct dvb_frontend *fe)
{
struct tda8290_priv *priv = fe->analog_demod_priv;
- unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
- 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
- unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
- 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
+ static unsigned char tda8275_init[] =
+ { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
+ 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
+ static unsigned char tda8275a_init[] =
+ { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
+ 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0,
.buf=tda8275_init, .len = 14};
if (priv->ver & TDA8275A)
@@ -834,11 +836,11 @@ int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
.addr = i2c_addr,
};
- unsigned char soft_reset[] = { 0x00, 0x00 };
- unsigned char easy_mode_b[] = { 0x01, 0x02 };
- unsigned char easy_mode_g[] = { 0x01, 0x04 };
- unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 };
- unsigned char addr_dto_lsb = 0x07;
+ static unsigned char soft_reset[] = { 0x00, 0x00 };
+ static unsigned char easy_mode_b[] = { 0x01, 0x02 };
+ static unsigned char easy_mode_g[] = { 0x01, 0x04 };
+ static unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 };
+ static unsigned char addr_dto_lsb = 0x07;
unsigned char data;
#define PROBE_BUFFER_SIZE 8
unsigned char buf[PROBE_BUFFER_SIZE];
diff --git a/drivers/media/tuners/tda8290.h b/drivers/media/tuners/tda8290.h
index 901b8cac7105..5db79f16ad7d 100644
--- a/drivers/media/tuners/tda8290.h
+++ b/drivers/media/tuners/tda8290.h
@@ -18,7 +18,7 @@
#define __TDA8290_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "tda18271.h"
enum tda8290_lna {
diff --git a/drivers/media/tuners/tda9887.c b/drivers/media/tuners/tda9887.c
index c0e815f8b951..9777da03e308 100644
--- a/drivers/media/tuners/tda9887.c
+++ b/drivers/media/tuners/tda9887.c
@@ -31,7 +31,7 @@ struct tda9887_priv {
struct tuner_i2c_props i2c_props;
struct list_head hybrid_tuner_instance_list;
- unsigned char data[4];
+ unsigned char data[4];
unsigned int config;
unsigned int mode;
unsigned int audmode;
@@ -94,7 +94,7 @@ struct tvnorm {
#define cAudioGain6 0x80 // bit c7
#define cTopMask 0x1f // bit c0:4
-#define cTopDefault 0x10 // bit c0:4
+#define cTopDefault 0x10 // bit c0:4
//// third reg (e)
#define cAudioIF_4_5 0x00 // bit e0:1
diff --git a/drivers/media/tuners/tda9887.h b/drivers/media/tuners/tda9887.h
index 95070eca02ca..2a143f8c6477 100644
--- a/drivers/media/tuners/tda9887.h
+++ b/drivers/media/tuners/tda9887.h
@@ -18,7 +18,7 @@
#define __TDA9887_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/* ------------------------------------------------------------------------ */
#if IS_REACHABLE(CONFIG_MEDIA_TUNER_TDA9887)
diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c
index a9b1bb134409..88b3e80c38ad 100644
--- a/drivers/media/tuners/tea5761.c
+++ b/drivers/media/tuners/tea5761.c
@@ -1,11 +1,8 @@
-/*
- * For Philips TEA5761 FM Chip
- * I2C address is allways 0x20 (0x10 at 7-bit mode).
- *
- * Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNUv2 General Public License
- *
- */
+// SPDX-License-Identifier: GPL-2.0
+// For Philips TEA5761 FM Chip
+// I2C address is always 0x20 (0x10 at 7-bit mode).
+//
+// Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org)
#include <linux/i2c.h>
#include <linux/slab.h>
@@ -341,4 +338,4 @@ EXPORT_SYMBOL_GPL(tea5761_autodetection);
MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/tuners/tea5761.h b/drivers/media/tuners/tea5761.h
index 2d624d9919e3..4bcf835fc613 100644
--- a/drivers/media/tuners/tea5761.h
+++ b/drivers/media/tuners/tea5761.h
@@ -18,7 +18,7 @@
#define __TEA5761_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#if IS_REACHABLE(CONFIG_MEDIA_TUNER_TEA5761)
extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
diff --git a/drivers/media/tuners/tea5767.c b/drivers/media/tuners/tea5767.c
index 525b7ab90c80..2b2c064d7dc3 100644
--- a/drivers/media/tuners/tea5767.c
+++ b/drivers/media/tuners/tea5767.c
@@ -1,14 +1,11 @@
-/*
- * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
- * I2C address is allways 0xC0.
- *
- *
- * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License
- *
- * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
- * from their contributions on DScaler.
- */
+// SPDX-License-Identifier: GPL-2.0
+// For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
+// I2C address is always 0xC0.
+//
+// Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
+//
+// tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
+// from their contributions on DScaler.
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -473,4 +470,4 @@ EXPORT_SYMBOL_GPL(tea5767_autodetection);
MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/tuners/tea5767.h b/drivers/media/tuners/tea5767.h
index 4f6f6c92db78..216a3192a35f 100644
--- a/drivers/media/tuners/tea5767.h
+++ b/drivers/media/tuners/tea5767.h
@@ -18,7 +18,7 @@
#define __TEA5767_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
enum tea5767_xtal {
TEA5767_LOW_LO_32768 = 0,
diff --git a/drivers/media/tuners/tua9001.h b/drivers/media/tuners/tua9001.h
index 7b0548181cdc..4df2c16592fb 100644
--- a/drivers/media/tuners/tua9001.h
+++ b/drivers/media/tuners/tua9001.h
@@ -17,7 +17,7 @@
#ifndef TUA9001_H
#define TUA9001_H
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/*
* I2C address
diff --git a/drivers/media/tuners/tuner-i2c.h b/drivers/media/tuners/tuner-i2c.h
index bda67a5a76f2..56dc2339a989 100644
--- a/drivers/media/tuners/tuner-i2c.h
+++ b/drivers/media/tuners/tuner-i2c.h
@@ -75,7 +75,7 @@ static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props,
*
* state structure must contain the following:
*
- * struct list_head hybrid_tuner_instance_list;
+ * struct list_head hybrid_tuner_instance_list;
* struct tuner_i2c_props i2c_props;
*
* hybrid_tuner_instance_list (both within state structure and globally)
diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c
index cf44d3657f55..36b88f820239 100644
--- a/drivers/media/tuners/tuner-simple.c
+++ b/drivers/media/tuners/tuner-simple.c
@@ -53,7 +53,7 @@ MODULE_PARM_DESC(dtv_input, "specify dtv rf input, 0 for autoselect");
/* tv tuner system standard selection for Philips FQ1216ME
this value takes the low bits of control byte 2
from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
- standard BG DK I L L`
+ standard BG DK I L L`
picture carrier 38.90 38.90 38.90 38.90 33.95
colour 34.47 34.47 34.47 34.47 38.38
sound 1 33.40 32.40 32.90 32.40 40.45
diff --git a/drivers/media/tuners/tuner-simple.h b/drivers/media/tuners/tuner-simple.h
index 6399b45b0590..fd71b3490dc8 100644
--- a/drivers/media/tuners/tuner-simple.h
+++ b/drivers/media/tuners/tuner-simple.h
@@ -18,7 +18,7 @@
#define __TUNER_SIMPLE_H__
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#if IS_REACHABLE(CONFIG_MEDIA_TUNER_SIMPLE)
extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
diff --git a/drivers/media/tuners/tuner-xc2028-types.h b/drivers/media/tuners/tuner-xc2028-types.h
index 7e4798783db7..bb0437c36c03 100644
--- a/drivers/media/tuners/tuner-xc2028-types.h
+++ b/drivers/media/tuners/tuner-xc2028-types.h
@@ -1,10 +1,11 @@
-/* tuner-xc2028_types
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * tuner-xc2028_types
*
* This file includes internal tipes to be used inside tuner-xc2028.
* Shouldn't be included outside tuner-xc2028
*
* Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
*/
/* xc3028 firmware types */
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
index b5b62b08159e..fca85e08ebd7 100644
--- a/drivers/media/tuners/tuner-xc2028.c
+++ b/drivers/media/tuners/tuner-xc2028.c
@@ -1,12 +1,10 @@
-/* tuner-xc2028
- *
- * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
- *
- * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
- * - frontend interface
- *
- * This code is placed under the terms of the GNU General Public License v2
- */
+// SPDX-License-Identifier: GPL-2.0
+// tuner-xc2028
+//
+// Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
+//
+// Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
+// - frontend interface
#include <linux/i2c.h>
#include <asm/div64.h>
@@ -22,7 +20,7 @@
#include "tuner-xc2028-types.h"
#include <linux/dvb/frontend.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
/* Max transfer size done by I2C transfer functions */
#define MAX_XFER_SIZE 80
@@ -89,7 +87,7 @@ struct firmware_properties {
v4l2_std_id std_req;
__u16 int_freq;
unsigned int scode_table;
- int scode_nr;
+ int scode_nr;
};
enum xc2028_state {
@@ -139,7 +137,7 @@ struct xc2028_data {
ibuf, isize); \
if (isize != _rc) \
tuner_err("i2c input error: rc = %d (should be %d)\n", \
- _rc, (int)isize); \
+ _rc, (int)isize); \
if (priv->ctrl.msleep) \
msleep(priv->ctrl.msleep); \
_rc; \
@@ -174,7 +172,7 @@ static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val)
return 0;
}
-#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
+#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
{
if (type & BASE)
@@ -1521,6 +1519,6 @@ EXPORT_SYMBOL(xc2028_attach);
MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE);
MODULE_FIRMWARE(XC3028L_DEFAULT_FIRMWARE);
diff --git a/drivers/media/tuners/tuner-xc2028.h b/drivers/media/tuners/tuner-xc2028.h
index 98e4effca896..03fd6d4233a4 100644
--- a/drivers/media/tuners/tuner-xc2028.h
+++ b/drivers/media/tuners/tuner-xc2028.h
@@ -1,13 +1,14 @@
-/* tuner-xc2028
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * tuner-xc2028
*
* Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
- * This code is placed under the terms of the GNU General Public License v2
*/
#ifndef __TUNER_XC2028_H__
#define __TUNER_XC2028_H__
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw"
#define XC3028L_DEFAULT_FIRMWARE "xc3028L-v36.fw"
@@ -47,7 +48,7 @@ struct xc2028_ctrl {
struct xc2028_config {
struct i2c_adapter *i2c_adap;
- u8 i2c_addr;
+ u8 i2c_addr;
struct xc2028_ctrl *ctrl;
};
diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
index e30948e4ff87..f0fa8da08afa 100644
--- a/drivers/media/tuners/xc4000.c
+++ b/drivers/media/tuners/xc4000.c
@@ -27,7 +27,7 @@
#include <linux/mutex.h>
#include <asm/unaligned.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "xc4000.h"
#include "tuner-i2c.h"
@@ -1036,7 +1036,10 @@ skip_std_specific:
dprintk(1, "load scode failed %d\n", rc);
check_device:
- rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
+ if (xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel) < 0) {
+ printk(KERN_ERR "Unable to read tuner registers.\n");
+ goto fail;
+ }
if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
&fw_minor) != 0) {
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
index 0e7e4fdf9e50..f7a8d05d1758 100644
--- a/drivers/media/tuners/xc5000.c
+++ b/drivers/media/tuners/xc5000.c
@@ -25,7 +25,7 @@
#include <linux/dvb/frontend.h>
#include <linux/i2c.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "xc5000.h"
#include "tuner-i2c.h"
@@ -685,8 +685,8 @@ static void xc_debug_dump(struct xc5000_priv *priv)
(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);
+ if (!xc5000_readreg(priv, priv->pll_register_no, &regval))
+ dprintk(1, "*** PLL lock status = 0x%04x\n", regval);
}
}
@@ -831,15 +831,16 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
u16 id;
ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
- if (ret == 0) {
+ if (!ret) {
if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
ret = -ENOENT;
else
ret = 0;
+ dprintk(1, "%s() returns id = 0x%x\n", __func__, id);
+ } else {
+ dprintk(1, "%s() returns error %d\n", __func__, ret);
}
- dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
- ret == 0 ? "True" : "False", id);
return ret;
}
@@ -935,7 +936,10 @@ tune_channel:
if (priv->pll_register_no != 0) {
msleep(20);
- xc5000_readreg(priv, priv->pll_register_no, &pll_lock_status);
+ ret = xc5000_readreg(priv, priv->pll_register_no,
+ &pll_lock_status);
+ if (ret)
+ return ret;
if (pll_lock_status > 63) {
/* PLL is unlocked, force reload of the firmware */
dprintk(1, "xc5000: PLL not locked (0x%x). Reloading...\n",
@@ -1190,8 +1194,10 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
}
if (priv->pll_register_no) {
- xc5000_readreg(priv, priv->pll_register_no,
- &pll_lock_status);
+ ret = xc5000_readreg(priv, priv->pll_register_no,
+ &pll_lock_status);
+ if (ret)
+ continue;
if (pll_lock_status > 63) {
/* PLL is unlocked, force reload of the firmware */
printk(KERN_ERR
diff --git a/drivers/media/usb/as102/Makefile b/drivers/media/usb/as102/Makefile
index 56bd2d00b920..b0b319622edb 100644
--- a/drivers/media/usb/as102/Makefile
+++ b/drivers/media/usb/as102/Makefile
@@ -4,5 +4,4 @@ dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \
obj-$(CONFIG_DVB_AS102) += dvb-as102.o
-ccflags-y += -Idrivers/media/dvb-core
ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/as102/as102_drv.c b/drivers/media/usb/as102/as102_drv.c
index 9dd7c7cb06b1..48b0c4e4dac1 100644
--- a/drivers/media/usb/as102/as102_drv.c
+++ b/drivers/media/usb/as102/as102_drv.c
@@ -27,7 +27,7 @@
#include "as10x_cmd.h"
#include "as102_fe.h"
#include "as102_fw.h"
-#include "dvbdev.h"
+#include <media/dvbdev.h>
int dual_tuner;
module_param_named(dual_tuner, dual_tuner, int, 0644);
diff --git a/drivers/media/usb/as102/as102_drv.h b/drivers/media/usb/as102/as102_drv.h
index 8def19d9ab92..c92a1e4f6a20 100644
--- a/drivers/media/usb/as102/as102_drv.h
+++ b/drivers/media/usb/as102/as102_drv.h
@@ -16,9 +16,9 @@
#ifndef _AS102_DRV_H
#define _AS102_DRV_H
#include <linux/usb.h>
-#include <dvb_demux.h>
-#include <dvb_frontend.h>
-#include <dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dmxdev.h>
#include "as10x_handle.h"
#include "as10x_cmd.h"
#include "as102_usb_drv.h"
diff --git a/drivers/media/usb/as102/as10x_cmd_cfg.c b/drivers/media/usb/as102/as10x_cmd_cfg.c
index c87f2ca223a2..fabbfead96d8 100644
--- a/drivers/media/usb/as102/as10x_cmd_cfg.c
+++ b/drivers/media/usb/as102/as10x_cmd_cfg.c
@@ -133,9 +133,9 @@ out:
* as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x
* @adap: pointer to AS10x bus adapter
* @mode: mode selected:
- * - ON : 0x0 => eLNA always ON
- * - OFF : 0x1 => eLNA always OFF
- * - AUTO : 0x2 => eLNA follow hysteresis parameters
+ * - ON : 0x0 => eLNA always ON
+ * - OFF : 0x1 => eLNA always OFF
+ * - AUTO : 0x2 => eLNA follow hysteresis parameters
* to be ON or OFF
*
* Return 0 on success or negative value in case of error.
diff --git a/drivers/media/usb/au0828/Makefile b/drivers/media/usb/au0828/Makefile
index c06ef6601f2d..5691881c56c0 100644
--- a/drivers/media/usb/au0828/Makefile
+++ b/drivers/media/usb/au0828/Makefile
@@ -12,7 +12,6 @@ endif
obj-$(CONFIG_VIDEO_AU0828) += au0828.o
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/usb/au0828/au0828-cards.h b/drivers/media/usb/au0828/au0828-cards.h
index 1f4412ee6da4..dbd8a90ee76f 100644
--- a/drivers/media/usb/au0828/au0828-cards.h
+++ b/drivers/media/usb/au0828/au0828-cards.h
@@ -17,7 +17,7 @@
#define AU0828_BOARD_UNKNOWN 0
#define AU0828_BOARD_HAUPPAUGE_HVR950Q 1
-#define AU0828_BOARD_HAUPPAUGE_HVR850 2
+#define AU0828_BOARD_HAUPPAUGE_HVR850 2
#define AU0828_BOARD_DVICO_FUSIONHDTV7 3
#define AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL 4
#define AU0828_BOARD_HAUPPAUGE_WOODBURY 5
diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c
index af68afe085b5..832ed9f25784 100644
--- a/drivers/media/usb/au0828/au0828-input.c
+++ b/drivers/media/usb/au0828/au0828-input.c
@@ -1,21 +1,10 @@
-/*
- handle au0828 IR remotes via linux kernel input layer.
-
- Copyright (C) 2014 Mauro Carvalho Chehab <mchehab@samsung.com>
- Copyright (c) 2014 Samsung Electronics Co., Ltd.
-
- Based on em28xx-input.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.
- */
+// SPDX-License-Identifier: GPL-2.0+
+// handle au0828 IR remotes via linux kernel input layer.
+//
+// Copyright (c) 2014 Mauro Carvalho Chehab <mchehab@samsung.com>
+// Copyright (c) 2014 Samsung Electronics Co., Ltd.
+//
+// Based on em28xx-input.c.
#include "au0828.h"
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index a240153821e0..c765d546114d 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -1797,7 +1797,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
static const struct video_device au0828_video_template = {
.fops = &au0828_v4l_fops,
.release = video_device_release_empty,
- .ioctl_ops = &video_ioctl_ops,
+ .ioctl_ops = &video_ioctl_ops,
.tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_M,
};
diff --git a/drivers/media/usb/au0828/au0828.h b/drivers/media/usb/au0828/au0828.h
index f6f37e8ef51d..004eadef55c7 100644
--- a/drivers/media/usb/au0828/au0828.h
+++ b/drivers/media/usb/au0828/au0828.h
@@ -33,12 +33,12 @@
#include <media/media-device.h>
/* DVB */
-#include "demux.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
-#include "dvbdev.h"
+#include <media/demux.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
+#include <media/dvbdev.h>
#include "au0828-reg.h"
#include "au0828-cards.h"
@@ -190,7 +190,7 @@ struct au0828_dev {
struct i2c_adapter i2c_adap;
struct i2c_algorithm i2c_algo;
struct i2c_client i2c_client;
- u32 i2c_rc;
+ u32 i2c_rc;
/* Digital */
struct au0828_dvb dvb;
@@ -293,8 +293,8 @@ struct au0828_dev {
/* ----------------------------------------------------------- */
#define au0828_read(dev, reg) au0828_readreg(dev, reg)
#define au0828_write(dev, reg, value) au0828_writereg(dev, reg, value)
-#define au0828_andor(dev, reg, mask, value) \
- au0828_writereg(dev, reg, \
+#define au0828_andor(dev, reg, mask, value) \
+ au0828_writereg(dev, reg, \
(au0828_readreg(dev, reg) & ~(mask)) | ((value) & (mask)))
#define au0828_set(dev, reg, bit) au0828_andor(dev, (reg), (bit), (bit))
diff --git a/drivers/media/usb/b2c2/Makefile b/drivers/media/usb/b2c2/Makefile
index 2778c19a45eb..f3cef05f37b6 100644
--- a/drivers/media/usb/b2c2/Makefile
+++ b/drivers/media/usb/b2c2/Makefile
@@ -1,5 +1,4 @@
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/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c
index 6089036049d9..f3a1e5b1e57c 100644
--- a/drivers/media/usb/cpia2/cpia2_usb.c
+++ b/drivers/media/usb/cpia2/cpia2_usb.c
@@ -33,13 +33,13 @@
static int frame_sizes[] = {
0, // USBIF_CMDONLY
- 0, // USBIF_BULK
- 128, // USBIF_ISO_1
- 384, // USBIF_ISO_2
- 640, // USBIF_ISO_3
- 768, // USBIF_ISO_4
- 896, // USBIF_ISO_5
- 1023, // USBIF_ISO_6
+ 0, // USBIF_BULK
+ 128, // USBIF_ISO_1
+ 384, // USBIF_ISO_2
+ 640, // USBIF_ISO_3
+ 768, // USBIF_ISO_4
+ 896, // USBIF_ISO_5
+ 1023, // USBIF_ISO_6
};
#define FRAMES_PER_DESC 10
diff --git a/drivers/media/usb/cpia2/cpia2_v4l.c b/drivers/media/usb/cpia2/cpia2_v4l.c
index 74c97565ccc6..99f106b13280 100644
--- a/drivers/media/usb/cpia2/cpia2_v4l.c
+++ b/drivers/media/usb/cpia2/cpia2_v4l.c
@@ -808,7 +808,7 @@ static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
struct camera_data *cam = video_drvdata(file);
if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- buf->index > cam->num_frames)
+ buf->index >= cam->num_frames)
return -EINVAL;
buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
@@ -859,7 +859,7 @@ static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
buf->memory != V4L2_MEMORY_MMAP ||
- buf->index > cam->num_frames)
+ buf->index >= cam->num_frames)
return -EINVAL;
DBG("QBUF #%d\n", buf->index);
diff --git a/drivers/media/usb/cx231xx/Makefile b/drivers/media/usb/cx231xx/Makefile
index 19e8c35d6a77..c023d97407de 100644
--- a/drivers/media/usb/cx231xx/Makefile
+++ b/drivers/media/usb/cx231xx/Makefile
@@ -9,8 +9,6 @@ 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/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/usb/cx231xx/cx231xx-audio.c b/drivers/media/usb/cx231xx/cx231xx-audio.c
index 06f10d7fc4b0..d96236d786d1 100644
--- a/drivers/media/usb/cx231xx/cx231xx-audio.c
+++ b/drivers/media/usb/cx231xx/cx231xx-audio.c
@@ -404,9 +404,9 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
}
static const struct snd_pcm_hardware snd_cx231xx_hw_capture = {
- .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
- SNDRV_PCM_INFO_MMAP |
- SNDRV_PCM_INFO_INTERLEAVED |
+ .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,
diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c
index 2f52d66b4dae..fdd3c221fa0d 100644
--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c
@@ -105,7 +105,7 @@ void uninitGPIO(struct cx231xx *dev)
/******************************************************************************
* A F E - B L O C K C O N T R O L functions *
- * [ANALOG FRONT END] *
+ * [ANALOG FRONT END] *
******************************************************************************/
static int afe_write_byte(struct cx231xx *dev, u16 saddr, u8 data)
{
@@ -2168,7 +2168,7 @@ int cx231xx_tuner_post_channel_change(struct cx231xx *dev)
}
/******************************************************************************
- * I 2 S - B L O C K C O N T R O L functions *
+ * I 2 S - B L O C K C O N T R O L functions *
******************************************************************************/
int cx231xx_i2s_blk_initialize(struct cx231xx *dev)
{
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index 54d9d0cb326f..f9ec7fedcd5b 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -31,7 +31,7 @@
#include <media/v4l2-common.h>
#include <media/drv-intf/cx25840.h>
-#include "dvb-usb-ids.h"
+#include <media/dvb-usb-ids.h>
#include "xc5000.h"
#include "tda18271.h"
@@ -896,6 +896,32 @@ struct cx231xx_board cx231xx_boards[] = {
},
},
},
+ [CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO] = {
+ .name = "The Imaging Source DFG/USB2pro",
+ .tuner_type = TUNER_ABSENT,
+ .decoder = CX231XX_AVDECODER,
+ .output_mode = OUT_MODE_VIP11,
+ .demod_xfer_mode = 0,
+ .ctl_pin_status_mask = 0xFFFFFFC4,
+ .agc_analog_digital_select_gpio = 0x0c,
+ .gpio_pin_status_mask = 0x4001000,
+ .norm = V4L2_STD_PAL,
+ .no_alt_vanc = 1,
+ .external_av = 1,
+ .input = {{
+ .type = CX231XX_VMUX_COMPOSITE1,
+ .vmux = CX231XX_VIN_1_1,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = NULL,
+ }, {
+ .type = CX231XX_VMUX_SVIDEO,
+ .vmux = CX231XX_VIN_2_1 |
+ (CX231XX_VIN_2_2 << 8) |
+ CX25840_SVIDEO_ON,
+ .amux = CX231XX_AMUX_LINE_IN,
+ .gpio = NULL,
+ } },
+ },
};
const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
@@ -967,6 +993,8 @@ struct usb_device_id cx231xx_id_table[] = {
.driver_info = CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD},
{USB_DEVICE(0x15f4, 0x0135),
.driver_info = CX231XX_BOARD_ASTROMETA_T2HYBRID},
+ {USB_DEVICE(0x199e, 0x8002),
+ .driver_info = CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO},
{},
};
diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c
index f372ad3917a8..4f43668df15d 100644
--- a/drivers/media/usb/cx231xx/cx231xx-core.c
+++ b/drivers/media/usb/cx231xx/cx231xx-core.c
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
dev->name, __func__ , ##arg); } while (0)
/*****************************************************************
-* Device control list functions *
+* Device control list functions *
******************************************************************/
LIST_HEAD(cx231xx_devlist);
diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c
index 54abc1a7c8e1..fb5654062b1a 100644
--- a/drivers/media/usb/cx231xx/cx231xx-dvb.c
+++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c
@@ -762,8 +762,8 @@ static int dvb_init(struct cx231xx *dev)
/* attach demod */
memset(&si2165_pdata, 0, sizeof(si2165_pdata));
si2165_pdata.fe = &dev->dvb->frontend;
- si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL,
- si2165_pdata.ref_freq_Hz = 16000000,
+ si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL;
+ si2165_pdata.ref_freq_hz = 16000000;
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "si2165", I2C_NAME_SIZE);
@@ -809,8 +809,8 @@ static int dvb_init(struct cx231xx *dev)
/* attach demod */
memset(&si2165_pdata, 0, sizeof(si2165_pdata));
si2165_pdata.fe = &dev->dvb->frontend;
- si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT,
- si2165_pdata.ref_freq_Hz = 24000000,
+ si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT;
+ si2165_pdata.ref_freq_hz = 24000000;
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "si2165", I2C_NAME_SIZE);
diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c b/drivers/media/usb/cx231xx/cx231xx-i2c.c
index 23648dab7be8..6e1bef2a45bb 100644
--- a/drivers/media/usb/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c
@@ -51,7 +51,7 @@ do { \
if (i2c_debug >= lvl) { \
printk(KERN_DEBUG "%s at %s: " fmt, \
dev->name, __func__ , ##args); \
- } \
+ } \
} while (0)
static inline int get_real_i2c_port(struct cx231xx *dev, int bus_nr)
diff --git a/drivers/media/usb/cx231xx/cx231xx-input.c b/drivers/media/usb/cx231xx/cx231xx-input.c
index 02ebeb16055f..3e9b73a6b7c9 100644
--- a/drivers/media/usb/cx231xx/cx231xx-input.c
+++ b/drivers/media/usb/cx231xx/cx231xx-input.c
@@ -1,22 +1,12 @@
-/*
- * cx231xx IR glue driver
- *
- * Copyright (C) 2010 Mauro Carvalho Chehab
- *
- * Polaris (cx231xx) has its support for IR's with a design close to MCE.
- * however, a few designs are using an external I2C chip for IR, instead
- * of using the one provided by the chip.
- * This driver provides support for those extra devices
- *
- * This program is free software; 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// cx231xx IR glue driver
+//
+// Copyright (c) 2010 Mauro Carvalho Chehab <mchehab@kernel.org>
+//
+// Polaris (cx231xx) has its support for IR's with a design close to MCE.
+// however, a few designs are using an external I2C chip for IR, instead
+// of using the one provided by the chip.
+// This driver provides support for those extra devices
#include "cx231xx.h"
#include <linux/slab.h>
diff --git a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
index 4511dc5d199c..8f00b1d38277 100644
--- a/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
+++ b/drivers/media/usb/cx231xx/cx231xx-pcb-cfg.h
@@ -144,7 +144,7 @@ enum AVDEC_STATUS{
#define SOURCE_EXTERNAL 0x8
#define SOURCE_TS_BDA 0x10
#define SOURCE_TS_ENCODE 0x20
-#define SOURCE_TS_EXTERNAL 0x40
+#define SOURCE_TS_EXTERNAL 0x40
/***************************************************************************
* interface information define *
diff --git a/drivers/media/usb/cx231xx/cx231xx-reg.h b/drivers/media/usb/cx231xx/cx231xx-reg.h
index 750c5d37d569..db5af8d51b61 100644
--- a/drivers/media/usb/cx231xx/cx231xx-reg.h
+++ b/drivers/media/usb/cx231xx/cx231xx-reg.h
@@ -1433,16 +1433,16 @@
#define FLD_AC97_SHUTDOWN 0x00000001
/* Cx231xx redefine */
-#define QPSK_IAGC_CTL1 0x94c
-#define QPSK_IAGC_CTL2 0x950
-#define QPSK_FEPR_FREQ 0x954
-#define QPSK_BTL_CTL1 0x958
-#define QPSK_BTL_CTL2 0x95c
-#define QPSK_CTL_CTL1 0x960
-#define QPSK_CTL_CTL2 0x964
-#define QPSK_MF_FAGC_CTL 0x968
-#define QPSK_EQ_CTL 0x96c
-#define QPSK_LOCK_CTL 0x970
+#define QPSK_IAGC_CTL1 0x94c
+#define QPSK_IAGC_CTL2 0x950
+#define QPSK_FEPR_FREQ 0x954
+#define QPSK_BTL_CTL1 0x958
+#define QPSK_BTL_CTL2 0x95c
+#define QPSK_CTL_CTL1 0x960
+#define QPSK_CTL_CTL2 0x964
+#define QPSK_MF_FAGC_CTL 0x968
+#define QPSK_EQ_CTL 0x96c
+#define QPSK_LOCK_CTL 0x970
/*****************************************************************************/
#define FM1_DFT_CTL 0x9a8
diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c
index d7b2e694bbb9..271f35208c49 100644
--- a/drivers/media/usb/cx231xx/cx231xx-video.c
+++ b/drivers/media/usb/cx231xx/cx231xx-video.c
@@ -39,7 +39,7 @@
#include <media/drv-intf/msp3400.h>
#include <media/tuner.h>
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "cx231xx-vbi.h"
@@ -1756,6 +1756,8 @@ static int cx231xx_v4l2_open(struct file *filp)
case VFL_TYPE_RADIO:
radio = 1;
break;
+ default:
+ return -EINVAL;
}
cx231xx_videodbg("open dev=%s type=%s users=%d\n",
diff --git a/drivers/media/usb/cx231xx/cx231xx.h b/drivers/media/usb/cx231xx/cx231xx.h
index 72d5937a087e..65b039cf80be 100644
--- a/drivers/media/usb/cx231xx/cx231xx.h
+++ b/drivers/media/usb/cx231xx/cx231xx.h
@@ -80,6 +80,7 @@
#define CX231XX_BOARD_TERRATEC_GRABBY 22
#define CX231XX_BOARD_EVROMEDIA_FULL_HYBRID_FULLHD 23
#define CX231XX_BOARD_ASTROMETA_T2HYBRID 24
+#define CX231XX_BOARD_THE_IMAGING_SOURCE_DFG_USB2_PRO 25
/* Limits minimum and default number of buffers */
#define CX231XX_MIN_BUF 4
diff --git a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile
index bed44601f324..58c0140e19de 100644
--- a/drivers/media/usb/dvb-usb-v2/Makefile
+++ b/drivers/media/usb/dvb-usb-v2/Makefile
@@ -44,7 +44,6 @@ obj-$(CONFIG_DVB_USB_DVBSKY) += dvb-usb-dvbsky.o
dvb-usb-zd1301-objs := zd1301.o
obj-$(CONFIG_DVB_USB_ZD1301) += zd1301.o
-ccflags-y += -I$(srctree)/drivers/media/dvb-core
ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
ccflags-y += -I$(srctree)/drivers/media/tuners
ccflags-y += -I$(srctree)/drivers/media/common
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.h b/drivers/media/usb/dvb-usb-v2/anysee.h
index 393e2fce2aed..2312c55619ca 100644
--- a/drivers/media/usb/dvb-usb-v2/anysee.h
+++ b/drivers/media/usb/dvb-usb-v2/anysee.h
@@ -32,7 +32,7 @@
#define DVB_USB_LOG_PREFIX "anysee"
#include "dvb_usb.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
enum cmd {
CMD_I2C_READ = 0x33,
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
index 1414d59e85ba..746926364535 100644
--- a/drivers/media/usb/dvb-usb-v2/az6007.c
+++ b/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -23,7 +23,7 @@
#include "drxk.h"
#include "mt2063.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
#include "dvb_usb.h"
#include "cypress_firmware.h"
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb.h b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
index 0005bdb2207d..d2e80537b2f7 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb.h
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb.h
@@ -27,11 +27,11 @@
#include <media/rc-core.h>
#include <media/media-device.h>
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
-#include "dvb-usb-ids.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dmxdev.h>
+#include <media/dvb-usb-ids.h>
/*
* device file: /dev/dvb/adapter[0-1]/frontend[0-2]
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
index 131b6c08e199..43eb82884555 100644
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
@@ -309,7 +309,7 @@ static int dvbsky_s960_attach(struct dvb_usb_adapter *adap)
struct dvb_usb_device *d = adap_to_d(adap);
int ret = 0;
/* demod I2C adapter */
- struct i2c_adapter *i2c_adapter;
+ struct i2c_adapter *i2c_adapter = NULL;
struct i2c_client *client;
struct i2c_board_info info;
struct ts2020_config ts2020_config = {};
@@ -431,7 +431,7 @@ static int dvbsky_s960c_attach(struct dvb_usb_adapter *adap)
struct dvb_usb_device *d = adap_to_d(adap);
int ret = 0;
/* demod I2C adapter */
- struct i2c_adapter *i2c_adapter;
+ struct i2c_adapter *i2c_adapter = NULL;
struct i2c_client *client_tuner, *client_ci;
struct i2c_board_info info;
struct sp2_config sp2_config;
@@ -661,6 +661,65 @@ fail_demod_device:
return ret;
}
+static int dvbsky_mygica_t230c_attach(struct dvb_usb_adapter *adap)
+{
+ struct dvbsky_state *state = adap_to_priv(adap);
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct i2c_adapter *i2c_adapter;
+ struct i2c_client *client_demod, *client_tuner;
+ struct i2c_board_info info;
+ struct si2168_config si2168_config;
+ struct si2157_config si2157_config;
+
+ /* attach demod */
+ memset(&si2168_config, 0, sizeof(si2168_config));
+ si2168_config.i2c_adapter = &i2c_adapter;
+ si2168_config.fe = &adap->fe[0];
+ si2168_config.ts_mode = SI2168_TS_PARALLEL;
+ si2168_config.ts_clock_inv = 1;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "si2168", sizeof(info.type));
+ info.addr = 0x64;
+ info.platform_data = &si2168_config;
+
+ request_module("si2168");
+ client_demod = i2c_new_device(&d->i2c_adap, &info);
+ if (!client_demod || !client_demod->dev.driver)
+ goto fail_demod_device;
+ if (!try_module_get(client_demod->dev.driver->owner))
+ goto fail_demod_module;
+
+ /* attach tuner */
+ memset(&si2157_config, 0, sizeof(si2157_config));
+ si2157_config.fe = adap->fe[0];
+ si2157_config.if_port = 0;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "si2141", sizeof(info.type));
+ info.addr = 0x60;
+ info.platform_data = &si2157_config;
+
+ request_module("si2157");
+ client_tuner = i2c_new_device(i2c_adapter, &info);
+ if (!client_tuner || !client_tuner->dev.driver)
+ goto fail_tuner_device;
+ if (!try_module_get(client_tuner->dev.driver->owner))
+ goto fail_tuner_module;
+
+ state->i2c_client_demod = client_demod;
+ state->i2c_client_tuner = client_tuner;
+ return 0;
+
+fail_tuner_module:
+ i2c_unregister_device(client_tuner);
+fail_tuner_device:
+ module_put(client_demod->dev.driver->owner);
+fail_demod_module:
+ i2c_unregister_device(client_demod);
+fail_demod_device:
+ return -ENODEV;
+}
+
+
static int dvbsky_identify_state(struct dvb_usb_device *d, const char **name)
{
dvbsky_gpio_ctrl(d, 0x04, 1);
@@ -826,6 +885,32 @@ static struct dvb_usb_device_properties dvbsky_t330_props = {
}
};
+static struct dvb_usb_device_properties mygica_t230c_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct dvbsky_state),
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ .generic_bulk_ctrl_endpoint_response = 0x81,
+ .generic_bulk_ctrl_delay = DVBSKY_MSG_DELAY,
+
+ .i2c_algo = &dvbsky_i2c_algo,
+ .frontend_attach = dvbsky_mygica_t230c_attach,
+ .init = dvbsky_init,
+ .get_rc_config = dvbsky_get_rc_config,
+ .streaming_ctrl = dvbsky_streaming_ctrl,
+ .identify_state = dvbsky_identify_state,
+ .exit = dvbsky_exit,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_BULK(0x82, 8, 4096),
+ }
+ }
+};
+
static const struct usb_device_id dvbsky_id_table[] = {
{ DVB_USB_DEVICE(0x0572, 0x6831,
&dvbsky_s960_props, "DVBSky S960/S860", RC_MAP_DVBSKY) },
@@ -858,6 +943,9 @@ static const struct usb_device_id dvbsky_id_table[] = {
{ DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_S2_R4,
&dvbsky_s960_props, "Terratec Cinergy S2 Rev.4",
RC_MAP_DVBSKY) },
+ { DVB_USB_DEVICE(USB_VID_CONEXANT, USB_PID_MYGICA_T230C,
+ &mygica_t230c_props, "MyGica Mini DVB-T2 USB Stick T230C",
+ RC_MAP_TOTAL_MEDIA_IN_HAND_02) },
{ }
};
MODULE_DEVICE_TABLE(usb, dvbsky_id_table);
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index 5e320fa4a795..be26c029546b 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -494,18 +494,23 @@ static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
static int lme2510_return_status(struct dvb_usb_device *d)
{
- int ret = 0;
+ int ret;
u8 *data;
- data = kzalloc(10, GFP_KERNEL);
+ data = kzalloc(6, GFP_KERNEL);
if (!data)
return -ENOMEM;
- 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]);
+ ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+ 0x06, 0x80, 0x0302, 0x00,
+ data, 0x6, 200);
+ if (ret != 6)
+ ret = -EINVAL;
+ else
+ ret = data[2];
+
+ info("Firmware Status: %6ph", data);
- ret = (ret < 0) ? -ENODEV : data[2];
kfree(data);
return ret;
}
@@ -1071,8 +1076,6 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
if (adap->fe[0]) {
info("FE Found M88RS2000");
- dvb_attach(ts2020_attach, adap->fe[0], &ts2020_config,
- &d->i2c_adap);
st->i2c_tuner_gate_w = 5;
st->i2c_tuner_gate_r = 5;
st->i2c_tuner_addr = 0x60;
@@ -1138,17 +1141,18 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
ret = st->tuner_config;
break;
case TUNER_RS2000:
- ret = st->tuner_config;
+ if (dvb_attach(ts2020_attach, adap->fe[0],
+ &ts2020_config, &d->i2c_adap))
+ ret = st->tuner_config;
break;
default:
break;
}
- if (ret)
+ if (ret) {
info("TUN Found %s tuner", tun_msg[ret]);
- else {
- info("TUN No tuner found --- resetting device");
- lme_coldreset(d);
+ } else {
+ info("TUN No tuner found");
return -ENODEV;
}
@@ -1189,6 +1193,7 @@ static int lme2510_get_adapter_count(struct dvb_usb_device *d)
static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
{
struct lme2510_state *st = d->priv;
+ int status;
usb_reset_configuration(d->udev);
@@ -1197,12 +1202,16 @@ static int lme2510_identify_state(struct dvb_usb_device *d, const char **name)
st->dvb_usb_lme2510_firmware = dvb_usb_lme2510_firmware;
- if (lme2510_return_status(d) == 0x44) {
+ status = lme2510_return_status(d);
+ if (status == 0x44) {
*name = lme_firmware_switch(d, 0);
return COLD;
}
- return 0;
+ if (status != 0x47)
+ return -EINVAL;
+
+ return WARM;
}
static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
index f0ed37da73d4..221cf46b4140 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
@@ -477,10 +477,15 @@ static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe,
{
struct mxl111sf_demod_state *state = fe->demodulator_priv;
enum fe_modulation modulation;
+ int ret;
u16 snr;
- mxl111sf_demod_calc_snr(state, &snr);
- mxl1x1sf_demod_get_tps_modulation(state, &modulation);
+ ret = mxl111sf_demod_calc_snr(state, &snr);
+ if (ret < 0)
+ return ret;
+ ret = mxl1x1sf_demod_get_tps_modulation(state, &modulation);
+ if (ret < 0)
+ return ret;
switch (modulation) {
case QPSK:
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
index 9cb4972ce7a3..95888b8885c4 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
@@ -17,7 +17,7 @@
#ifndef __MXL111SF_DEMOD_H__
#define __MXL111SF_DEMOD_H__
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mxl111sf.h"
struct mxl111sf_demod_config {
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
index 11ea07a73271..87c1b1642115 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
@@ -17,7 +17,7 @@
#ifndef __MXL111SF_TUNER_H__
#define __MXL111SF_TUNER_H__
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "mxl111sf.h"
enum mxl_if_freq {
diff --git a/drivers/media/usb/dvb-usb/Kconfig b/drivers/media/usb/dvb-usb/Kconfig
index 959fa09dfd92..2651ae277347 100644
--- a/drivers/media/usb/dvb-usb/Kconfig
+++ b/drivers/media/usb/dvb-usb/Kconfig
@@ -86,6 +86,7 @@ config DVB_USB_DIB0700
select DVB_USB_DIB3000MC if MEDIA_SUBDRV_AUTOSELECT
select DVB_S5H1411 if MEDIA_SUBDRV_AUTOSELECT
select DVB_LGDT3305 if MEDIA_SUBDRV_AUTOSELECT
+ select DVB_MN88472 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
@@ -94,6 +95,7 @@ config DVB_USB_DIB0700
select MEDIA_TUNER_XC5000 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_XC4000 if MEDIA_SUBDRV_AUTOSELECT
select MEDIA_TUNER_MXL5007T if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_TDA18250 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
diff --git a/drivers/media/usb/dvb-usb/Makefile b/drivers/media/usb/dvb-usb/Makefile
index 16de1e4f36a4..9ad2618408ef 100644
--- a/drivers/media/usb/dvb-usb/Makefile
+++ b/drivers/media/usb/dvb-usb/Makefile
@@ -80,7 +80,6 @@ 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
diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
index 2e711362847e..f0d10ac03a37 100644
--- a/drivers/media/usb/dvb-usb/az6027.c
+++ b/drivers/media/usb/dvb-usb/az6027.c
@@ -17,7 +17,7 @@
#include "stb6100.h"
#include "stb6100_cfg.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
int dvb_usb_az6027_debug;
module_param_named(debug, dvb_usb_az6027_debug, int, 0644);
@@ -36,70 +36,70 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = {
/* 0x0000000b, SYSREG */
{ STB0899_DEV_ID , 0x30 },
{ STB0899_DISCNTRL1 , 0x32 },
- { STB0899_DISCNTRL2 , 0x80 },
- { STB0899_DISRX_ST0 , 0x04 },
- { STB0899_DISRX_ST1 , 0x00 },
- { STB0899_DISPARITY , 0x00 },
+ { STB0899_DISCNTRL2 , 0x80 },
+ { STB0899_DISRX_ST0 , 0x04 },
+ { STB0899_DISRX_ST1 , 0x00 },
+ { STB0899_DISPARITY , 0x00 },
{ STB0899_DISSTATUS , 0x20 },
- { STB0899_DISF22 , 0x99 },
- { STB0899_DISF22RX , 0xa8 },
+ { STB0899_DISF22 , 0x99 },
+ { STB0899_DISF22RX , 0xa8 },
/* SYSREG ? */
- { STB0899_ACRPRESC , 0x11 },
- { STB0899_ACRDIV1 , 0x0a },
- { STB0899_ACRDIV2 , 0x05 },
- { STB0899_DACR1 , 0x00 },
- { STB0899_DACR2 , 0x00 },
- { STB0899_OUTCFG , 0x00 },
- { STB0899_MODECFG , 0x00 },
+ { STB0899_ACRPRESC , 0x11 },
+ { STB0899_ACRDIV1 , 0x0a },
+ { STB0899_ACRDIV2 , 0x05 },
+ { STB0899_DACR1 , 0x00 },
+ { STB0899_DACR2 , 0x00 },
+ { STB0899_OUTCFG , 0x00 },
+ { STB0899_MODECFG , 0x00 },
{ STB0899_IRQSTATUS_3 , 0xfe },
{ STB0899_IRQSTATUS_2 , 0x03 },
{ STB0899_IRQSTATUS_1 , 0x7c },
{ STB0899_IRQSTATUS_0 , 0xf4 },
- { STB0899_IRQMSK_3 , 0xf3 },
- { STB0899_IRQMSK_2 , 0xfc },
- { STB0899_IRQMSK_1 , 0xff },
+ { STB0899_IRQMSK_3 , 0xf3 },
+ { STB0899_IRQMSK_2 , 0xfc },
+ { STB0899_IRQMSK_1 , 0xff },
{ STB0899_IRQMSK_0 , 0xff },
{ STB0899_IRQCFG , 0x00 },
- { STB0899_I2CCFG , 0x88 },
- { STB0899_I2CRPT , 0x58 },
+ { STB0899_I2CCFG , 0x88 },
+ { STB0899_I2CRPT , 0x58 },
{ STB0899_IOPVALUE5 , 0x00 },
{ STB0899_IOPVALUE4 , 0x33 },
{ STB0899_IOPVALUE3 , 0x6d },
{ STB0899_IOPVALUE2 , 0x90 },
{ STB0899_IOPVALUE1 , 0x60 },
{ STB0899_IOPVALUE0 , 0x00 },
- { STB0899_GPIO00CFG , 0x82 },
- { STB0899_GPIO01CFG , 0x82 },
- { STB0899_GPIO02CFG , 0x82 },
- { STB0899_GPIO03CFG , 0x82 },
- { STB0899_GPIO04CFG , 0x82 },
- { STB0899_GPIO05CFG , 0x82 },
- { STB0899_GPIO06CFG , 0x82 },
- { STB0899_GPIO07CFG , 0x82 },
- { STB0899_GPIO08CFG , 0x82 },
- { STB0899_GPIO09CFG , 0x82 },
- { STB0899_GPIO10CFG , 0x82 },
- { STB0899_GPIO11CFG , 0x82 },
- { STB0899_GPIO12CFG , 0x82 },
- { STB0899_GPIO13CFG , 0x82 },
- { STB0899_GPIO14CFG , 0x82 },
- { STB0899_GPIO15CFG , 0x82 },
- { STB0899_GPIO16CFG , 0x82 },
- { STB0899_GPIO17CFG , 0x82 },
- { STB0899_GPIO18CFG , 0x82 },
- { STB0899_GPIO19CFG , 0x82 },
- { STB0899_GPIO20CFG , 0x82 },
- { STB0899_SDATCFG , 0xb8 },
- { STB0899_SCLTCFG , 0xba },
- { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
- { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
- { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
- { STB0899_DIRCLKCFG , 0x82 },
- { STB0899_CLKOUT27CFG , 0x7e },
- { STB0899_STDBYCFG , 0x82 },
- { STB0899_CS0CFG , 0x82 },
- { STB0899_CS1CFG , 0x82 },
- { STB0899_DISEQCOCFG , 0x20 },
+ { STB0899_GPIO00CFG , 0x82 },
+ { STB0899_GPIO01CFG , 0x82 },
+ { STB0899_GPIO02CFG , 0x82 },
+ { STB0899_GPIO03CFG , 0x82 },
+ { STB0899_GPIO04CFG , 0x82 },
+ { STB0899_GPIO05CFG , 0x82 },
+ { STB0899_GPIO06CFG , 0x82 },
+ { STB0899_GPIO07CFG , 0x82 },
+ { STB0899_GPIO08CFG , 0x82 },
+ { STB0899_GPIO09CFG , 0x82 },
+ { STB0899_GPIO10CFG , 0x82 },
+ { STB0899_GPIO11CFG , 0x82 },
+ { STB0899_GPIO12CFG , 0x82 },
+ { STB0899_GPIO13CFG , 0x82 },
+ { STB0899_GPIO14CFG , 0x82 },
+ { STB0899_GPIO15CFG , 0x82 },
+ { STB0899_GPIO16CFG , 0x82 },
+ { STB0899_GPIO17CFG , 0x82 },
+ { STB0899_GPIO18CFG , 0x82 },
+ { STB0899_GPIO19CFG , 0x82 },
+ { STB0899_GPIO20CFG , 0x82 },
+ { STB0899_SDATCFG , 0xb8 },
+ { STB0899_SCLTCFG , 0xba },
+ { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
+ { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
+ { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
+ { STB0899_DIRCLKCFG , 0x82 },
+ { STB0899_CLKOUT27CFG , 0x7e },
+ { STB0899_STDBYCFG , 0x82 },
+ { STB0899_CS0CFG , 0x82 },
+ { STB0899_CS1CFG , 0x82 },
+ { STB0899_DISEQCOCFG , 0x20 },
{ STB0899_GPIO32CFG , 0x82 },
{ STB0899_GPIO33CFG , 0x82 },
{ STB0899_GPIO34CFG , 0x82 },
@@ -108,35 +108,35 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = {
{ STB0899_GPIO37CFG , 0x82 },
{ STB0899_GPIO38CFG , 0x82 },
{ STB0899_GPIO39CFG , 0x82 },
- { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
- { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
- { STB0899_FILTCTRL , 0x00 },
- { STB0899_SYSCTRL , 0x01 },
- { STB0899_STOPCLK1 , 0x20 },
- { STB0899_STOPCLK2 , 0x00 },
+ { STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
+ { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
+ { STB0899_FILTCTRL , 0x00 },
+ { STB0899_SYSCTRL , 0x01 },
+ { STB0899_STOPCLK1 , 0x20 },
+ { STB0899_STOPCLK2 , 0x00 },
{ STB0899_INTBUFSTATUS , 0x00 },
- { STB0899_INTBUFCTRL , 0x0a },
+ { STB0899_INTBUFCTRL , 0x0a },
{ 0xffff , 0xff },
};
static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
- { STB0899_DEMOD , 0x00 },
- { STB0899_RCOMPC , 0xc9 },
- { STB0899_AGC1CN , 0x01 },
- { STB0899_AGC1REF , 0x10 },
+ { STB0899_DEMOD , 0x00 },
+ { STB0899_RCOMPC , 0xc9 },
+ { STB0899_AGC1CN , 0x01 },
+ { STB0899_AGC1REF , 0x10 },
{ STB0899_RTC , 0x23 },
- { STB0899_TMGCFG , 0x4e },
- { STB0899_AGC2REF , 0x34 },
- { STB0899_TLSR , 0x84 },
- { STB0899_CFD , 0xf7 },
+ { STB0899_TMGCFG , 0x4e },
+ { STB0899_AGC2REF , 0x34 },
+ { STB0899_TLSR , 0x84 },
+ { STB0899_CFD , 0xf7 },
{ STB0899_ACLC , 0x87 },
- { STB0899_BCLC , 0x94 },
- { STB0899_EQON , 0x41 },
- { STB0899_LDT , 0xf1 },
- { STB0899_LDT2 , 0xe3 },
- { STB0899_EQUALREF , 0xb4 },
- { STB0899_TMGRAMP , 0x10 },
- { STB0899_TMGTHD , 0x30 },
+ { STB0899_BCLC , 0x94 },
+ { STB0899_EQON , 0x41 },
+ { STB0899_LDT , 0xf1 },
+ { STB0899_LDT2 , 0xe3 },
+ { STB0899_EQUALREF , 0xb4 },
+ { STB0899_TMGRAMP , 0x10 },
+ { STB0899_TMGTHD , 0x30 },
{ STB0899_IDCCOMP , 0xfd },
{ STB0899_QDCCOMP , 0xff },
{ STB0899_POWERI , 0x0c },
@@ -155,12 +155,12 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
{ STB0899_NIRL , 0x80 },
{ STB0899_ISYMB , 0x1d },
{ STB0899_QSYMB , 0xa6 },
- { STB0899_SFRH , 0x2f },
- { STB0899_SFRM , 0x68 },
- { STB0899_SFRL , 0x40 },
- { STB0899_SFRUPH , 0x2f },
- { STB0899_SFRUPM , 0x68 },
- { STB0899_SFRUPL , 0x40 },
+ { STB0899_SFRH , 0x2f },
+ { STB0899_SFRM , 0x68 },
+ { STB0899_SFRL , 0x40 },
+ { STB0899_SFRUPH , 0x2f },
+ { STB0899_SFRUPM , 0x68 },
+ { STB0899_SFRUPL , 0x40 },
{ STB0899_EQUAI1 , 0x02 },
{ STB0899_EQUAQ1 , 0xff },
{ STB0899_EQUAI2 , 0x04 },
@@ -172,7 +172,7 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
{ STB0899_EQUAI5 , 0x08 },
{ STB0899_EQUAQ5 , 0xf5 },
{ STB0899_DSTATUS2 , 0x00 },
- { STB0899_VSTATUS , 0x00 },
+ { STB0899_VSTATUS , 0x00 },
{ STB0899_VERROR , 0x86 },
{ STB0899_IQSWAP , 0x2a },
{ STB0899_ECNT1M , 0x00 },
@@ -181,26 +181,26 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
{ STB0899_ECNT2L , 0x00 },
{ STB0899_ECNT3M , 0x0a },
{ STB0899_ECNT3L , 0xad },
- { STB0899_FECAUTO1 , 0x06 },
+ { STB0899_FECAUTO1 , 0x06 },
{ STB0899_FECM , 0x01 },
- { STB0899_VTH12 , 0xb0 },
- { STB0899_VTH23 , 0x7a },
+ { STB0899_VTH12 , 0xb0 },
+ { STB0899_VTH23 , 0x7a },
{ STB0899_VTH34 , 0x58 },
- { STB0899_VTH56 , 0x38 },
- { STB0899_VTH67 , 0x34 },
- { STB0899_VTH78 , 0x24 },
- { STB0899_PRVIT , 0xff },
- { STB0899_VITSYNC , 0x19 },
- { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
- { STB0899_TSULC , 0x42 },
- { STB0899_RSLLC , 0x41 },
+ { STB0899_VTH56 , 0x38 },
+ { STB0899_VTH67 , 0x34 },
+ { STB0899_VTH78 , 0x24 },
+ { STB0899_PRVIT , 0xff },
+ { STB0899_VITSYNC , 0x19 },
+ { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
+ { STB0899_TSULC , 0x42 },
+ { STB0899_RSLLC , 0x41 },
{ STB0899_TSLPL , 0x12 },
- { STB0899_TSCFGH , 0x0c },
- { STB0899_TSCFGM , 0x00 },
- { STB0899_TSCFGL , 0x00 },
+ { STB0899_TSCFGH , 0x0c },
+ { STB0899_TSCFGM , 0x00 },
+ { STB0899_TSCFGL , 0x00 },
{ STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */
- { STB0899_RSSYNCDEL , 0x00 },
- { STB0899_TSINHDELH , 0x02 },
+ { STB0899_RSSYNCDEL , 0x00 },
+ { STB0899_TSINHDELH , 0x02 },
{ STB0899_TSINHDELM , 0x00 },
{ STB0899_TSINHDELL , 0x00 },
{ STB0899_TSLLSTKM , 0x1b },
@@ -211,18 +211,18 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_3[] = {
{ STB0899_PCKLENLL , 0xcc },
{ STB0899_RSPCKLEN , 0xbd },
{ STB0899_TSSTATUS , 0x90 },
- { STB0899_ERRCTRL1 , 0xb6 },
- { STB0899_ERRCTRL2 , 0x95 },
- { STB0899_ERRCTRL3 , 0x8d },
+ { STB0899_ERRCTRL1 , 0xb6 },
+ { STB0899_ERRCTRL2 , 0x95 },
+ { STB0899_ERRCTRL3 , 0x8d },
{ STB0899_DMONMSK1 , 0x27 },
{ STB0899_DMONMSK0 , 0x03 },
- { STB0899_DEMAPVIT , 0x5c },
+ { STB0899_DEMAPVIT , 0x5c },
{ STB0899_PLPARM , 0x19 },
- { STB0899_PDELCTRL , 0x48 },
- { STB0899_PDELCTRL2 , 0x00 },
- { STB0899_BBHCTRL1 , 0x00 },
- { STB0899_BBHCTRL2 , 0x00 },
- { STB0899_HYSTTHRESH , 0x77 },
+ { STB0899_PDELCTRL , 0x48 },
+ { STB0899_PDELCTRL2 , 0x00 },
+ { STB0899_BBHCTRL1 , 0x00 },
+ { STB0899_BBHCTRL2 , 0x00 },
+ { STB0899_HYSTTHRESH , 0x77 },
{ STB0899_MATCSTM , 0x00 },
{ STB0899_MATCSTL , 0x00 },
{ STB0899_UPLCSTM , 0x00 },
@@ -261,7 +261,7 @@ static struct stb0899_config az6027_stb0899_config = {
.init_s2_fec = stb0899_s2_init_4,
.init_tst = stb0899_s1_init_5,
- .demod_address = 0xd0, /* 0x68, 0xd0 >> 1 */
+ .demod_address = 0xd0, /* 0x68, 0xd0 >> 1 */
.xtal_freq = 27000000,
.inversion = IQ_SWAP_ON,
@@ -1181,9 +1181,9 @@ static struct dvb_usb_device_properties az6027_properties = {
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver az6027_usb_driver = {
.name = "dvb_usb_az6027",
- .probe = az6027_usb_probe,
- .disconnect = az6027_usb_disconnect,
- .id_table = az6027_usb_table,
+ .probe = az6027_usb_probe,
+ .disconnect = az6027_usb_disconnect,
+ .id_table = az6027_usb_table,
};
module_usb_driver(az6027_usb_driver);
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c
index 37dea0adc695..2abd15c6df81 100644
--- a/drivers/media/usb/dvb-usb/cxusb.c
+++ b/drivers/media/usb/dvb-usb/cxusb.c
@@ -26,6 +26,7 @@
#include <media/tuner.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
+#include <linux/kernel.h>
#include "cxusb.h"
@@ -56,7 +57,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args)
static int cxusb_ctrl_msg(struct dvb_usb_device *d,
- u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+ u8 cmd, const u8 *wbuf, int wlen, u8 *rbuf, int rlen)
{
struct cxusb_state *st = d->priv;
int ret;
@@ -290,7 +291,8 @@ static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
/* FIXME: We don't know why, but we need to configure the
* lgdt3303 with the register settings below on resume */
int i;
- u8 buf, bufs[] = {
+ u8 buf;
+ static const u8 bufs[] = {
0x0e, 0x2, 0x00, 0x7f,
0x0e, 0x2, 0x02, 0xfe,
0x0e, 0x2, 0x02, 0x01,
@@ -303,7 +305,7 @@ static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff)
0x0e, 0x2, 0x47, 0x88,
};
msleep(20);
- for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) {
+ for (i = 0; i < ARRAY_SIZE(bufs); i += 4 / sizeof(u8)) {
ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE,
bufs+i, 4, &buf, 1);
if (ret)
@@ -677,6 +679,8 @@ static int dvico_bluebird_xc2028_callback(void *ptr, int component,
case XC2028_RESET_CLK:
deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg);
break;
+ case XC2028_I2C_FLUSH:
+ break;
default:
deb_info("%s: unknown command %d, arg %d\n", __func__,
command, arg);
diff --git a/drivers/media/usb/dvb-usb/dib0700.h b/drivers/media/usb/dvb-usb/dib0700.h
index f89ab3b5a6c4..3a9d4c288cc2 100644
--- a/drivers/media/usb/dvb-usb/dib0700.h
+++ b/drivers/media/usb/dvb-usb/dib0700.h
@@ -51,6 +51,8 @@ struct dib0700_state {
int (*read_status)(struct dvb_frontend *, enum fe_status *);
int (*sleep)(struct dvb_frontend* fe);
u8 buf[255];
+ struct i2c_client *i2c_client_demod;
+ struct i2c_client *i2c_client_tuner;
};
extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
index 1ee7ec558293..94bd176104c1 100644
--- a/drivers/media/usb/dvb-usb/dib0700_core.c
+++ b/drivers/media/usb/dvb-usb/dib0700_core.c
@@ -911,10 +911,34 @@ static int dib0700_probe(struct usb_interface *intf,
return -ENODEV;
}
+static void dib0700_disconnect(struct usb_interface *intf)
+{
+ struct dvb_usb_device *d = usb_get_intfdata(intf);
+ struct dib0700_state *st = d->priv;
+ struct i2c_client *client;
+
+ /* remove I2C client for tuner */
+ client = st->i2c_client_tuner;
+ if (client) {
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+ }
+
+ /* remove I2C client for demodulator */
+ client = st->i2c_client_demod;
+ if (client) {
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+ }
+
+ dvb_usb_device_exit(intf);
+}
+
+
static struct usb_driver dib0700_driver = {
.name = "dvb_usb_dib0700",
.probe = dib0700_probe,
- .disconnect = dvb_usb_device_exit,
+ .disconnect = dib0700_disconnect,
.id_table = dib0700_usb_id_table,
};
diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c
index 366b05529915..3d99e141d566 100644
--- a/drivers/media/usb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -23,6 +23,9 @@
#include "dib0090.h"
#include "lgdt3305.h"
#include "mxl5007t.h"
+#include "mn88472.h"
+#include "tda18250.h"
+
static int force_lna_activation;
module_param(force_lna_activation, int, 0644);
@@ -430,6 +433,7 @@ static int stk7700ph_xc3028_callback(void *ptr, int component,
state->dib7000p_ops.set_gpio(adap->fe_adap[0].fe, 8, 0, 1);
break;
case XC2028_RESET_CLK:
+ case XC2028_I2C_FLUSH:
break;
default:
err("%s: unknown command %d, arg %d\n", __func__,
@@ -3725,6 +3729,90 @@ static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
&hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
}
+static int xbox_one_attach(struct dvb_usb_adapter *adap)
+{
+ struct dib0700_state *st = adap->dev->priv;
+ struct i2c_client *client_demod, *client_tuner;
+ struct dvb_usb_device *d = adap->dev;
+ struct mn88472_config mn88472_config = { };
+ struct tda18250_config tda18250_config;
+ struct i2c_board_info info;
+
+ st->fw_use_new_i2c_api = 1;
+ st->disable_streaming_master_mode = 1;
+
+ /* fe power enable */
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ msleep(30);
+
+ /* demod reset */
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(30);
+
+ /* attach demod */
+ mn88472_config.fe = &adap->fe_adap[0].fe;
+ mn88472_config.i2c_wr_max = 22;
+ mn88472_config.xtal = 20500000;
+ mn88472_config.ts_mode = PARALLEL_TS_MODE;
+ mn88472_config.ts_clock = FIXED_TS_CLOCK;
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "mn88472", I2C_NAME_SIZE);
+ info.addr = 0x18;
+ info.platform_data = &mn88472_config;
+ request_module(info.type);
+ client_demod = i2c_new_device(&d->i2c_adap, &info);
+ if (client_demod == NULL || client_demod->dev.driver == NULL)
+ goto fail_demod_device;
+ if (!try_module_get(client_demod->dev.driver->owner))
+ goto fail_demod_module;
+
+ st->i2c_client_demod = client_demod;
+
+ adap->fe_adap[0].fe = mn88472_config.get_dvb_frontend(client_demod);
+
+ /* attach tuner */
+ memset(&tda18250_config, 0, sizeof(tda18250_config));
+ tda18250_config.if_dvbt_6 = 3950;
+ tda18250_config.if_dvbt_7 = 4450;
+ tda18250_config.if_dvbt_8 = 4950;
+ tda18250_config.if_dvbc_6 = 4950;
+ tda18250_config.if_dvbc_8 = 4950;
+ tda18250_config.if_atsc = 4079;
+ tda18250_config.loopthrough = true;
+ tda18250_config.xtal_freq = TDA18250_XTAL_FREQ_27MHZ;
+ tda18250_config.fe = adap->fe_adap[0].fe;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "tda18250", I2C_NAME_SIZE);
+ info.addr = 0x60;
+ info.platform_data = &tda18250_config;
+
+ request_module(info.type);
+ client_tuner = i2c_new_device(&adap->dev->i2c_adap, &info);
+ if (client_tuner == NULL || client_tuner->dev.driver == NULL)
+ goto fail_tuner_device;
+ if (!try_module_get(client_tuner->dev.driver->owner))
+ goto fail_tuner_module;
+
+ st->i2c_client_tuner = client_tuner;
+ return 0;
+
+fail_tuner_module:
+ i2c_unregister_device(client_tuner);
+fail_tuner_device:
+ module_put(client_demod->dev.driver->owner);
+fail_demod_module:
+ i2c_unregister_device(client_demod);
+fail_demod_device:
+ return -ENODEV;
+}
+
/* DVB-USB and USB stuff follows */
struct usb_device_id dib0700_usb_id_table[] = {
@@ -3816,7 +3904,8 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_PCTV, USB_PID_PCTV_2002E_SE) },
{ USB_DEVICE(USB_VID_PCTV, USB_PID_DIBCOM_STK8096PVR) },
{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096PVR) },
- { USB_DEVICE(USB_VID_HAMA, USB_PID_HAMA_DVBT_HYBRID) },
+/* 85 */{ USB_DEVICE(USB_VID_HAMA, USB_PID_HAMA_DVBT_HYBRID) },
+ { USB_DEVICE(USB_VID_MICROSOFT, USB_PID_XBOX_ONE_TUNER) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -5040,6 +5129,25 @@ struct dvb_usb_device_properties dib0700_devices[] = {
RC_PROTO_BIT_NEC,
.change_protocol = dib0700_change_protocol,
},
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+ .num_adapters = 1,
+ .adapter = {
+ {
+ DIB0700_NUM_FRONTENDS(1),
+ .fe = {{
+ .frontend_attach = xbox_one_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x82),
+ } },
+ },
+ },
+ .num_device_descs = 1,
+ .devices = {
+ { "Microsoft Xbox One Digital TV Tuner",
+ { &dib0700_usb_id_table[86], NULL },
+ { NULL },
+ },
+ },
},
};
diff --git a/drivers/media/usb/dvb-usb/dvb-usb.h b/drivers/media/usb/dvb-usb/dvb-usb.h
index e71fc86b4fb2..317ed6a82d19 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb.h
+++ b/drivers/media/usb/dvb-usb/dvb-usb.h
@@ -17,14 +17,14 @@
#include <linux/mutex.h>
#include <media/rc-core.h>
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dmxdev.h>
#include "dvb-pll.h"
-#include "dvb-usb-ids.h"
+#include <media/dvb-usb-ids.h>
/* debug */
#ifdef CONFIG_DVB_USB_DEBUG
diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c
index b421329b21fa..346946f35b1a 100644
--- a/drivers/media/usb/dvb-usb/dw2102.c
+++ b/drivers/media/usb/dvb-usb/dw2102.c
@@ -13,7 +13,7 @@
*
* see Documentation/dvb/README.dvb-usb for more information
*/
-#include "dvb-usb-ids.h"
+#include <media/dvb-usb-ids.h>
#include "dw2102.h"
#include "si21xx.h"
#include "stv0299.h"
diff --git a/drivers/media/usb/dvb-usb/friio-fe.c b/drivers/media/usb/dvb-usb/friio-fe.c
index b6046e0e07f6..b2830c157548 100644
--- a/drivers/media/usb/dvb-usb/friio-fe.c
+++ b/drivers/media/usb/dvb-usb/friio-fe.c
@@ -13,6 +13,7 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
+#include <linux/kernel.h>
#include "friio.h"
@@ -340,8 +341,6 @@ static u8 init_code[][2] = {
{0x76, 0x0C},
};
-static const int init_code_len = sizeof(init_code) / sizeof(u8[2]);
-
static int jdvbt90502_init(struct dvb_frontend *fe)
{
int i = -1;
@@ -355,7 +354,7 @@ static int jdvbt90502_init(struct dvb_frontend *fe)
msg.addr = state->config.demod_address;
msg.flags = 0;
msg.len = 2;
- for (i = 0; i < init_code_len; i++) {
+ for (i = 0; i < ARRAY_SIZE(init_code); i++) {
msg.buf = init_code[i];
ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 1)
diff --git a/drivers/media/usb/dvb-usb/pctv452e.c b/drivers/media/usb/dvb-usb/pctv452e.c
index 601ade7ca48d..0af74383083d 100644
--- a/drivers/media/usb/dvb-usb/pctv452e.c
+++ b/drivers/media/usb/dvb-usb/pctv452e.c
@@ -26,7 +26,7 @@
/* FE Power */
#include "lnbp22.h"
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
#include "ttpci-eeprom.h"
static int debug;
@@ -913,6 +913,14 @@ static int pctv452e_frontend_attach(struct dvb_usb_adapter *a)
&a->dev->i2c_adap);
if (!a->fe_adap[0].fe)
return -ENODEV;
+
+ /*
+ * dvb_frontend will call dvb_detach for both stb0899_detach
+ * and stb0899_release but we only do dvb_attach(stb0899_attach).
+ * Increment the module refcount instead.
+ */
+ symbol_get(stb0899_attach);
+
if ((dvb_attach(lnbp22_attach, a->fe_adap[0].fe,
&a->dev->i2c_adap)) == NULL)
err("Cannot attach lnbp22\n");
diff --git a/drivers/media/usb/dvb-usb/ttusb2.c b/drivers/media/usb/dvb-usb/ttusb2.c
index e7020f245f53..12de89665d60 100644
--- a/drivers/media/usb/dvb-usb/ttusb2.c
+++ b/drivers/media/usb/dvb-usb/ttusb2.c
@@ -34,7 +34,7 @@
#include "tda827x.h"
#include "lnbp21.h"
/* CA */
-#include "dvb_ca_en50221.h"
+#include <media/dvb_ca_en50221.h>
/* debug */
static int dvb_usb_ttusb2_debug;
diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig
index 4cc029f18aa8..451e076525d3 100644
--- a/drivers/media/usb/em28xx/Kconfig
+++ b/drivers/media/usb/em28xx/Kconfig
@@ -71,10 +71,10 @@ config VIDEO_EM28XX_DVB
Empiatech em28xx chips.
config VIDEO_EM28XX_RC
- tristate "EM28XX Remote Controller support"
- depends on RC_CORE
- depends on VIDEO_EM28XX
- depends on !(RC_CORE=m && VIDEO_EM28XX=y)
- default VIDEO_EM28XX
- ---help---
- Enables Remote Controller support on em28xx driver.
+ tristate "EM28XX Remote Controller support"
+ depends on RC_CORE
+ depends on VIDEO_EM28XX
+ depends on !(RC_CORE=m && VIDEO_EM28XX=y)
+ default VIDEO_EM28XX
+ ---help---
+ Enables Remote Controller support on em28xx driver.
diff --git a/drivers/media/usb/em28xx/Makefile b/drivers/media/usb/em28xx/Makefile
index 86bfc35e2ed4..8a224007d755 100644
--- a/drivers/media/usb/em28xx/Makefile
+++ b/drivers/media/usb/em28xx/Makefile
@@ -11,7 +11,5 @@ 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/i2c
ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
index 4c57fd7929cb..34e16f6ab4ac 100644
--- a/drivers/media/usb/em28xx/em28xx-cards.c
+++ b/drivers/media/usb/em28xx/em28xx-cards.c
@@ -36,7 +36,6 @@
#include <media/i2c/saa7115.h>
#include <dt-bindings/media/tvp5150.h>
#include <media/i2c/tvaudio.h>
-#include <media/i2c-addr.h>
#include <media/tveeprom.h>
#include <media/v4l2-common.h>
#include <sound/ac97_codec.h>
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c
index 9950a740e04e..8a81c94a8a27 100644
--- a/drivers/media/usb/em28xx/em28xx-dvb.c
+++ b/drivers/media/usb/em28xx/em28xx-dvb.c
@@ -28,9 +28,9 @@
#include <linux/usb.h>
#include <media/v4l2-common.h>
-#include <dvb_demux.h>
-#include <dvb_net.h>
-#include <dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dmxdev.h>
#include <media/tuner.h>
#include "tuner-simple.h"
#include <linux/gpio.h>
@@ -2105,6 +2105,8 @@ static int em28xx_dvb_fini(struct em28xx *dev)
}
}
+ em28xx_unregister_dvb(dvb);
+
/* remove I2C SEC */
client = dvb->i2c_client_sec;
if (client) {
@@ -2126,7 +2128,6 @@ static int em28xx_dvb_fini(struct em28xx *dev)
i2c_unregister_device(client);
}
- em28xx_unregister_dvb(dvb);
kfree(dvb);
dev->dvb = NULL;
kref_put(&dev->ref, em28xx_free_device);
diff --git a/drivers/media/usb/gspca/autogain_functions.c b/drivers/media/usb/gspca/autogain_functions.c
index 427db745e027..6dfab2b077f7 100644
--- a/drivers/media/usb/gspca/autogain_functions.c
+++ b/drivers/media/usb/gspca/autogain_functions.c
@@ -32,7 +32,7 @@ int gspca_expo_autogain(
int i, steps, retval = 0;
if (v4l2_ctrl_g_ctrl(gspca_dev->autogain) == 0)
- return 0;
+ return 0;
orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain);
orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
@@ -41,8 +41,8 @@ int gspca_expo_autogain(
desired lumination fast (with the risc of a slight overshoot) */
steps = abs(desired_avg_lum - avg_lum) / deadzone;
- PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
- avg_lum, desired_avg_lum, steps);
+ gspca_dbg(gspca_dev, D_FRAM, "autogain: lum: %d, desired: %d, steps: %d\n",
+ avg_lum, desired_avg_lum, steps);
for (i = 0; i < steps; i++) {
if (avg_lum > desired_avg_lum) {
@@ -75,17 +75,17 @@ int gspca_expo_autogain(
}
if (gain != orig_gain) {
- v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
+ v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
retval = 1;
}
if (exposure != orig_exposure) {
- v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
+ v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
retval = 1;
}
if (retval)
- PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
- gain, exposure);
+ gspca_dbg(gspca_dev, D_FRAM, "autogain: changed gain: %d, expo: %d\n",
+ gain, exposure);
return retval;
}
EXPORT_SYMBOL(gspca_expo_autogain);
@@ -112,7 +112,7 @@ int gspca_coarse_grained_expo_autogain(
int steps, retval = 0;
if (v4l2_ctrl_g_ctrl(gspca_dev->autogain) == 0)
- return 0;
+ return 0;
orig_gain = gain = v4l2_ctrl_g_ctrl(gspca_dev->gain);
orig_exposure = exposure = v4l2_ctrl_g_ctrl(gspca_dev->exposure);
@@ -126,8 +126,8 @@ int gspca_coarse_grained_expo_autogain(
desired lumination fast (with the risc of a slight overshoot) */
steps = (desired_avg_lum - avg_lum) / deadzone;
- PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
- avg_lum, desired_avg_lum, steps);
+ gspca_dbg(gspca_dev, D_FRAM, "autogain: lum: %d, desired: %d, steps: %d\n",
+ avg_lum, desired_avg_lum, steps);
if ((gain + steps) > gain_high &&
exposure < gspca_dev->exposure->maximum) {
@@ -158,17 +158,17 @@ int gspca_coarse_grained_expo_autogain(
}
if (gain != orig_gain) {
- v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
+ v4l2_ctrl_s_ctrl(gspca_dev->gain, gain);
retval = 1;
}
if (exposure != orig_exposure) {
- v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
+ v4l2_ctrl_s_ctrl(gspca_dev->exposure, exposure);
retval = 1;
}
if (retval)
- PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
- gain, exposure);
+ gspca_dbg(gspca_dev, D_FRAM, "autogain: changed gain: %d, expo: %d\n",
+ gain, exposure);
return retval;
}
EXPORT_SYMBOL(gspca_coarse_grained_expo_autogain);
diff --git a/drivers/media/usb/gspca/benq.c b/drivers/media/usb/gspca/benq.c
index 60a728203b3b..8a8db5eb6d5f 100644
--- a/drivers/media/usb/gspca/benq.c
+++ b/drivers/media/usb/gspca/benq.c
@@ -152,7 +152,7 @@ static void sd_isoc_irq(struct urb *urb)
u8 *data;
int i, st;
- PDEBUG(D_PACK, "sd isoc irq");
+ gspca_dbg(gspca_dev, D_PACK, "sd isoc irq\n");
if (!gspca_dev->streaming)
return;
if (urb->status != 0) {
@@ -180,9 +180,9 @@ static void sd_isoc_irq(struct urb *urb)
/* check the packet status and length */
if (urb0->iso_frame_desc[i].actual_length != SD_PKT_SZ
|| urb->iso_frame_desc[i].actual_length != SD_PKT_SZ) {
- PERR("ISOC bad lengths %d / %d",
- urb0->iso_frame_desc[i].actual_length,
- urb->iso_frame_desc[i].actual_length);
+ gspca_err(gspca_dev, "ISOC bad lengths %d / %d\n",
+ urb0->iso_frame_desc[i].actual_length,
+ urb->iso_frame_desc[i].actual_length);
gspca_dev->last_packet_type = DISCARD_PACKET;
continue;
}
diff --git a/drivers/media/usb/gspca/conex.c b/drivers/media/usb/gspca/conex.c
index bdcdf7999c56..6df4e204e291 100644
--- a/drivers/media/usb/gspca/conex.c
+++ b/drivers/media/usb/gspca/conex.c
@@ -70,7 +70,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
struct usb_device *dev = gspca_dev->dev;
if (len > USB_BUF_SZ) {
- PERR("reg_r: buffer overflow\n");
+ gspca_err(gspca_dev, "reg_r: buffer overflow\n");
return;
}
@@ -81,8 +81,8 @@ static void reg_r(struct gspca_dev *gspca_dev,
0,
index, gspca_dev->usb_buf, len,
500);
- PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
- index, gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "reg read [%02x] -> %02x ..\n",
+ index, gspca_dev->usb_buf[0]);
}
/* the bytes to write are in gspca_dev->usb_buf */
@@ -109,10 +109,11 @@ static void reg_w(struct gspca_dev *gspca_dev,
struct usb_device *dev = gspca_dev->dev;
if (len > USB_BUF_SZ) {
- PERR("reg_w: buffer overflow\n");
+ gspca_err(gspca_dev, "reg_w: buffer overflow\n");
return;
}
- PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
+ gspca_dbg(gspca_dev, D_USBO, "reg write [%02x] = %02x..\n",
+ index, *buffer);
memcpy(gspca_dev->usb_buf, buffer, len);
usb_control_msg(dev,
@@ -683,7 +684,7 @@ static void cx11646_jpeg(struct gspca_dev*gspca_dev)
reg_w_val(gspca_dev, 0x0053, 0x00);
} while (--retry);
if (retry == 0)
- PERR("Damned Errors sending jpeg Table");
+ gspca_err(gspca_dev, "Damned Errors sending jpeg Table\n");
/* send the qtable now */
reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
length = 8;
diff --git a/drivers/media/usb/gspca/cpia1.c b/drivers/media/usb/gspca/cpia1.c
index e91d00762e94..2b09af8865f4 100644
--- a/drivers/media/usb/gspca/cpia1.c
+++ b/drivers/media/usb/gspca/cpia1.c
@@ -419,7 +419,8 @@ static int cpia_usb_transferCmd(struct gspca_dev *gspca_dev, u8 *command)
pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
requesttype = USB_TYPE_VENDOR | USB_RECIP_DEVICE;
} else {
- PERR("Unexpected first byte of command: %x", command[0]);
+ gspca_err(gspca_dev, "Unexpected first byte of command: %x\n",
+ command[0]);
return -EINVAL;
}
@@ -542,7 +543,7 @@ static int do_command(struct gspca_dev *gspca_dev, u16 command,
input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
input_sync(gspca_dev->input_dev);
#endif
- sd->params.qx3.button = a;
+ sd->params.qx3.button = a;
}
if (sd->params.qx3.button) {
/* button pressed - unlock the latch */
@@ -700,11 +701,11 @@ static void reset_camera_params(struct gspca_dev *gspca_dev)
static void printstatus(struct gspca_dev *gspca_dev, struct cam_params *params)
{
- PDEBUG(D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x",
- params->status.systemState, params->status.grabState,
- params->status.streamState, params->status.fatalError,
- params->status.cmdError, params->status.debugFlags,
- params->status.vpStatus, params->status.errorCode);
+ gspca_dbg(gspca_dev, D_PROBE, "status: %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ params->status.systemState, params->status.grabState,
+ params->status.streamState, params->status.fatalError,
+ params->status.cmdError, params->status.debugFlags,
+ params->status.vpStatus, params->status.errorCode);
}
static int goto_low_power(struct gspca_dev *gspca_dev)
@@ -722,14 +723,14 @@ static int goto_low_power(struct gspca_dev *gspca_dev)
if (sd->params.status.systemState != LO_POWER_STATE) {
if (sd->params.status.systemState != WARM_BOOT_STATE) {
- PERR("unexpected state after lo power cmd: %02x",
- sd->params.status.systemState);
+ gspca_err(gspca_dev, "unexpected state after lo power cmd: %02x\n",
+ sd->params.status.systemState);
printstatus(gspca_dev, &sd->params);
}
return -EIO;
}
- PDEBUG(D_CONF, "camera now in LOW power state");
+ gspca_dbg(gspca_dev, D_CONF, "camera now in LOW power state\n");
return 0;
}
@@ -752,13 +753,13 @@ static int goto_high_power(struct gspca_dev *gspca_dev)
return ret;
if (sd->params.status.systemState != HI_POWER_STATE) {
- PERR("unexpected state after hi power cmd: %02x",
- sd->params.status.systemState);
+ gspca_err(gspca_dev, "unexpected state after hi power cmd: %02x\n",
+ sd->params.status.systemState);
printstatus(gspca_dev, &sd->params);
return -EIO;
}
- PDEBUG(D_CONF, "camera now in HIGH power state");
+ gspca_dbg(gspca_dev, D_CONF, "camera now in HIGH power state\n");
return 0;
}
@@ -1301,7 +1302,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
sd->params.exposure.coarseExpHi = new_exposure >> 8;
setexp = 1;
sd->exposure_status = EXPOSURE_NORMAL;
- PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
+ gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
sd->exposure_status == EXPOSURE_LIGHT) &&
@@ -1330,7 +1331,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
sd->params.exposure.coarseExpHi = new_exposure >> 8;
setexp = 1;
sd->exposure_status = EXPOSURE_NORMAL;
- PDEBUG(D_CONF, "Automatically increasing sensor_fps");
+ gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
}
} else {
/* Flicker control off */
@@ -1348,7 +1349,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
setexp = 1;
}
sd->exposure_status = EXPOSURE_NORMAL;
- PDEBUG(D_CONF, "Automatically decreasing sensor_fps");
+ gspca_dbg(gspca_dev, D_CONF, "Automatically decreasing sensor_fps\n");
} else if ((sd->exposure_status == EXPOSURE_VERY_LIGHT ||
sd->exposure_status == EXPOSURE_LIGHT) &&
@@ -1365,7 +1366,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
setexp = 1;
}
sd->exposure_status = EXPOSURE_NORMAL;
- PDEBUG(D_CONF, "Automatically increasing sensor_fps");
+ gspca_dbg(gspca_dev, D_CONF, "Automatically increasing sensor_fps\n");
}
}
@@ -1433,8 +1434,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->mainsFreq = FREQ_DEF == V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
reset_camera_params(gspca_dev);
- PDEBUG(D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)",
- id->idVendor, id->idProduct);
+ gspca_dbg(gspca_dev, D_PROBE, "cpia CPiA camera detected (vid/pid 0x%04X:0x%04X)\n",
+ id->idVendor, id->idProduct);
cam = &gspca_dev->cam;
cam->cam_mode = mode;
@@ -1445,8 +1446,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->params.version.firmwareVersion = 0;
get_version_information(gspca_dev);
if (sd->params.version.firmwareVersion != 1) {
- PERR("only firmware version 1 is supported (got: %d)",
- sd->params.version.firmwareVersion);
+ gspca_err(gspca_dev, "only firmware version 1 is supported (got: %d)\n",
+ sd->params.version.firmwareVersion);
return -ENODEV;
}
@@ -1471,8 +1472,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* Start the camera in low power mode */
if (goto_low_power(gspca_dev)) {
if (sd->params.status.systemState != WARM_BOOT_STATE) {
- PERR("unexpected systemstate: %02x",
- sd->params.status.systemState);
+ gspca_err(gspca_dev, "unexpected systemstate: %02x\n",
+ sd->params.status.systemState);
printstatus(gspca_dev, &sd->params);
return -ENODEV;
}
@@ -1519,8 +1520,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
return ret;
if (sd->params.status.fatalError) {
- PERR("fatal_error: %04x, vp_status: %04x",
- sd->params.status.fatalError, sd->params.status.vpStatus);
+ gspca_err(gspca_dev, "fatal_error: %04x, vp_status: %04x\n",
+ sd->params.status.fatalError,
+ sd->params.status.vpStatus);
return -EIO;
}
@@ -1667,18 +1669,18 @@ static int sd_init(struct gspca_dev *gspca_dev)
sd_stopN(gspca_dev);
- PDEBUG(D_PROBE, "CPIA Version: %d.%02d (%d.%d)",
- sd->params.version.firmwareVersion,
- sd->params.version.firmwareRevision,
- sd->params.version.vcVersion,
- sd->params.version.vcRevision);
- PDEBUG(D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
- sd->params.pnpID.vendor, sd->params.pnpID.product,
- sd->params.pnpID.deviceRevision);
- PDEBUG(D_PROBE, "VP-Version: %d.%d %04x",
- sd->params.vpVersion.vpVersion,
- sd->params.vpVersion.vpRevision,
- sd->params.vpVersion.cameraHeadID);
+ gspca_dbg(gspca_dev, D_PROBE, "CPIA Version: %d.%02d (%d.%d)\n",
+ sd->params.version.firmwareVersion,
+ sd->params.version.firmwareRevision,
+ sd->params.version.vcVersion,
+ sd->params.version.vcRevision);
+ gspca_dbg(gspca_dev, D_PROBE, "CPIA PnP-ID: %04x:%04x:%04x",
+ sd->params.pnpID.vendor, sd->params.pnpID.product,
+ sd->params.pnpID.deviceRevision);
+ gspca_dbg(gspca_dev, D_PROBE, "VP-Version: %d.%d %04x",
+ sd->params.vpVersion.vpVersion,
+ sd->params.vpVersion.vpRevision,
+ sd->params.vpVersion.cameraHeadID);
return 0;
}
diff --git a/drivers/media/usb/gspca/dtcs033.c b/drivers/media/usb/gspca/dtcs033.c
index 96bfd4e0f0eb..cdf27cf0112a 100644
--- a/drivers/media/usb/gspca/dtcs033.c
+++ b/drivers/media/usb/gspca/dtcs033.c
@@ -71,18 +71,18 @@ static int reg_reqs(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_err < 0) {
- PERR("usb error request no: %d / %d\n",
- i, n_reqs);
+ gspca_err(gspca_dev, "usb error request no: %d / %d\n",
+ i, n_reqs);
} else if (preq->bRequestType & USB_DIR_IN) {
- PDEBUG(D_STREAM,
- "USB IN (%d) returned[%d] %02X %02X %02X %s",
- i,
- preq->wLength,
- gspca_dev->usb_buf[0],
- gspca_dev->usb_buf[1],
- gspca_dev->usb_buf[2],
- preq->wLength > 3 ? "...\n" : "\n");
+ gspca_dbg(gspca_dev, D_STREAM,
+ "USB IN (%d) returned[%d] %02X %02X %02X %s\n",
+ i,
+ preq->wLength,
+ gspca_dev->usb_buf[0],
+ gspca_dev->usb_buf[1],
+ gspca_dev->usb_buf[2],
+ preq->wLength > 3 ? "...\n" : "\n");
}
i++;
@@ -176,12 +176,12 @@ static void dtcs033_setexposure(struct gspca_dev *gspca_dev,
reg_rw(gspca_dev,
bRequestType, bRequest, wValue, wIndex, 0);
if (gspca_dev->usb_err < 0)
- PERR("usb error in setexposure(gain) sequence.\n");
+ gspca_err(gspca_dev, "usb error in setexposure(gain) sequence\n");
reg_rw(gspca_dev,
bRequestType, bRequest, (xtimeVal<<4), 0x6300, 0);
if (gspca_dev->usb_err < 0)
- PERR("usb error in setexposure(time) sequence.\n");
+ gspca_err(gspca_dev, "usb error in setexposure(time) sequence\n");
}
/* specific webcam descriptor */
@@ -239,8 +239,8 @@ static int dtcs033_init_controls(struct gspca_dev *gspca_dev)
V4L2_CID_GAIN,
14, 33, 1, 24);/* [dB] */
if (hdl->error) {
- PERR("Could not initialize controls: %d\n",
- hdl->error);
+ gspca_err(gspca_dev, "Could not initialize controls: %d\n",
+ hdl->error);
return hdl->error;
}
diff --git a/drivers/media/usb/gspca/etoms.c b/drivers/media/usb/gspca/etoms.c
index 8f84292936e9..48b28897051f 100644
--- a/drivers/media/usb/gspca/etoms.c
+++ b/drivers/media/usb/gspca/etoms.c
@@ -160,7 +160,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
struct usb_device *dev = gspca_dev->dev;
if (len > USB_BUF_SZ) {
- PERR("reg_r: buffer overflow\n");
+ gspca_err(gspca_dev, "reg_r: buffer overflow\n");
return;
}
@@ -170,8 +170,8 @@ static void reg_r(struct gspca_dev *gspca_dev,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0,
index, gspca_dev->usb_buf, len, 500);
- PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
- index, gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "reg read [%02x] -> %02x ..\n",
+ index, gspca_dev->usb_buf[0]);
}
static void reg_w_val(struct gspca_dev *gspca_dev,
@@ -200,7 +200,8 @@ static void reg_w(struct gspca_dev *gspca_dev,
pr_err("reg_w: buffer overflow\n");
return;
}
- PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
+ gspca_dbg(gspca_dev, D_USBO, "reg write [%02x] = %02x..\n",
+ index, *buffer);
memcpy(gspca_dev->usb_buf, buffer, len);
usb_control_msg(dev,
@@ -268,7 +269,7 @@ static int et_video(struct gspca_dev *gspca_dev,
: 0); /* stopvideo */
ret = Et_WaitStatus(gspca_dev);
if (ret != 0)
- PERR("timeout video on/off");
+ gspca_err(gspca_dev, "timeout video on/off\n");
return ret;
}
@@ -277,7 +278,7 @@ static void Et_init2(struct gspca_dev *gspca_dev)
__u8 value;
static const __u8 FormLine[] = { 0x84, 0x03, 0x14, 0xf4, 0x01, 0x05 };
- PDEBUG(D_STREAM, "Open Init2 ET");
+ gspca_dbg(gspca_dev, D_STREAM, "Open Init2 ET\n");
reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 0x2f);
reg_w_val(gspca_dev, ET_GPIO_OUT, 0x10);
reg_r(gspca_dev, ET_GPIO_IN, 1);
@@ -416,8 +417,6 @@ static void setcolors(struct gspca_dev *gspca_dev, s32 val)
i2c_w(gspca_dev, PAS106_REG13, &i2cflags, 1, 3);
i2c_w(gspca_dev, PAS106_REG9, I2cc, sizeof I2cc, 1);
}
-/* PDEBUG(D_CONF , "Etoms red %d blue %d green %d",
- I2cc[3], I2cc[0], green); */
}
static s32 getcolors(struct gspca_dev *gspca_dev)
@@ -451,7 +450,7 @@ static void Et_init1(struct gspca_dev *gspca_dev)
/* __u8 I2c0 [] = {0x0a, 0x12, 0x05, 0xfe, 0xfe, 0xc0, 0x01, 0x00};
* 1/60000 hmm ?? */
- PDEBUG(D_STREAM, "Open Init1 ET");
+ gspca_dbg(gspca_dev, D_STREAM, "Open Init1 ET\n\n");
reg_w_val(gspca_dev, ET_GPIO_DIR_CTRL, 7);
reg_r(gspca_dev, ET_GPIO_IN, 1);
reg_w_val(gspca_dev, ET_RESET_ALL, 1);
@@ -463,9 +462,9 @@ static void Et_init1(struct gspca_dev *gspca_dev)
value = ET_COMP_VAL1;
else
value = ET_COMP_VAL0;
- PDEBUG(D_STREAM, "Open mode %d Compression %d",
- gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv,
- value);
+ gspca_dbg(gspca_dev, D_STREAM, "Open mode %d Compression %d\n",
+ gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv,
+ value);
reg_w_val(gspca_dev, ET_COMP, value);
reg_w_val(gspca_dev, ET_MAXQt, 0x1d);
reg_w_val(gspca_dev, ET_MINQt, 0x02);
@@ -604,7 +603,8 @@ static __u8 Et_getgainG(struct gspca_dev *gspca_dev)
if (sd->sensor == SENSOR_PAS106) {
i2c_r(gspca_dev, PAS106_REG0e);
- PDEBUG(D_CONF, "Etoms gain G %d", gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_CONF, "Etoms gain G %d\n",
+ gspca_dev->usb_buf[0]);
return gspca_dev->usb_buf[0];
}
return 0x1f;
@@ -652,11 +652,11 @@ static void do_autogain(struct gspca_dev *gspca_dev)
b = ((b << 7) >> 10);
g = ((g << 9) + (g << 7) + (g << 5)) >> 10;
luma = LIMIT(r + g + b);
- PDEBUG(D_FRAM, "Etoms luma G %d", luma);
+ gspca_dbg(gspca_dev, D_FRAM, "Etoms luma G %d\n", luma);
if (luma < luma_mean - luma_delta || luma > luma_mean + luma_delta) {
Gbright += (luma_mean - luma) >> spring;
Gbright = BLIMIT(Gbright);
- PDEBUG(D_FRAM, "Etoms Gbright %d", Gbright);
+ gspca_dbg(gspca_dev, D_FRAM, "Etoms Gbright %d\n", Gbright);
Et_setgainG(gspca_dev, (__u8) Gbright);
}
}
@@ -673,10 +673,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
seqframe = data[0] & 0x3f;
len = (int) (((data[0] & 0xc0) << 2) | data[1]);
if (seqframe == 0x3f) {
- PDEBUG(D_FRAM,
- "header packet found datalength %d !!", len);
- PDEBUG(D_FRAM, "G %d R %d G %d B %d",
- data[2], data[3], data[4], data[5]);
+ gspca_dbg(gspca_dev, D_FRAM,
+ "header packet found datalength %d !!\n", len);
+ gspca_dbg(gspca_dev, D_FRAM, "G %d R %d G %d B %d",
+ data[2], data[3], data[4], data[5]);
data += 30;
/* don't change datalength as the chips provided it */
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
diff --git a/drivers/media/usb/gspca/finepix.c b/drivers/media/usb/gspca/finepix.c
index 7bb469aa61a7..1ef1239eb3db 100644
--- a/drivers/media/usb/gspca/finepix.c
+++ b/drivers/media/usb/gspca/finepix.c
@@ -89,7 +89,7 @@ static void dostream(struct work_struct *work)
int ret = 0;
int len;
- PDEBUG(D_STREAM, "dostream started");
+ gspca_dbg(gspca_dev, D_STREAM, "dostream started\n");
/* loop reading a frame */
again:
@@ -160,7 +160,7 @@ again:
}
out:
- PDEBUG(D_STREAM, "dostream stopped");
+ gspca_dbg(gspca_dev, D_STREAM, "dostream stopped\n");
}
/* this function is called at probe time */
diff --git a/drivers/media/usb/gspca/gl860/gl860.c b/drivers/media/usb/gspca/gl860/gl860.c
index cea8d7f51c3c..262200af76a3 100644
--- a/drivers/media/usb/gspca/gl860/gl860.c
+++ b/drivers/media/usb/gspca/gl860/gl860.c
@@ -582,7 +582,7 @@ int gl860_RTx(struct gspca_dev *gspca_dev,
pr_err("ctrl transfer failed %4d [p%02x r%d v%04x i%04x len%d]\n",
r, pref, req, val, index, len);
else if (len > 1 && r < len)
- PERR("short ctrl transfer %d/%d", r, len);
+ gspca_err(gspca_dev, "short ctrl transfer %d/%d\n", r, len);
msleep(1);
@@ -661,7 +661,7 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
msleep(56);
- PDEBUG(D_PROBE, "probing for sensor MI2020 or OVXXXX");
+ gspca_dbg(gspca_dev, D_PROBE, "probing for sensor MI2020 or OVXXXX\n");
nOV = 0;
for (ntry = 0; ntry < 4; ntry++) {
ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
@@ -671,14 +671,14 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
msleep(10);
ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
- PDEBUG(D_PROBE, "probe=0x%02x", probe);
+ gspca_dbg(gspca_dev, D_PROBE, "probe=0x%02x\n", probe);
if (probe == 0xff)
nOV++;
}
if (nOV) {
- PDEBUG(D_PROBE, "0xff -> OVXXXX");
- PDEBUG(D_PROBE, "probing for sensor OV2640 or OV9655");
+ gspca_dbg(gspca_dev, D_PROBE, "0xff -> OVXXXX\n");
+ gspca_dbg(gspca_dev, D_PROBE, "probing for sensor OV2640 or OV9655");
nb26 = nb96 = 0;
for (ntry = 0; ntry < 4; ntry++) {
@@ -694,22 +694,23 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
1, &probe);
if (probe == 0x26 || probe == 0x40) {
- PDEBUG(D_PROBE,
- "probe=0x%02x -> OV2640",
- probe);
+ gspca_dbg(gspca_dev, D_PROBE,
+ "probe=0x%02x -> OV2640\n",
+ probe);
sd->sensor = ID_OV2640;
nb26 += 4;
break;
}
if (probe == 0x96 || probe == 0x55) {
- PDEBUG(D_PROBE,
- "probe=0x%02x -> OV9655",
- probe);
+ gspca_dbg(gspca_dev, D_PROBE,
+ "probe=0x%02x -> OV9655\n",
+ probe);
sd->sensor = ID_OV9655;
nb96 += 4;
break;
}
- PDEBUG(D_PROBE, "probe=0x%02x", probe);
+ gspca_dbg(gspca_dev, D_PROBE, "probe=0x%02x\n",
+ probe);
if (probe == 0x00)
nb26++;
if (probe == 0xff)
@@ -719,21 +720,21 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
if (nb26 < 4 && nb96 < 4)
return -1;
} else {
- PDEBUG(D_PROBE, "Not any 0xff -> MI2020");
+ gspca_dbg(gspca_dev, D_PROBE, "Not any 0xff -> MI2020\n");
sd->sensor = ID_MI2020;
}
}
if (_MI1320_) {
- PDEBUG(D_PROBE, "05e3:f191 sensor MI1320 (1.3M)");
+ gspca_dbg(gspca_dev, D_PROBE, "05e3:f191 sensor MI1320 (1.3M)\n");
} else if (_MI2020_) {
- PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 (2.0M)");
+ gspca_dbg(gspca_dev, D_PROBE, "05e3:0503 sensor MI2020 (2.0M)\n");
} else if (_OV9655_) {
- PDEBUG(D_PROBE, "05e3:0503 sensor OV9655 (1.3M)");
+ gspca_dbg(gspca_dev, D_PROBE, "05e3:0503 sensor OV9655 (1.3M)\n");
} else if (_OV2640_) {
- PDEBUG(D_PROBE, "05e3:0503 sensor OV2640 (2.0M)");
+ gspca_dbg(gspca_dev, D_PROBE, "05e3:0503 sensor OV2640 (2.0M)\n");
} else {
- PDEBUG(D_PROBE, "***** Unknown sensor *****");
+ gspca_dbg(gspca_dev, D_PROBE, "***** Unknown sensor *****\n");
return -1;
}
diff --git a/drivers/media/usb/gspca/gspca.c b/drivers/media/usb/gspca/gspca.c
index b72d02e225fd..87e18d0c5766 100644
--- a/drivers/media/usb/gspca/gspca.c
+++ b/drivers/media/usb/gspca/gspca.c
@@ -63,18 +63,18 @@ static void PDEBUG_MODE(struct gspca_dev *gspca_dev, int debug, char *txt,
__u32 pixfmt, int w, int h)
{
if ((pixfmt >> 24) >= '0' && (pixfmt >> 24) <= 'z') {
- PDEBUG(debug, "%s %c%c%c%c %dx%d",
- txt,
- pixfmt & 0xff,
- (pixfmt >> 8) & 0xff,
- (pixfmt >> 16) & 0xff,
- pixfmt >> 24,
- w, h);
+ gspca_dbg(gspca_dev, debug, "%s %c%c%c%c %dx%d\n",
+ txt,
+ pixfmt & 0xff,
+ (pixfmt >> 8) & 0xff,
+ (pixfmt >> 16) & 0xff,
+ pixfmt >> 24,
+ w, h);
} else {
- PDEBUG(debug, "%s 0x%08x %dx%d",
- txt,
- pixfmt,
- w, h);
+ gspca_dbg(gspca_dev, debug, "%s 0x%08x %dx%d\n",
+ txt,
+ pixfmt,
+ w, h);
}
}
@@ -122,7 +122,7 @@ static void int_irq(struct urb *urb)
case 0:
if (gspca_dev->sd_desc->int_pkt_scan(gspca_dev,
urb->transfer_buffer, urb->actual_length) < 0) {
- PERR("Unknown packet received");
+ gspca_err(gspca_dev, "Unknown packet received\n");
}
break;
@@ -136,7 +136,8 @@ static void int_irq(struct urb *urb)
break;
default:
- PERR("URB error %i, resubmitting", urb->status);
+ gspca_err(gspca_dev, "URB error %i, resubmitting\n",
+ urb->status);
urb->status = 0;
ret = 0;
}
@@ -197,8 +198,8 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
buffer_len = le16_to_cpu(ep->wMaxPacketSize);
interval = ep->bInterval;
- PDEBUG(D_CONF, "found int in endpoint: 0x%x, buffer_len=%u, interval=%u",
- ep->bEndpointAddress, buffer_len, interval);
+ gspca_dbg(gspca_dev, D_CONF, "found int in endpoint: 0x%x, buffer_len=%u, interval=%u\n",
+ ep->bEndpointAddress, buffer_len, interval);
dev = gspca_dev->dev;
@@ -221,7 +222,8 @@ static int alloc_and_submit_int_urb(struct gspca_dev *gspca_dev,
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret < 0) {
- PERR("submit int URB failed with error %i", ret);
+ gspca_err(gspca_dev, "submit int URB failed with error %i\n",
+ ret);
goto error_submit;
}
gspca_dev->int_urb = urb;
@@ -307,7 +309,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
if (gspca_dev->frozen)
return;
#endif
- PERR("urb status: %d", urb->status);
+ gspca_err(gspca_dev, "urb status: %d\n", urb->status);
urb->status = 0;
goto resubmit;
}
@@ -330,8 +332,8 @@ static void fill_frame(struct gspca_dev *gspca_dev,
}
/* let the packet be analyzed by the subdriver */
- PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
- i, urb->iso_frame_desc[i].offset, len);
+ gspca_dbg(gspca_dev, D_PACK, "packet [%d] o:%d l:%d\n",
+ i, urb->iso_frame_desc[i].offset, len);
data = (u8 *) urb->transfer_buffer
+ urb->iso_frame_desc[i].offset;
pkt_scan(gspca_dev, data, len);
@@ -353,7 +355,7 @@ static void isoc_irq(struct urb *urb)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
- PDEBUG(D_PACK, "isoc irq");
+ gspca_dbg(gspca_dev, D_PACK, "isoc irq\n");
if (!gspca_dev->streaming)
return;
fill_frame(gspca_dev, urb);
@@ -367,7 +369,7 @@ static void bulk_irq(struct urb *urb)
struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
int st;
- PDEBUG(D_PACK, "bulk irq");
+ gspca_dbg(gspca_dev, D_PACK, "bulk irq\n");
if (!gspca_dev->streaming)
return;
switch (urb->status) {
@@ -380,12 +382,12 @@ static void bulk_irq(struct urb *urb)
if (gspca_dev->frozen)
return;
#endif
- PERR("urb status: %d", urb->status);
+ gspca_err(gspca_dev, "urb status: %d\n", urb->status);
urb->status = 0;
goto resubmit;
}
- PDEBUG(D_PACK, "packet l:%d", urb->actual_length);
+ gspca_dbg(gspca_dev, D_PACK, "packet l:%d\n", urb->actual_length);
gspca_dev->sd_desc->pkt_scan(gspca_dev,
urb->transfer_buffer,
urb->actual_length);
@@ -418,7 +420,7 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
struct gspca_frame *frame;
int i, j;
- PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);
+ gspca_dbg(gspca_dev, D_PACK, "add t:%d l:%d\n", packet_type, len);
if (packet_type == FIRST_PACKET) {
i = atomic_read(&gspca_dev->fr_i);
@@ -452,9 +454,9 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
/* append the packet to the frame buffer */
if (len > 0) {
if (gspca_dev->image_len + len > gspca_dev->frsz) {
- PERR("frame overflow %d > %d",
- gspca_dev->image_len + len,
- gspca_dev->frsz);
+ gspca_err(gspca_dev, "frame overflow %d > %d\n",
+ gspca_dev->image_len + len,
+ gspca_dev->frsz);
packet_type = DISCARD_PACKET;
} else {
/* !! image is NULL only when last pkt is LAST or DISCARD
@@ -484,8 +486,8 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
i = (i + 1) % GSPCA_MAX_FRAMES;
atomic_set(&gspca_dev->fr_i, i);
wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
- PDEBUG(D_FRAM, "frame complete len:%d",
- frame->v4l2_buf.bytesused);
+ gspca_dbg(gspca_dev, D_FRAM, "frame complete len:%d\n",
+ frame->v4l2_buf.bytesused);
gspca_dev->image = NULL;
gspca_dev->image_len = 0;
}
@@ -500,7 +502,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file,
int i;
frsz = gspca_dev->pixfmt.sizeimage;
- PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
+ gspca_dbg(gspca_dev, D_STREAM, "frame alloc frsz: %d\n", frsz);
frsz = PAGE_ALIGN(frsz);
if (count >= GSPCA_MAX_FRAMES)
count = GSPCA_MAX_FRAMES - 1;
@@ -535,7 +537,7 @@ static void frame_free(struct gspca_dev *gspca_dev)
{
int i;
- PDEBUG(D_STREAM, "frame free");
+ gspca_dbg(gspca_dev, D_STREAM, "frame free\n");
if (gspca_dev->frbuf != NULL) {
vfree(gspca_dev->frbuf);
gspca_dev->frbuf = NULL;
@@ -553,7 +555,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
struct urb *urb;
unsigned int i;
- PDEBUG(D_STREAM, "kill transfer");
+ gspca_dbg(gspca_dev, D_STREAM, "kill transfer\n");
for (i = 0; i < MAX_NURBS; i++) {
urb = gspca_dev->urb[i];
if (urb == NULL)
@@ -594,7 +596,7 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
gspca_input_create_urb(gspca_dev);
if (gspca_dev->sd_desc->stop0)
gspca_dev->sd_desc->stop0(gspca_dev);
- PDEBUG(D_STREAM, "stream off OK");
+ gspca_dbg(gspca_dev, D_STREAM, "stream off OK\n");
}
/*
@@ -653,7 +655,7 @@ static u32 which_bandwidth(struct gspca_dev *gspca_dev)
bandwidth *= 30; /* 30 fps */
}
- PDEBUG(D_STREAM, "min bandwidth: %d", bandwidth);
+ gspca_dbg(gspca_dev, D_STREAM, "min bandwidth: %d\n", bandwidth);
return bandwidth;
}
@@ -713,8 +715,8 @@ static int build_isoc_ep_tb(struct gspca_dev *gspca_dev,
}
if (!found)
break;
- PDEBUG(D_STREAM, "alt %d bandwidth %d",
- ep_tb->alt, ep_tb->bandwidth);
+ gspca_dbg(gspca_dev, D_STREAM, "alt %d bandwidth %d\n",
+ ep_tb->alt, ep_tb->bandwidth);
last_bw = ep_tb->bandwidth;
i++;
ep_tb++;
@@ -732,7 +734,7 @@ static int build_isoc_ep_tb(struct gspca_dev *gspca_dev,
gspca_dev->dev->speed == USB_SPEED_FULL &&
last_bw >= 1000000 &&
i > 1) {
- PDEBUG(D_STREAM, "dev has usb audio, skipping highest alt");
+ gspca_dbg(gspca_dev, D_STREAM, "dev has usb audio, skipping highest alt\n");
i--;
ep_tb--;
}
@@ -772,16 +774,16 @@ static int create_urbs(struct gspca_dev *gspca_dev,
if (npkt == 0)
npkt = 32; /* default value */
bsize = psize * npkt;
- PDEBUG(D_STREAM,
- "isoc %d pkts size %d = bsize:%d",
- npkt, psize, bsize);
+ gspca_dbg(gspca_dev, D_STREAM,
+ "isoc %d pkts size %d = bsize:%d\n",
+ npkt, psize, bsize);
nurbs = DEF_NURBS;
} else { /* bulk */
npkt = 0;
bsize = gspca_dev->cam.bulk_size;
if (bsize == 0)
bsize = psize;
- PDEBUG(D_STREAM, "bulk bsize:%d", bsize);
+ gspca_dbg(gspca_dev, D_STREAM, "bulk bsize:%d\n", bsize);
if (gspca_dev->cam.bulk_nurbs != 0)
nurbs = gspca_dev->cam.bulk_nurbs;
else
@@ -900,7 +902,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
}
}
if (!gspca_dev->cam.no_urb_create) {
- PDEBUG(D_STREAM, "init transfer alt %d", alt);
+ gspca_dbg(gspca_dev, D_STREAM, "init transfer alt %d\n",
+ alt);
ret = create_urbs(gspca_dev,
alt_xfer(&intf->altsetting[alt], xfer,
gspca_dev->xfer_ep));
@@ -952,7 +955,8 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
/* the bandwidth is not wide enough
* negotiate or try a lower alternate setting */
retry:
- PERR("alt %d - bandwidth not wide enough, trying again", alt);
+ gspca_err(gspca_dev, "alt %d - bandwidth not wide enough, trying again\n",
+ alt);
msleep(20); /* wait for kill complete */
if (gspca_dev->sd_desc->isoc_nego) {
ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);
@@ -1282,7 +1286,7 @@ static int dev_open(struct file *file)
struct gspca_dev *gspca_dev = video_drvdata(file);
int ret;
- PDEBUG(D_STREAM, "[%s] open", current->comm);
+ gspca_dbg(gspca_dev, D_STREAM, "[%s] open\n", current->comm);
/* protect the subdriver against rmmod */
if (!try_module_get(gspca_dev->module))
@@ -1298,7 +1302,7 @@ static int dev_close(struct file *file)
{
struct gspca_dev *gspca_dev = video_drvdata(file);
- PDEBUG(D_STREAM, "[%s] close", current->comm);
+ gspca_dbg(gspca_dev, D_STREAM, "[%s] close\n", current->comm);
/* Needed for gspca_stream_off, always lock before queue_lock! */
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
@@ -1319,7 +1323,7 @@ static int dev_close(struct file *file)
mutex_unlock(&gspca_dev->queue_lock);
mutex_unlock(&gspca_dev->usb_lock);
- PDEBUG(D_STREAM, "close done");
+ gspca_dbg(gspca_dev, D_STREAM, "close done\n");
return v4l2_fh_release(file);
}
@@ -1440,7 +1444,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
}
out:
mutex_unlock(&gspca_dev->queue_lock);
- PDEBUG(D_STREAM, "reqbufs st:%d c:%d", ret, rb->count);
+ gspca_dbg(gspca_dev, D_STREAM, "reqbufs st:%d c:%d\n", ret, rb->count);
return ret;
}
@@ -1598,7 +1602,8 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
start = vma->vm_start;
size = vma->vm_end - vma->vm_start;
- PDEBUG(D_STREAM, "mmap start:%08x size:%d", (int) start, (int) size);
+ gspca_dbg(gspca_dev, D_STREAM, "mmap start:%08x size:%d\n",
+ (int) start, (int)size);
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
@@ -1610,7 +1615,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
frame = NULL;
for (i = 0; i < gspca_dev->nframes; ++i) {
if (gspca_dev->frame[i].v4l2_buf.memory != V4L2_MEMORY_MMAP) {
- PDEBUG(D_STREAM, "mmap bad memory type");
+ gspca_dbg(gspca_dev, D_STREAM, "mmap bad memory type\n");
break;
}
if ((gspca_dev->frame[i].v4l2_buf.m.offset >> PAGE_SHIFT)
@@ -1620,12 +1625,12 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
}
}
if (frame == NULL) {
- PDEBUG(D_STREAM, "mmap no frame buffer found");
+ gspca_dbg(gspca_dev, D_STREAM, "mmap no frame buffer found\n");
ret = -EINVAL;
goto out;
}
if (size != frame->v4l2_buf.length) {
- PDEBUG(D_STREAM, "mmap bad size");
+ gspca_dbg(gspca_dev, D_STREAM, "mmap bad size\n");
ret = -EINVAL;
goto out;
}
@@ -1693,7 +1698,7 @@ static int vidioc_dqbuf(struct file *file, void *priv,
struct gspca_frame *frame;
int i, j, ret;
- PDEBUG(D_FRAM, "dqbuf");
+ gspca_dbg(gspca_dev, D_FRAM, "dqbuf\n");
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
@@ -1731,14 +1736,14 @@ static int vidioc_dqbuf(struct file *file, void *priv,
frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
- PDEBUG(D_FRAM, "dqbuf %d", j);
+ gspca_dbg(gspca_dev, D_FRAM, "dqbuf %d\n", j);
ret = 0;
if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
if (copy_to_user((__u8 __user *) frame->v4l2_buf.m.userptr,
frame->data,
frame->v4l2_buf.bytesused)) {
- PERR("dqbuf cp to user failed");
+ gspca_err(gspca_dev, "dqbuf cp to user failed\n");
ret = -EFAULT;
}
}
@@ -1769,27 +1774,27 @@ static int vidioc_qbuf(struct file *file, void *priv,
struct gspca_frame *frame;
int i, index, ret;
- PDEBUG(D_FRAM, "qbuf %d", v4l2_buf->index);
+ gspca_dbg(gspca_dev, D_FRAM, "qbuf %d\n", v4l2_buf->index);
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
index = v4l2_buf->index;
if ((unsigned) index >= gspca_dev->nframes) {
- PDEBUG(D_FRAM,
- "qbuf idx %d >= %d", index, gspca_dev->nframes);
+ gspca_dbg(gspca_dev, D_FRAM,
+ "qbuf idx %d >= %d\n", index, gspca_dev->nframes);
ret = -EINVAL;
goto out;
}
if (v4l2_buf->memory != gspca_dev->memory) {
- PDEBUG(D_FRAM, "qbuf bad memory type");
+ gspca_dbg(gspca_dev, D_FRAM, "qbuf bad memory type\n");
ret = -EINVAL;
goto out;
}
frame = &gspca_dev->frame[index];
if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) {
- PDEBUG(D_FRAM, "qbuf bad state");
+ gspca_dbg(gspca_dev, D_FRAM, "qbuf bad state\n");
ret = -EINVAL;
goto out;
}
@@ -1823,7 +1828,7 @@ static int read_alloc(struct gspca_dev *gspca_dev,
struct v4l2_buffer v4l2_buf;
int i, ret;
- PDEBUG(D_STREAM, "read alloc");
+ gspca_dbg(gspca_dev, D_STREAM, "read alloc\n");
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
@@ -1837,7 +1842,8 @@ static int read_alloc(struct gspca_dev *gspca_dev,
rb.memory = GSPCA_MEMORY_READ;
ret = vidioc_reqbufs(file, gspca_dev, &rb);
if (ret != 0) {
- PDEBUG(D_STREAM, "read reqbuf err %d", ret);
+ gspca_dbg(gspca_dev, D_STREAM, "read reqbuf err %d\n",
+ ret);
goto out;
}
memset(&v4l2_buf, 0, sizeof v4l2_buf);
@@ -1847,7 +1853,8 @@ static int read_alloc(struct gspca_dev *gspca_dev,
v4l2_buf.index = i;
ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
if (ret != 0) {
- PDEBUG(D_STREAM, "read qbuf err: %d", ret);
+ gspca_dbg(gspca_dev, D_STREAM, "read qbuf err: %d\n",
+ ret);
goto out;
}
}
@@ -1856,7 +1863,7 @@ static int read_alloc(struct gspca_dev *gspca_dev,
/* start streaming */
ret = vidioc_streamon(file, gspca_dev, V4L2_BUF_TYPE_VIDEO_CAPTURE);
if (ret != 0)
- PDEBUG(D_STREAM, "read streamon err %d", ret);
+ gspca_dbg(gspca_dev, D_STREAM, "read streamon err %d\n", ret);
out:
mutex_unlock(&gspca_dev->usb_lock);
return ret;
@@ -1868,7 +1875,7 @@ static __poll_t dev_poll(struct file *file, poll_table *wait)
__poll_t req_events = poll_requested_events(wait);
__poll_t ret = 0;
- PDEBUG(D_FRAM, "poll");
+ gspca_dbg(gspca_dev, D_FRAM, "poll\n");
if (req_events & POLLPRI)
ret |= v4l2_ctrl_poll(file, wait);
@@ -1910,7 +1917,7 @@ static ssize_t dev_read(struct file *file, char __user *data,
struct timeval timestamp;
int n, ret, ret2;
- PDEBUG(D_FRAM, "read (%zd)", count);
+ gspca_dbg(gspca_dev, D_FRAM, "read (%zd)\n", count);
if (gspca_dev->memory == GSPCA_MEMORY_NO) { /* first time ? */
ret = read_alloc(gspca_dev, file);
if (ret != 0)
@@ -1927,7 +1934,8 @@ static ssize_t dev_read(struct file *file, char __user *data,
v4l2_buf.memory = GSPCA_MEMORY_READ;
ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf);
if (ret != 0) {
- PDEBUG(D_STREAM, "read dqbuf err %d", ret);
+ gspca_dbg(gspca_dev, D_STREAM, "read dqbuf err %d\n",
+ ret);
return ret;
}
@@ -1940,7 +1948,8 @@ static ssize_t dev_read(struct file *file, char __user *data,
break;
ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);
if (ret != 0) {
- PDEBUG(D_STREAM, "read qbuf err %d", ret);
+ gspca_dbg(gspca_dev, D_STREAM, "read qbuf err %d\n",
+ ret);
return ret;
}
}
@@ -1950,7 +1959,8 @@ static ssize_t dev_read(struct file *file, char __user *data,
count = frame->v4l2_buf.bytesused;
ret = copy_to_user(data, frame->data, count);
if (ret != 0) {
- PERR("read cp to user lack %d / %zd", ret, count);
+ gspca_err(gspca_dev, "read cp to user lack %d / %zd\n",
+ ret, count);
ret = -EFAULT;
goto out;
}
@@ -2128,7 +2138,8 @@ int gspca_dev_probe2(struct usb_interface *intf,
}
usb_set_intfdata(intf, gspca_dev);
- PDEBUG(D_PROBE, "%s created", video_device_node_name(&gspca_dev->vdev));
+ gspca_dbg(gspca_dev, D_PROBE, "%s created\n",
+ video_device_node_name(&gspca_dev->vdev));
gspca_input_create_urb(gspca_dev);
@@ -2183,8 +2194,8 @@ void gspca_disconnect(struct usb_interface *intf)
struct input_dev *input_dev;
#endif
- PDEBUG(D_PROBE, "%s disconnect",
- video_device_node_name(&gspca_dev->vdev));
+ gspca_dbg(gspca_dev, D_PROBE, "%s disconnect\n",
+ video_device_node_name(&gspca_dev->vdev));
mutex_lock(&gspca_dev->usb_lock);
diff --git a/drivers/media/usb/gspca/gspca.h b/drivers/media/usb/gspca/gspca.h
index 9e0cf711642b..249cb38a542f 100644
--- a/drivers/media/usb/gspca/gspca.h
+++ b/drivers/media/usb/gspca/gspca.h
@@ -26,11 +26,12 @@
extern int gspca_debug;
-#define PDEBUG(level, fmt, ...) \
- v4l2_dbg(level, gspca_debug, &gspca_dev->v4l2_dev, fmt, ##__VA_ARGS__)
+#define gspca_dbg(gspca_dev, level, fmt, ...) \
+ v4l2_dbg(level, gspca_debug, &(gspca_dev)->v4l2_dev, \
+ fmt, ##__VA_ARGS__)
-#define PERR(fmt, ...) \
- v4l2_err(&gspca_dev->v4l2_dev, fmt, ##__VA_ARGS__)
+#define gspca_err(gspca_dev, fmt, ...) \
+ v4l2_err(&(gspca_dev)->v4l2_dev, fmt, ##__VA_ARGS__)
#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
/* image transfers */
diff --git a/drivers/media/usb/gspca/jeilinj.c b/drivers/media/usb/gspca/jeilinj.c
index 34e043b7d1bc..86d0a0a45631 100644
--- a/drivers/media/usb/gspca/jeilinj.c
+++ b/drivers/media/usb/gspca/jeilinj.c
@@ -262,7 +262,7 @@ static int jlj_start(struct gspca_dev *gspca_dev)
msleep(2);
setfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->freq));
if (gspca_dev->usb_err < 0)
- PERR("Start streaming command failed");
+ gspca_err(gspca_dev, "Start streaming command failed\n");
return gspca_dev->usb_err;
}
@@ -273,17 +273,18 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
int packet_type;
u32 header_marker;
- PDEBUG(D_STREAM, "Got %d bytes out of %d for Block 0",
- len, JEILINJ_MAX_TRANSFER);
+ gspca_dbg(gspca_dev, D_STREAM, "Got %d bytes out of %d for Block 0\n",
+ len, JEILINJ_MAX_TRANSFER);
if (len != JEILINJ_MAX_TRANSFER) {
- PDEBUG(D_PACK, "bad length");
+ gspca_dbg(gspca_dev, D_PACK, "bad length\n");
goto discard;
}
/* check if it's start of frame */
header_marker = ((u32 *)data)[0];
if (header_marker == FRAME_START) {
sd->blocks_left = data[0x0a] - 1;
- PDEBUG(D_STREAM, "blocks_left = 0x%x", sd->blocks_left);
+ gspca_dbg(gspca_dev, D_STREAM, "blocks_left = 0x%x\n",
+ sd->blocks_left);
/* Start a new frame, and add the JPEG header, first thing */
gspca_frame_add(gspca_dev, FIRST_PACKET,
sd->jpeg_hdr, JPEG_HDR_SZ);
@@ -292,8 +293,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data + FRAME_HEADER_LEN,
JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
} else if (sd->blocks_left > 0) {
- PDEBUG(D_STREAM, "%d blocks remaining for frame",
- sd->blocks_left);
+ gspca_dbg(gspca_dev, D_STREAM, "%d blocks remaining for frame\n",
+ sd->blocks_left);
sd->blocks_left -= 1;
if (sd->blocks_left == 0)
packet_type = LAST_PACKET;
@@ -378,8 +379,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
gspca_dev->pixfmt.width,
0x21); /* JPEG 422 */
jpeg_set_qual(dev->jpeg_hdr, dev->quality);
- PDEBUG(D_STREAM, "Start streaming at %dx%d",
- gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
+ gspca_dbg(gspca_dev, D_STREAM, "Start streaming at %dx%d\n",
+ gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
jlj_start(gspca_dev);
return gspca_dev->usb_err;
}
diff --git a/drivers/media/usb/gspca/jl2005bcd.c b/drivers/media/usb/gspca/jl2005bcd.c
index 17c7a953564c..d668589598d6 100644
--- a/drivers/media/usb/gspca/jl2005bcd.c
+++ b/drivers/media/usb/gspca/jl2005bcd.c
@@ -149,7 +149,8 @@ static int jl2005c_start_new_frame(struct gspca_dev *gspca_dev)
return retval;
i++;
}
- PDEBUG(D_FRAM, "frame_brightness is 0x%02x", gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_FRAM, "frame_brightness is 0x%02x\n",
+ gspca_dev->usb_buf[0]);
return retval;
}
@@ -176,10 +177,11 @@ static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev)
int retval = -1;
unsigned char regs_to_read[] = {0x57, 0x02, 0x03, 0x5d, 0x5e, 0x5f};
- PDEBUG(D_PROBE, "Running jl2005c_get_firmware_id");
+ gspca_dbg(gspca_dev, D_PROBE, "Running jl2005c_get_firmware_id\n");
/* Read the first ID byte once for warmup */
retval = jl2005c_read_reg(gspca_dev, regs_to_read[0]);
- PDEBUG(D_PROBE, "response is %02x", gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_PROBE, "response is %02x\n",
+ gspca_dev->usb_buf[0]);
if (retval < 0)
return retval;
/* Now actually get the ID string */
@@ -189,13 +191,13 @@ static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev)
return retval;
sd->firmware_id[i] = gspca_dev->usb_buf[0];
}
- PDEBUG(D_PROBE, "firmware ID is %02x%02x%02x%02x%02x%02x",
- sd->firmware_id[0],
- sd->firmware_id[1],
- sd->firmware_id[2],
- sd->firmware_id[3],
- sd->firmware_id[4],
- sd->firmware_id[5]);
+ gspca_dbg(gspca_dev, D_PROBE, "firmware ID is %02x%02x%02x%02x%02x%02x\n",
+ sd->firmware_id[0],
+ sd->firmware_id[1],
+ sd->firmware_id[2],
+ sd->firmware_id[3],
+ sd->firmware_id[4],
+ sd->firmware_id[5]);
return 0;
}
@@ -341,9 +343,9 @@ static void jl2005c_dostream(struct work_struct *work)
usb_rcvbulkpipe(gspca_dev->dev, 0x82),
buffer, JL2005C_MAX_TRANSFER, &act_len,
JL2005C_DATA_TIMEOUT);
- PDEBUG(D_PACK,
- "Got %d bytes out of %d for header",
- act_len, JL2005C_MAX_TRANSFER);
+ gspca_dbg(gspca_dev, D_PACK,
+ "Got %d bytes out of %d for header\n",
+ act_len, JL2005C_MAX_TRANSFER);
if (ret < 0 || act_len < JL2005C_MAX_TRANSFER)
goto quit_stream;
/* Check whether we actually got the first blodk */
@@ -354,7 +356,8 @@ static void jl2005c_dostream(struct work_struct *work)
/* total size to fetch is byte 7, times blocksize
* of which we already got act_len */
bytes_left = buffer[0x07] * dev->block_size - act_len;
- PDEBUG(D_PACK, "bytes_left = 0x%x", bytes_left);
+ gspca_dbg(gspca_dev, D_PACK, "bytes_left = 0x%x\n",
+ bytes_left);
/* We keep the header. It has other information, too.*/
packet_type = FIRST_PACKET;
gspca_frame_add(gspca_dev, packet_type,
@@ -370,9 +373,9 @@ static void jl2005c_dostream(struct work_struct *work)
JL2005C_DATA_TIMEOUT);
if (ret < 0 || act_len < data_len)
goto quit_stream;
- PDEBUG(D_PACK,
- "Got %d bytes out of %d for frame",
- data_len, bytes_left);
+ gspca_dbg(gspca_dev, D_PACK,
+ "Got %d bytes out of %d for frame\n",
+ data_len, bytes_left);
bytes_left -= data_len;
if (bytes_left == 0) {
packet_type = LAST_PACKET;
@@ -449,19 +452,19 @@ static int sd_start(struct gspca_dev *gspca_dev)
switch (gspca_dev->pixfmt.width) {
case 640:
- PDEBUG(D_STREAM, "Start streaming at vga resolution");
+ gspca_dbg(gspca_dev, D_STREAM, "Start streaming at vga resolution\n");
jl2005c_stream_start_vga_lg(gspca_dev);
break;
case 320:
- PDEBUG(D_STREAM, "Start streaming at qvga resolution");
+ gspca_dbg(gspca_dev, D_STREAM, "Start streaming at qvga resolution\n");
jl2005c_stream_start_vga_small(gspca_dev);
break;
case 352:
- PDEBUG(D_STREAM, "Start streaming at cif resolution");
+ gspca_dbg(gspca_dev, D_STREAM, "Start streaming at cif resolution\n");
jl2005c_stream_start_cif_lg(gspca_dev);
break;
case 176:
- PDEBUG(D_STREAM, "Start streaming at qcif resolution");
+ gspca_dbg(gspca_dev, D_STREAM, "Start streaming at qcif resolution\n");
jl2005c_stream_start_cif_small(gspca_dev);
break;
default:
diff --git a/drivers/media/usb/gspca/kinect.c b/drivers/media/usb/gspca/kinect.c
index 2f28b38c5479..0cfdf8a1e19d 100644
--- a/drivers/media/usb/gspca/kinect.c
+++ b/drivers/media/usb/gspca/kinect.c
@@ -151,8 +151,9 @@ static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf,
memcpy(obuf+sizeof(*chdr), cmdbuf, cmd_len);
res = kinect_write(udev, obuf, cmd_len + sizeof(*chdr));
- PDEBUG(D_USBO, "Control cmd=%04x tag=%04x len=%04x: %d", cmd,
- sd->cam_tag, cmd_len, res);
+ gspca_dbg(gspca_dev, D_USBO, "Control cmd=%04x tag=%04x len=%04x: %d\n",
+ cmd,
+ sd->cam_tag, cmd_len, res);
if (res < 0) {
pr_err("send_cmd: Output control transfer failed (%d)\n", res);
return res;
@@ -161,7 +162,7 @@ static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf,
do {
actual_len = kinect_read(udev, ibuf, 0x200);
} while (actual_len == 0);
- PDEBUG(D_USBO, "Control reply: %d", actual_len);
+ gspca_dbg(gspca_dev, D_USBO, "Control reply: %d\n", actual_len);
if (actual_len < sizeof(*rhdr)) {
pr_err("send_cmd: Input control transfer failed (%d)\n",
actual_len);
@@ -213,7 +214,7 @@ static int write_register(struct gspca_dev *gspca_dev, uint16_t reg,
cmd[0] = cpu_to_le16(reg);
cmd[1] = cpu_to_le16(data);
- PDEBUG(D_USBO, "Write Reg 0x%04x <= 0x%02x", reg, data);
+ gspca_dbg(gspca_dev, D_USBO, "Write Reg 0x%04x <= 0x%02x\n", reg, data);
res = send_cmd(gspca_dev, 0x03, cmd, 4, reply, 4);
if (res < 0)
return res;
@@ -274,7 +275,7 @@ static int sd_config_depth(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- PDEBUG(D_PROBE, "Kinect Camera device.");
+ gspca_dbg(gspca_dev, D_PROBE, "Kinect Camera device.\n");
return 0;
}
diff --git a/drivers/media/usb/gspca/konica.c b/drivers/media/usb/gspca/konica.c
index 31b2117e8f1d..989ae997f66d 100644
--- a/drivers/media/usb/gspca/konica.c
+++ b/drivers/media/usb/gspca/konica.c
@@ -263,7 +263,7 @@ static void sd_isoc_irq(struct urb *urb)
u8 *data;
int i, st;
- PDEBUG(D_PACK, "sd isoc irq");
+ gspca_dbg(gspca_dev, D_PACK, "sd isoc irq\n");
if (!gspca_dev->streaming)
return;
@@ -274,7 +274,7 @@ static void sd_isoc_irq(struct urb *urb)
if (gspca_dev->frozen)
return;
#endif
- PERR("urb status: %d", urb->status);
+ gspca_err(gspca_dev, "urb status: %d\n", urb->status);
st = usb_submit_urb(urb, GFP_ATOMIC);
if (st < 0)
pr_err("resubmit urb error %d\n", st);
@@ -292,30 +292,31 @@ static void sd_isoc_irq(struct urb *urb)
sd->last_data_urb = NULL;
if (!data_urb || data_urb->start_frame != status_urb->start_frame) {
- PERR("lost sync on frames");
+ gspca_err(gspca_dev, "lost sync on frames\n");
goto resubmit;
}
if (data_urb->number_of_packets != status_urb->number_of_packets) {
- PERR("no packets does not match, data: %d, status: %d",
- data_urb->number_of_packets,
- status_urb->number_of_packets);
+ gspca_err(gspca_dev, "no packets does not match, data: %d, status: %d\n",
+ data_urb->number_of_packets,
+ status_urb->number_of_packets);
goto resubmit;
}
for (i = 0; i < status_urb->number_of_packets; i++) {
if (data_urb->iso_frame_desc[i].status ||
status_urb->iso_frame_desc[i].status) {
- PERR("pkt %d data-status %d, status-status %d", i,
- data_urb->iso_frame_desc[i].status,
- status_urb->iso_frame_desc[i].status);
+ gspca_err(gspca_dev, "pkt %d data-status %d, status-status %d\n",
+ i,
+ data_urb->iso_frame_desc[i].status,
+ status_urb->iso_frame_desc[i].status);
gspca_dev->last_packet_type = DISCARD_PACKET;
continue;
}
if (status_urb->iso_frame_desc[i].actual_length != 1) {
- PERR("bad status packet length %d",
- status_urb->iso_frame_desc[i].actual_length);
+ gspca_err(gspca_dev, "bad status packet length %d\n",
+ status_urb->iso_frame_desc[i].actual_length);
gspca_dev->last_packet_type = DISCARD_PACKET;
continue;
}
@@ -360,11 +361,12 @@ resubmit:
if (data_urb) {
st = usb_submit_urb(data_urb, GFP_ATOMIC);
if (st < 0)
- PERR("usb_submit_urb(data_urb) ret %d", st);
+ gspca_err(gspca_dev, "usb_submit_urb(data_urb) ret %d\n",
+ st);
}
st = usb_submit_urb(status_urb, GFP_ATOMIC);
if (st < 0)
- PERR("usb_submit_urb(status_urb) ret %d\n", st);
+ gspca_err(gspca_dev, "usb_submit_urb(status_urb) ret %d\n", st);
}
static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
diff --git a/drivers/media/usb/gspca/m5602/m5602_core.c b/drivers/media/usb/gspca/m5602/m5602_core.c
index f1dcd9021983..b83ec4285a0b 100644
--- a/drivers/media/usb/gspca/m5602/m5602_core.c
+++ b/drivers/media/usb/gspca/m5602/m5602_core.c
@@ -66,8 +66,8 @@ int m5602_read_bridge(struct sd *sd, const u8 address, u8 *i2c_data)
1, M5602_URB_MSG_TIMEOUT);
*i2c_data = buf[0];
- PDEBUG(D_CONF, "Reading bridge register 0x%x containing 0x%x",
- address, *i2c_data);
+ gspca_dbg(gspca_dev, D_CONF, "Reading bridge register 0x%x containing 0x%x\n",
+ address, *i2c_data);
/* usb_control_msg(...) returns the number of bytes sent upon success,
mask that and return zero instead*/
@@ -82,8 +82,8 @@ int m5602_write_bridge(struct sd *sd, const u8 address, const u8 i2c_data)
struct usb_device *udev = sd->gspca_dev.dev;
__u8 *buf = sd->gspca_dev.usb_buf;
- PDEBUG(D_CONF, "Writing bridge register 0x%x with 0x%x",
- address, i2c_data);
+ gspca_dbg(gspca_dev, D_CONF, "Writing bridge register 0x%x with 0x%x\n",
+ address, i2c_data);
memcpy(buf, bridge_urb_skeleton,
sizeof(bridge_urb_skeleton));
@@ -154,8 +154,8 @@ int m5602_read_sensor(struct sd *sd, const u8 address,
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(D_CONF, "Reading sensor register 0x%x containing 0x%x ",
- address, *i2c_data);
+ gspca_dbg(gspca_dev, D_CONF, "Reading sensor register 0x%x containing 0x%x\n",
+ address, *i2c_data);
}
return err;
}
@@ -187,8 +187,8 @@ int m5602_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
- address, i2c_data[i]);
+ gspca_dbg(gspca_dev, D_CONF, "Writing sensor register 0x%x with 0x%x\n",
+ address, i2c_data[i]);
}
/* Copy the tailer */
@@ -264,7 +264,7 @@ static int m5602_init(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int err;
- PDEBUG(D_CONF, "Initializing ALi m5602 webcam");
+ gspca_dbg(gspca_dev, D_CONF, "Initializing ALi m5602 webcam\n");
/* Run the init sequence */
err = sd->sensor->init(sd);
@@ -299,7 +299,7 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev)
0x04, 0x40, 0x19, 0x0000, buf,
sizeof(buffer), M5602_URB_MSG_TIMEOUT);
- PDEBUG(D_STREAM, "Transfer started");
+ gspca_dbg(gspca_dev, D_STREAM, "Transfer started\n");
return (err < 0) ? err : 0;
}
@@ -309,14 +309,14 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
if (len < 6) {
- PDEBUG(D_PACK, "Packet is less than 6 bytes");
+ gspca_dbg(gspca_dev, D_PACK, "Packet is less than 6 bytes\n");
return;
}
/* Frame delimiter: ff xx xx xx ff ff */
if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff &&
data[2] != sd->frame_id) {
- PDEBUG(D_FRAM, "Frame delimiter detected");
+ gspca_dbg(gspca_dev, D_FRAM, "Frame delimiter detected\n");
sd->frame_id = data[2];
/* Remove the extra fluff appended on each header */
@@ -331,8 +331,8 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
/* Create a new frame */
gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- PDEBUG(D_FRAM, "Starting new frame %d",
- sd->frame_count);
+ gspca_dbg(gspca_dev, D_FRAM, "Starting new frame %d\n",
+ sd->frame_count);
} else {
int cur_frame_len;
@@ -343,8 +343,8 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
len -= 4;
if (cur_frame_len + len <= gspca_dev->frsz) {
- PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
- sd->frame_count, len);
+ gspca_dbg(gspca_dev, D_FRAM, "Continuing frame %d copying %d bytes\n",
+ sd->frame_count, len);
gspca_frame_add(gspca_dev, INTER_PACKET,
data, len);
@@ -397,7 +397,7 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
return 0;
fail:
- PERR("ALi m5602 webcam failed");
+ gspca_err(gspca_dev, "ALi m5602 webcam failed\n");
cam->cam_mode = NULL;
cam->nmodes = 0;
diff --git a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c
index 7d01ddd7ed01..c9947c4a0f63 100644
--- a/drivers/media/usb/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/usb/gspca/m5602/m5602_mt9m111.c
@@ -212,7 +212,7 @@ int mt9m111_probe(struct sd *sd)
return -ENODEV;
}
- PDEBUG(D_PROBE, "Probing for a mt9m111 sensor");
+ gspca_dbg(gspca_dev, D_PROBE, "Probing for a mt9m111 sensor\n");
/* Do the preinit */
for (i = 0; i < ARRAY_SIZE(preinit_mt9m111); i++) {
@@ -375,11 +375,11 @@ int mt9m111_start(struct sd *sd)
switch (width) {
case 640:
- PDEBUG(D_CONF, "Configuring camera for VGA mode");
+ gspca_dbg(gspca_dev, D_CONF, "Configuring camera for VGA mode\n");
break;
case 320:
- PDEBUG(D_CONF, "Configuring camera for QVGA mode");
+ gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QVGA mode\n");
break;
}
return err;
@@ -398,7 +398,8 @@ static int mt9m111_set_hvflip(struct gspca_dev *gspca_dev)
int hflip;
int vflip;
- PDEBUG(D_CONF, "Set hvflip to %d %d", sd->hflip->val, sd->vflip->val);
+ gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d %d\n",
+ sd->hflip->val, sd->vflip->val);
/* The mt9m111 is flipped by default */
hflip = !sd->hflip->val;
@@ -439,7 +440,7 @@ static int mt9m111_set_auto_white_balance(struct gspca_dev *gspca_dev,
err = m5602_write_sensor(sd, MT9M111_CP_OPERATING_MODE_CTL, data, 2);
- PDEBUG(D_CONF, "Set auto white balance %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set auto white balance %d\n", val);
return err;
}
@@ -472,8 +473,8 @@ static int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
data[1] = (tmp & 0xff);
data[0] = (tmp & 0xff00) >> 8;
- PDEBUG(D_CONF, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
- data[1], data[0]);
+ gspca_dbg(gspca_dev, D_CONF, "tmp=%d, data[1]=%d, data[0]=%d\n", tmp,
+ data[1], data[0]);
err = m5602_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
data, 2);
@@ -490,7 +491,7 @@ static int mt9m111_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
data[1] = (val & 0xff);
data[0] = (val & 0xff00) >> 8;
- PDEBUG(D_CONF, "Set green balance %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set green balance %d\n", val);
err = m5602_write_sensor(sd, MT9M111_SC_GREEN_1_GAIN,
data, 2);
if (err < 0)
@@ -508,7 +509,7 @@ static int mt9m111_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
data[1] = (val & 0xff);
data[0] = (val & 0xff00) >> 8;
- PDEBUG(D_CONF, "Set blue balance %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set blue balance %d\n", val);
return m5602_write_sensor(sd, MT9M111_SC_BLUE_GAIN,
data, 2);
@@ -522,7 +523,7 @@ static int mt9m111_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
data[1] = (val & 0xff);
data[0] = (val & 0xff00) >> 8;
- PDEBUG(D_CONF, "Set red balance %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set red balance %d\n", val);
return m5602_write_sensor(sd, MT9M111_SC_RED_GAIN,
data, 2);
diff --git a/drivers/media/usb/gspca/m5602/m5602_ov7660.c b/drivers/media/usb/gspca/m5602/m5602_ov7660.c
index 672b7a520695..aa1f569c82fd 100644
--- a/drivers/media/usb/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/usb/gspca/m5602/m5602_ov7660.c
@@ -330,7 +330,7 @@ static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data = val;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Setting gain to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val);
err = m5602_write_sensor(sd, OV7660_GAIN, &i2c_data, 1);
return err;
@@ -343,7 +343,7 @@ static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Set auto white balance to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
if (err < 0)
@@ -361,7 +361,7 @@ static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Set auto gain control to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val);
err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
if (err < 0)
@@ -379,7 +379,7 @@ static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev,
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Set auto exposure control to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val);
err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
if (err < 0)
@@ -397,7 +397,8 @@ static int ov7660_set_hvflip(struct gspca_dev *gspca_dev)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Set hvflip to %d, %d", sd->hflip->val, sd->vflip->val);
+ gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d, %d\n",
+ sd->hflip->val, sd->vflip->val);
i2c_data = (sd->hflip->val << 5) | (sd->vflip->val << 4);
diff --git a/drivers/media/usb/gspca/m5602/m5602_ov9650.c b/drivers/media/usb/gspca/m5602/m5602_ov9650.c
index 4544d3a1ad58..2ffbb54e89f9 100644
--- a/drivers/media/usb/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/usb/gspca/m5602/m5602_ov9650.c
@@ -311,7 +311,7 @@ int ov9650_probe(struct sd *sd)
return -ENODEV;
}
- PDEBUG(D_PROBE, "Probing for an ov9650 sensor");
+ gspca_dbg(gspca_dev, D_PROBE, "Probing for an ov9650 sensor\n");
/* Run the pre-init before probing the sensor */
for (i = 0; i < ARRAY_SIZE(preinit_ov9650) && !err; i++) {
@@ -505,7 +505,7 @@ int ov9650_start(struct sd *sd)
switch (width) {
case 640:
- PDEBUG(D_CONF, "Configuring camera for VGA mode");
+ gspca_dbg(gspca_dev, D_CONF, "Configuring camera for VGA mode\n");
data = OV9650_VGA_SELECT | OV9650_RGB_SELECT |
OV9650_RAW_RGB_SELECT;
@@ -513,7 +513,7 @@ int ov9650_start(struct sd *sd)
break;
case 352:
- PDEBUG(D_CONF, "Configuring camera for CIF mode");
+ gspca_dbg(gspca_dev, D_CONF, "Configuring camera for CIF mode\n");
data = OV9650_CIF_SELECT | OV9650_RGB_SELECT |
OV9650_RAW_RGB_SELECT;
@@ -521,7 +521,7 @@ int ov9650_start(struct sd *sd)
break;
case 320:
- PDEBUG(D_CONF, "Configuring camera for QVGA mode");
+ gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QVGA mode\n");
data = OV9650_QVGA_SELECT | OV9650_RGB_SELECT |
OV9650_RAW_RGB_SELECT;
@@ -529,7 +529,7 @@ int ov9650_start(struct sd *sd)
break;
case 176:
- PDEBUG(D_CONF, "Configuring camera for QCIF mode");
+ gspca_dbg(gspca_dev, D_CONF, "Configuring camera for QCIF mode\n");
data = OV9650_QCIF_SELECT | OV9650_RGB_SELECT |
OV9650_RAW_RGB_SELECT;
@@ -558,7 +558,7 @@ static int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
int err;
- PDEBUG(D_CONF, "Set exposure to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d\n", val);
/* The 6 MSBs */
i2c_data = (val >> 10) & 0x3f;
@@ -586,7 +586,7 @@ static int ov9650_set_gain(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Setting gain to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Setting gain to %d\n", val);
/* The 2 MSB */
/* Read the OV9650_VREF register first to avoid
@@ -614,7 +614,7 @@ static int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Set red gain to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set red gain to %d\n", val);
i2c_data = val & 0xff;
err = m5602_write_sensor(sd, OV9650_RED, &i2c_data, 1);
@@ -627,7 +627,7 @@ static int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Set blue gain to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set blue gain to %d\n", val);
i2c_data = val & 0xff;
err = m5602_write_sensor(sd, OV9650_BLUE, &i2c_data, 1);
@@ -642,7 +642,7 @@ static int ov9650_set_hvflip(struct gspca_dev *gspca_dev)
int hflip = sd->hflip->val;
int vflip = sd->vflip->val;
- PDEBUG(D_CONF, "Set hvflip to %d %d", hflip, vflip);
+ gspca_dbg(gspca_dev, D_CONF, "Set hvflip to %d %d\n", hflip, vflip);
if (dmi_check_system(ov9650_flip_dmi_table))
vflip = !vflip;
@@ -666,7 +666,7 @@ static int ov9650_set_auto_exposure(struct gspca_dev *gspca_dev,
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Set auto exposure control to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set auto exposure control to %d\n", val);
err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
if (err < 0)
@@ -685,7 +685,7 @@ static int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev,
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Set auto white balance to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
if (err < 0)
@@ -703,7 +703,7 @@ static int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Set auto gain control to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set auto gain control to %d\n", val);
err = m5602_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
if (err < 0)
diff --git a/drivers/media/usb/gspca/m5602/m5602_po1030.c b/drivers/media/usb/gspca/m5602/m5602_po1030.c
index a0a90dd34ca8..37d2891e5f5b 100644
--- a/drivers/media/usb/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/usb/gspca/m5602/m5602_po1030.c
@@ -171,7 +171,7 @@ int po1030_probe(struct sd *sd)
return -ENODEV;
}
- PDEBUG(D_PROBE, "Probing for a po1030 sensor");
+ gspca_dbg(gspca_dev, D_PROBE, "Probing for a po1030 sensor\n");
/* Run the pre-init to actually probe the unit */
for (i = 0; i < ARRAY_SIZE(preinit_po1030); i++) {
@@ -410,11 +410,11 @@ static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
int err;
- PDEBUG(D_CONF, "Set exposure to %d", val & 0xffff);
+ gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d\n", val & 0xffff);
i2c_data = ((val & 0xff00) >> 8);
- PDEBUG(D_CONF, "Set exposure to high byte to 0x%x",
- i2c_data);
+ gspca_dbg(gspca_dev, D_CONF, "Set exposure to high byte to 0x%x\n",
+ i2c_data);
err = m5602_write_sensor(sd, PO1030_INTEGLINES_H,
&i2c_data, 1);
@@ -422,8 +422,8 @@ static int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
return err;
i2c_data = (val & 0xff);
- PDEBUG(D_CONF, "Set exposure to low byte to 0x%x",
- i2c_data);
+ gspca_dbg(gspca_dev, D_CONF, "Set exposure to low byte to 0x%x\n",
+ i2c_data);
err = m5602_write_sensor(sd, PO1030_INTEGLINES_M,
&i2c_data, 1);
@@ -437,7 +437,7 @@ static int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
int err;
i2c_data = val & 0xff;
- PDEBUG(D_CONF, "Set global gain to %d", i2c_data);
+ gspca_dbg(gspca_dev, D_CONF, "Set global gain to %d\n", i2c_data);
err = m5602_write_sensor(sd, PO1030_GLOBALGAIN,
&i2c_data, 1);
return err;
@@ -449,7 +449,8 @@ static int po1030_set_hvflip(struct gspca_dev *gspca_dev)
u8 i2c_data;
int err;
- PDEBUG(D_CONF, "Set hvflip %d %d", sd->hflip->val, sd->vflip->val);
+ gspca_dbg(gspca_dev, D_CONF, "Set hvflip %d %d\n",
+ sd->hflip->val, sd->vflip->val);
err = m5602_read_sensor(sd, PO1030_CONTROL2, &i2c_data, 1);
if (err < 0)
return err;
@@ -470,7 +471,7 @@ static int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
int err;
i2c_data = val & 0xff;
- PDEBUG(D_CONF, "Set red gain to %d", i2c_data);
+ gspca_dbg(gspca_dev, D_CONF, "Set red gain to %d\n", i2c_data);
err = m5602_write_sensor(sd, PO1030_RED_GAIN,
&i2c_data, 1);
return err;
@@ -483,7 +484,7 @@ static int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
int err;
i2c_data = val & 0xff;
- PDEBUG(D_CONF, "Set blue gain to %d", i2c_data);
+ gspca_dbg(gspca_dev, D_CONF, "Set blue gain to %d\n", i2c_data);
err = m5602_write_sensor(sd, PO1030_BLUE_GAIN,
&i2c_data, 1);
@@ -497,7 +498,7 @@ static int po1030_set_green_balance(struct gspca_dev *gspca_dev, __s32 val)
int err;
i2c_data = val & 0xff;
- PDEBUG(D_CONF, "Set green gain to %d", i2c_data);
+ gspca_dbg(gspca_dev, D_CONF, "Set green gain to %d\n", i2c_data);
err = m5602_write_sensor(sd, PO1030_GREEN_1_GAIN,
&i2c_data, 1);
@@ -519,7 +520,7 @@ static int po1030_set_auto_white_balance(struct gspca_dev *gspca_dev,
if (err < 0)
return err;
- PDEBUG(D_CONF, "Set auto white balance to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set auto white balance to %d\n", val);
i2c_data = (i2c_data & 0xfe) | (val & 0x01);
err = m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
return err;
@@ -536,7 +537,7 @@ static int po1030_set_auto_exposure(struct gspca_dev *gspca_dev,
if (err < 0)
return err;
- PDEBUG(D_CONF, "Set auto exposure to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set auto exposure to %d\n", val);
val = (val == V4L2_EXPOSURE_AUTO);
i2c_data = (i2c_data & 0xfd) | ((val & 0x01) << 1);
return m5602_write_sensor(sd, PO1030_AUTOCTRL1, &i2c_data, 1);
diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c
index 8447b9c5f8e0..cec4a5838aec 100644
--- a/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/usb/gspca/m5602/m5602_s5k4aa.c
@@ -357,7 +357,7 @@ int s5k4aa_probe(struct sd *sd)
return -ENODEV;
}
- PDEBUG(D_PROBE, "Probing for a s5k4aa sensor");
+ gspca_dbg(gspca_dev, D_PROBE, "Probing for a s5k4aa sensor\n");
/* Preinit the sensor */
for (i = 0; i < ARRAY_SIZE(preinit_s5k4aa) && !err; i++) {
@@ -419,7 +419,7 @@ int s5k4aa_start(struct sd *sd)
switch (cam->cam_mode[sd->gspca_dev.curr_mode].width) {
case 1280:
- PDEBUG(D_CONF, "Configuring camera for SXGA mode");
+ gspca_dbg(gspca_dev, D_CONF, "Configuring camera for SXGA mode\n");
for (i = 0; i < ARRAY_SIZE(SXGA_s5k4aa); i++) {
switch (SXGA_s5k4aa[i][0]) {
@@ -452,7 +452,7 @@ int s5k4aa_start(struct sd *sd)
break;
case 640:
- PDEBUG(D_CONF, "Configuring camera for VGA mode");
+ gspca_dbg(gspca_dev, D_CONF, "Configuring camera for VGA mode\n");
for (i = 0; i < ARRAY_SIZE(VGA_s5k4aa); i++) {
switch (VGA_s5k4aa[i][0]) {
@@ -568,7 +568,7 @@ static int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(D_CONF, "Set exposure to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d\n", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
return err;
@@ -590,7 +590,7 @@ static int s5k4aa_set_hvflip(struct gspca_dev *gspca_dev)
int hflip = sd->hflip->val;
int vflip = sd->vflip->val;
- PDEBUG(D_CONF, "Set hvflip %d %d", hflip, vflip);
+ gspca_dbg(gspca_dev, D_CONF, "Set hvflip %d %d\n", hflip, vflip);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
return err;
@@ -640,7 +640,7 @@ static int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(D_CONF, "Set gain to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set gain to %d\n", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
return err;
@@ -657,7 +657,7 @@ static int s5k4aa_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(D_CONF, "Set brightness to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set brightness to %d\n", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
return err;
@@ -672,7 +672,7 @@ static int s5k4aa_set_noise(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(D_CONF, "Set noise to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set noise to %d\n", val);
err = m5602_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
return err;
diff --git a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
index 6ad8d4849680..3d8ab18138aa 100644
--- a/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/usb/gspca/m5602/m5602_s5k83a.c
@@ -187,7 +187,7 @@ int s5k83a_probe(struct sd *sd)
return -ENODEV;
}
- PDEBUG(D_PROBE, "Probing for a s5k83a sensor");
+ gspca_dbg(gspca_dev, D_PROBE, "Probing for a s5k83a sensor\n");
/* Preinit the sensor */
for (i = 0; i < ARRAY_SIZE(preinit_s5k83a) && !err; i++) {
diff --git a/drivers/media/usb/gspca/mars.c b/drivers/media/usb/gspca/mars.c
index 25df55e840c7..a537cb195c46 100644
--- a/drivers/media/usb/gspca/mars.c
+++ b/drivers/media/usb/gspca/mars.c
@@ -378,8 +378,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|| data[5 + p] == 0x65
|| data[5 + p] == 0x66
|| data[5 + p] == 0x67) {
- PDEBUG(D_PACK, "sof offset: %d len: %d",
- p, len);
+ gspca_dbg(gspca_dev, D_PACK, "sof offset: %d len: %d\n",
+ p, len);
gspca_frame_add(gspca_dev, LAST_PACKET,
data, p);
diff --git a/drivers/media/usb/gspca/mr97310a.c b/drivers/media/usb/gspca/mr97310a.c
index 8b0e32a649ac..bea196361215 100644
--- a/drivers/media/usb/gspca/mr97310a.c
+++ b/drivers/media/usb/gspca/mr97310a.c
@@ -221,10 +221,11 @@ static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
return err_code;
if (verbose)
- PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
- gspca_dev->usb_buf[0],
- gspca_dev->usb_buf[1],
- gspca_dev->usb_buf[2]);
+ gspca_dbg(gspca_dev, D_PROBE, "Register: %02x reads %02x%02x%02x\n",
+ reg,
+ gspca_dev->usb_buf[0],
+ gspca_dev->usb_buf[1],
+ gspca_dev->usb_buf[2]);
return 0;
}
@@ -284,7 +285,7 @@ static int zero_the_pointer(struct gspca_dev *gspca_dev)
return err_code;
}
if (status != 0x0a)
- PERR("status is %02x", status);
+ gspca_err(gspca_dev, "status is %02x\n", status);
tries = 0;
while (tries < 4) {
@@ -325,7 +326,7 @@ static void stream_stop(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0] = 0x01;
gspca_dev->usb_buf[1] = 0x00;
if (mr_write(gspca_dev, 2) < 0)
- PERR("Stream Stop failed");
+ gspca_err(gspca_dev, "Stream Stop failed\n");
}
static void lcd_stop(struct gspca_dev *gspca_dev)
@@ -333,7 +334,7 @@ static void lcd_stop(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0] = 0x19;
gspca_dev->usb_buf[1] = 0x54;
if (mr_write(gspca_dev, 2) < 0)
- PERR("LCD Stop failed");
+ gspca_err(gspca_dev, "LCD Stop failed\n");
}
static int isoc_enable(struct gspca_dev *gspca_dev)
@@ -413,8 +414,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
gspca_dev->usb_buf[1]);
return -ENODEV;
}
- PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
- sd->sensor_type);
+ gspca_dbg(gspca_dev, D_PROBE, "MR97310A CIF camera detected, sensor: %d\n",
+ sd->sensor_type);
} else {
sd->cam_type = CAM_TYPE_VGA;
@@ -458,7 +459,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
switch (gspca_dev->usb_buf[1]) {
case 0x50:
sd->sensor_type = 0;
- PDEBUG(D_PROBE, "sensor_type corrected to 0");
+ gspca_dbg(gspca_dev, D_PROBE, "sensor_type corrected to 0\n");
break;
case 0x20:
/* Nothing to do here. */
@@ -470,16 +471,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
pr_err("Please report this\n");
}
}
- PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
- sd->sensor_type);
+ gspca_dbg(gspca_dev, D_PROBE, "MR97310A VGA camera detected, sensor: %d\n",
+ sd->sensor_type);
}
/* Stop streaming as we've started it only to probe the sensor type. */
sd_stopN(gspca_dev);
if (force_sensor_type != -1) {
sd->sensor_type = !!force_sensor_type;
- PDEBUG(D_PROBE, "Forcing sensor type to: %d",
- sd->sensor_type);
+ gspca_dbg(gspca_dev, D_PROBE, "Forcing sensor type to: %d\n",
+ sd->sensor_type);
}
return 0;
diff --git a/drivers/media/usb/gspca/nw80x.c b/drivers/media/usb/gspca/nw80x.c
index 5d2d0bcb038d..bedc04a72e97 100644
--- a/drivers/media/usb/gspca/nw80x.c
+++ b/drivers/media/usb/gspca/nw80x.c
@@ -1543,10 +1543,11 @@ static void reg_w(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_err < 0)
return;
if (len == 1)
- PDEBUG(D_USBO, "SET 00 0000 %04x %02x", index, *data);
+ gspca_dbg(gspca_dev, D_USBO, "SET 00 0000 %04x %02x\n",
+ index, *data);
else
- PDEBUG(D_USBO, "SET 00 0000 %04x %02x %02x ...",
- index, *data, data[1]);
+ gspca_dbg(gspca_dev, D_USBO, "SET 00 0000 %04x %02x %02x ...\n",
+ index, *data, data[1]);
memcpy(gspca_dev->usb_buf, data, len);
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
0x00,
@@ -1583,12 +1584,12 @@ static void reg_r(struct gspca_dev *gspca_dev,
return;
}
if (len == 1)
- PDEBUG(D_USBI, "GET 00 0000 %04x %02x",
- index, gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "GET 00 0000 %04x %02x\n",
+ index, gspca_dev->usb_buf[0]);
else
- PDEBUG(D_USBI, "GET 00 0000 %04x %02x %02x ..",
- index, gspca_dev->usb_buf[0],
- gspca_dev->usb_buf[1]);
+ gspca_dbg(gspca_dev, D_USBI, "GET 00 0000 %04x %02x %02x ..\n",
+ index, gspca_dev->usb_buf[0],
+ gspca_dev->usb_buf[1]);
}
static void i2c_w(struct gspca_dev *gspca_dev,
@@ -1762,8 +1763,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->webcam = P35u;
} else if (id->idVendor == 0x06a5 && id->idProduct == 0xd800) {
reg_r(gspca_dev, 0x0403, 1); /* GPIO */
- PDEBUG(D_PROBE, "et31x110 sensor type %02x",
- gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_PROBE, "et31x110 sensor type %02x\n",
+ gspca_dev->usb_buf[0]);
switch (gspca_dev->usb_buf[0] >> 1) {
case 0x00: /* ?? */
if (sd->webcam == Generic800)
@@ -1785,7 +1786,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
gspca_dev->usb_err = -ENODEV;
return gspca_dev->usb_err;
}
- PDEBUG(D_PROBE, "Bridge nw80%d - type: %d", sd->bridge, sd->webcam);
+ gspca_dbg(gspca_dev, D_PROBE, "Bridge nw80%d - type: %d\n",
+ sd->bridge, sd->webcam);
if (sd->bridge == BRIDGE_NW800) {
switch (sd->webcam) {
diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c
index 1b30434b72ef..10fcbe9e8614 100644
--- a/drivers/media/usb/gspca/ov519.c
+++ b/drivers/media/usb/gspca/ov519.c
@@ -2016,8 +2016,8 @@ static void reg_w(struct sd *sd, u16 index, u16 value)
req = 0x0a;
/* fall through */
case BRIDGE_W9968CF:
- PDEBUG(D_USBO, "SET %02x %04x %04x",
- req, value, index);
+ gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n",
+ req, value, index);
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
req,
@@ -2028,8 +2028,8 @@ static void reg_w(struct sd *sd, u16 index, u16 value)
req = 1;
}
- PDEBUG(D_USBO, "SET %02x 0000 %04x %02x",
- req, index, value);
+ gspca_dbg(gspca_dev, D_USBO, "SET %02x 0000 %04x %02x\n",
+ req, index, value);
sd->gspca_dev.usb_buf[0] = value;
ret = usb_control_msg(sd->gspca_dev.dev,
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
@@ -2039,7 +2039,7 @@ static void reg_w(struct sd *sd, u16 index, u16 value)
sd->gspca_dev.usb_buf, 1, 500);
leave:
if (ret < 0) {
- PERR("reg_w %02x failed %d\n", index, ret);
+ gspca_err(gspca_dev, "reg_w %02x failed %d\n", index, ret);
sd->gspca_dev.usb_err = ret;
return;
}
@@ -2078,10 +2078,10 @@ static int reg_r(struct sd *sd, u16 index)
if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0];
- PDEBUG(D_USBI, "GET %02x 0000 %04x %02x",
- req, index, ret);
+ gspca_dbg(gspca_dev, D_USBI, "GET %02x 0000 %04x %02x\n",
+ req, index, ret);
} else {
- PERR("reg_r %02x failed %d\n", index, ret);
+ gspca_err(gspca_dev, "reg_r %02x failed %d\n", index, ret);
sd->gspca_dev.usb_err = ret;
}
@@ -2109,7 +2109,7 @@ static int reg_r8(struct sd *sd,
if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0];
} else {
- PERR("reg_r8 %02x failed %d\n", index, ret);
+ gspca_err(gspca_dev, "reg_r8 %02x failed %d\n", index, ret);
sd->gspca_dev.usb_err = ret;
}
@@ -2165,7 +2165,7 @@ static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
0, index,
sd->gspca_dev.usb_buf, n, 500);
if (ret < 0) {
- PERR("reg_w32 %02x failed %d\n", index, ret);
+ gspca_err(gspca_dev, "reg_w32 %02x failed %d\n", index, ret);
sd->gspca_dev.usb_err = ret;
}
}
@@ -2175,7 +2175,7 @@ static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
int rc, retries;
- PDEBUG(D_USBO, "ov511_i2c_w %02x %02x", reg, value);
+ gspca_dbg(gspca_dev, D_USBO, "ov511_i2c_w %02x %02x\n", reg, value);
/* Three byte write cycle */
for (retries = 6; ; ) {
@@ -2198,7 +2198,7 @@ static void ov511_i2c_w(struct sd *sd, u8 reg, u8 value)
if ((rc & 2) == 0) /* Ack? */
break;
if (--retries < 0) {
- PDEBUG(D_USBO, "i2c write retries exhausted");
+ gspca_dbg(gspca_dev, D_USBO, "i2c write retries exhausted\n");
return;
}
}
@@ -2231,7 +2231,7 @@ static int ov511_i2c_r(struct sd *sd, u8 reg)
reg_w(sd, R511_I2C_CTL, 0x10);
if (--retries < 0) {
- PDEBUG(D_USBI, "i2c write retries exhausted");
+ gspca_dbg(gspca_dev, D_USBI, "i2c write retries exhausted\n");
return -1;
}
}
@@ -2255,14 +2255,14 @@ static int ov511_i2c_r(struct sd *sd, u8 reg)
reg_w(sd, R511_I2C_CTL, 0x10);
if (--retries < 0) {
- PDEBUG(D_USBI, "i2c read retries exhausted");
+ gspca_dbg(gspca_dev, D_USBI, "i2c read retries exhausted\n");
return -1;
}
}
value = reg_r(sd, R51x_I2C_DATA);
- PDEBUG(D_USBI, "ov511_i2c_r %02x %02x", reg, value);
+ gspca_dbg(gspca_dev, D_USBI, "ov511_i2c_r %02x %02x\n", reg, value);
/* This is needed to make i2c_w() work */
reg_w(sd, R511_I2C_CTL, 0x05);
@@ -2281,7 +2281,7 @@ static void ov518_i2c_w(struct sd *sd,
{
struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
- PDEBUG(D_USBO, "ov518_i2c_w %02x %02x", reg, value);
+ gspca_dbg(gspca_dev, D_USBO, "ov518_i2c_w %02x %02x\n", reg, value);
/* Select camera register */
reg_w(sd, R51x_I2C_SADDR_3, reg);
@@ -2321,7 +2321,7 @@ static int ov518_i2c_r(struct sd *sd, u8 reg)
reg_r8(sd, R518_I2C_CTL);
value = reg_r(sd, R51x_I2C_DATA);
- PDEBUG(D_USBI, "ov518_i2c_r %02x %02x", reg, value);
+ gspca_dbg(gspca_dev, D_USBI, "ov518_i2c_r %02x %02x\n", reg, value);
return value;
}
@@ -2340,11 +2340,11 @@ static void ovfx2_i2c_w(struct sd *sd, u8 reg, u8 value)
(u16) value, (u16) reg, NULL, 0, 500);
if (ret < 0) {
- PERR("ovfx2_i2c_w %02x failed %d\n", reg, ret);
+ gspca_err(gspca_dev, "ovfx2_i2c_w %02x failed %d\n", reg, ret);
sd->gspca_dev.usb_err = ret;
}
- PDEBUG(D_USBO, "ovfx2_i2c_w %02x %02x", reg, value);
+ gspca_dbg(gspca_dev, D_USBO, "ovfx2_i2c_w %02x %02x\n", reg, value);
}
static int ovfx2_i2c_r(struct sd *sd, u8 reg)
@@ -2363,9 +2363,10 @@ static int ovfx2_i2c_r(struct sd *sd, u8 reg)
if (ret >= 0) {
ret = sd->gspca_dev.usb_buf[0];
- PDEBUG(D_USBI, "ovfx2_i2c_r %02x %02x", reg, ret);
+ gspca_dbg(gspca_dev, D_USBI, "ovfx2_i2c_r %02x %02x\n",
+ reg, ret);
} else {
- PERR("ovfx2_i2c_r %02x failed %d\n", reg, ret);
+ gspca_err(gspca_dev, "ovfx2_i2c_r %02x failed %d\n", reg, ret);
sd->gspca_dev.usb_err = ret;
}
@@ -2464,7 +2465,7 @@ static inline void ov51x_stop(struct sd *sd)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
- PDEBUG(D_STREAM, "stopping");
+ gspca_dbg(gspca_dev, D_STREAM, "stopping\n");
sd->stopped = 1;
switch (sd->bridge) {
case BRIDGE_OV511:
@@ -2495,7 +2496,7 @@ static inline void ov51x_restart(struct sd *sd)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
- PDEBUG(D_STREAM, "restarting");
+ gspca_dbg(gspca_dev, D_STREAM, "restarting\n");
if (!sd->stopped)
return;
sd->stopped = 0;
@@ -2546,7 +2547,8 @@ static int init_ov_sensor(struct sd *sd, u8 slave)
for (i = 0; i < i2c_detect_tries; i++) {
if (i2c_r(sd, OV7610_REG_ID_HIGH) == 0x7f &&
i2c_r(sd, OV7610_REG_ID_LOW) == 0xa2) {
- PDEBUG(D_PROBE, "I2C synced in %d attempt(s)", i);
+ gspca_dbg(gspca_dev, D_PROBE, "I2C synced in %d attempt(s)\n",
+ i);
return 0;
}
@@ -2617,11 +2619,11 @@ static void ov_hires_configure(struct sd *sd)
int high, low;
if (sd->bridge != BRIDGE_OVFX2) {
- PERR("error hires sensors only supported with ovfx2\n");
+ gspca_err(gspca_dev, "error hires sensors only supported with ovfx2\n");
return;
}
- PDEBUG(D_PROBE, "starting ov hires configuration");
+ gspca_dbg(gspca_dev, D_PROBE, "starting ov hires configuration\n");
/* Detect sensor (sub)type */
high = i2c_r(sd, 0x0a);
@@ -2631,28 +2633,29 @@ static void ov_hires_configure(struct sd *sd)
case 0x96:
switch (low) {
case 0x40:
- PDEBUG(D_PROBE, "Sensor is a OV2610");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV2610\n");
sd->sensor = SEN_OV2610;
return;
case 0x41:
- PDEBUG(D_PROBE, "Sensor is a OV2610AE");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV2610AE\n");
sd->sensor = SEN_OV2610AE;
return;
case 0xb1:
- PDEBUG(D_PROBE, "Sensor is a OV9600");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV9600\n");
sd->sensor = SEN_OV9600;
return;
}
break;
case 0x36:
if ((low & 0x0f) == 0x00) {
- PDEBUG(D_PROBE, "Sensor is a OV3610");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV3610\n");
sd->sensor = SEN_OV3610;
return;
}
break;
}
- PERR("Error unknown sensor type: %02x%02x\n", high, low);
+ gspca_err(gspca_dev, "Error unknown sensor type: %02x%02x\n",
+ high, low);
}
/* This initializes the OV8110, OV8610 sensor. The OV8110 uses
@@ -2663,18 +2666,19 @@ static void ov8xx0_configure(struct sd *sd)
struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
int rc;
- PDEBUG(D_PROBE, "starting ov8xx0 configuration");
+ gspca_dbg(gspca_dev, D_PROBE, "starting ov8xx0 configuration\n");
/* Detect sensor (sub)type */
rc = i2c_r(sd, OV7610_REG_COM_I);
if (rc < 0) {
- PERR("Error detecting sensor type");
+ gspca_err(gspca_dev, "Error detecting sensor type\n");
return;
}
if ((rc & 3) == 1)
sd->sensor = SEN_OV8610;
else
- PERR("Unknown image sensor version: %d\n", rc & 3);
+ gspca_err(gspca_dev, "Unknown image sensor version: %d\n",
+ rc & 3);
}
/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
@@ -2685,7 +2689,7 @@ static void ov7xx0_configure(struct sd *sd)
struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
int rc, high, low;
- PDEBUG(D_PROBE, "starting OV7xx0 configuration");
+ gspca_dbg(gspca_dev, D_PROBE, "starting OV7xx0 configuration\n");
/* Detect sensor (sub)type */
rc = i2c_r(sd, OV7610_REG_COM_I);
@@ -2693,7 +2697,7 @@ static void ov7xx0_configure(struct sd *sd)
/* add OV7670 here
* it appears to be wrongly detected as a 7610 by default */
if (rc < 0) {
- PERR("Error detecting sensor type\n");
+ gspca_err(gspca_dev, "Error detecting sensor type\n");
return;
}
if ((rc & 3) == 3) {
@@ -2702,65 +2706,68 @@ static void ov7xx0_configure(struct sd *sd)
low = i2c_r(sd, 0x0b);
/* info("%x, %x", high, low); */
if (high == 0x76 && (low & 0xf0) == 0x70) {
- PDEBUG(D_PROBE, "Sensor is an OV76%02x", low);
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV76%02x\n",
+ low);
sd->sensor = SEN_OV7670;
} else {
- PDEBUG(D_PROBE, "Sensor is an OV7610");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7610\n");
sd->sensor = SEN_OV7610;
}
} else if ((rc & 3) == 1) {
/* I don't know what's different about the 76BE yet. */
if (i2c_r(sd, 0x15) & 1) {
- PDEBUG(D_PROBE, "Sensor is an OV7620AE");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7620AE\n");
sd->sensor = SEN_OV7620AE;
} else {
- PDEBUG(D_PROBE, "Sensor is an OV76BE");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV76BE\n");
sd->sensor = SEN_OV76BE;
}
} else if ((rc & 3) == 0) {
/* try to read product id registers */
high = i2c_r(sd, 0x0a);
if (high < 0) {
- PERR("Error detecting camera chip PID\n");
+ gspca_err(gspca_dev, "Error detecting camera chip PID\n");
return;
}
low = i2c_r(sd, 0x0b);
if (low < 0) {
- PERR("Error detecting camera chip VER\n");
+ gspca_err(gspca_dev, "Error detecting camera chip VER\n");
return;
}
if (high == 0x76) {
switch (low) {
case 0x30:
- PERR("Sensor is an OV7630/OV7635\n");
- PERR("7630 is not supported by this driver\n");
+ gspca_err(gspca_dev, "Sensor is an OV7630/OV7635\n");
+ gspca_err(gspca_dev, "7630 is not supported by this driver\n");
return;
case 0x40:
- PDEBUG(D_PROBE, "Sensor is an OV7645");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7645\n");
sd->sensor = SEN_OV7640; /* FIXME */
break;
case 0x45:
- PDEBUG(D_PROBE, "Sensor is an OV7645B");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7645B\n");
sd->sensor = SEN_OV7640; /* FIXME */
break;
case 0x48:
- PDEBUG(D_PROBE, "Sensor is an OV7648");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7648\n");
sd->sensor = SEN_OV7648;
break;
case 0x60:
- PDEBUG(D_PROBE, "Sensor is a OV7660");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is a OV7660\n");
sd->sensor = SEN_OV7660;
break;
default:
- PERR("Unknown sensor: 0x76%02x\n", low);
+ gspca_err(gspca_dev, "Unknown sensor: 0x76%02x\n",
+ low);
return;
}
} else {
- PDEBUG(D_PROBE, "Sensor is an OV7620");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV7620\n");
sd->sensor = SEN_OV7620;
}
} else {
- PERR("Unknown image sensor version: %d\n", rc & 3);
+ gspca_err(gspca_dev, "Unknown image sensor version: %d\n",
+ rc & 3);
}
}
@@ -2770,12 +2777,12 @@ static void ov6xx0_configure(struct sd *sd)
struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
int rc;
- PDEBUG(D_PROBE, "starting OV6xx0 configuration");
+ gspca_dbg(gspca_dev, D_PROBE, "starting OV6xx0 configuration\n");
/* Detect sensor (sub)type */
rc = i2c_r(sd, OV7610_REG_COM_I);
if (rc < 0) {
- PERR("Error detecting sensor type\n");
+ gspca_err(gspca_dev, "Error detecting sensor type\n");
return;
}
@@ -2789,22 +2796,23 @@ static void ov6xx0_configure(struct sd *sd)
break;
case 0x01:
sd->sensor = SEN_OV6620;
- PDEBUG(D_PROBE, "Sensor is an OV6620");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV6620\n");
break;
case 0x02:
sd->sensor = SEN_OV6630;
- PDEBUG(D_PROBE, "Sensor is an OV66308AE");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV66308AE\n");
break;
case 0x03:
sd->sensor = SEN_OV66308AF;
- PDEBUG(D_PROBE, "Sensor is an OV66308AF");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor is an OV66308AF\n");
break;
case 0x90:
sd->sensor = SEN_OV6630;
pr_warn("WARNING: Sensor is an OV66307. Your camera may have been misdetected in previous driver versions.\n");
break;
default:
- PERR("FATAL: Unknown sensor version: 0x%02x\n", rc);
+ gspca_err(gspca_dev, "FATAL: Unknown sensor version: 0x%02x\n",
+ rc);
return;
}
@@ -2906,7 +2914,7 @@ static void ov51x_upload_quan_tables(struct sd *sd)
unsigned char val0, val1;
int i, size, reg = R51x_COMP_LUT_BEGIN;
- PDEBUG(D_PROBE, "Uploading quantization tables");
+ gspca_dbg(gspca_dev, D_PROBE, "Uploading quantization tables\n");
if (sd->bridge == BRIDGE_OV511 || sd->bridge == BRIDGE_OV511PLUS) {
pYTable = yQuanTable511;
@@ -2984,7 +2992,8 @@ static void ov511_configure(struct gspca_dev *gspca_dev)
{ 0x77, 0x04 },
};
- PDEBUG(D_PROBE, "Device custom id %x", reg_r(sd, R51x_SYS_CUST_ID));
+ gspca_dbg(gspca_dev, D_PROBE, "Device custom id %x\n",
+ reg_r(sd, R51x_SYS_CUST_ID));
write_regvals(sd, init_511, ARRAY_SIZE(init_511));
@@ -3054,7 +3063,7 @@ static void ov518_configure(struct gspca_dev *gspca_dev)
/* First 5 bits of custom ID reg are a revision ID on OV518 */
sd->revision = reg_r(sd, R51x_SYS_CUST_ID) & 0x1f;
- PDEBUG(D_PROBE, "Device revision %d", sd->revision);
+ gspca_dbg(gspca_dev, D_PROBE, "Device revision %d\n", sd->revision);
write_regvals(sd, init_518, ARRAY_SIZE(init_518));
@@ -3295,7 +3304,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
} else if (init_ov_sensor(sd, OV_HIRES_SID) >= 0) {
ov_hires_configure(sd);
} else {
- PERR("Can't determine sensor slave IDs\n");
+ gspca_err(gspca_dev, "Can't determine sensor slave IDs\n");
goto error;
}
@@ -3428,7 +3437,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
}
return gspca_dev->usb_err;
error:
- PERR("OV519 Config failed");
+ gspca_err(gspca_dev, "OV519 Config failed\n");
return -EINVAL;
}
@@ -3463,7 +3472,7 @@ static void ov511_mode_init_regs(struct sd *sd)
intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
if (!alt) {
- PERR("Couldn't get altsetting\n");
+ gspca_err(gspca_dev, "Couldn't get altsetting\n");
sd->gspca_dev.usb_err = -EIO;
return;
}
@@ -3589,7 +3598,7 @@ static void ov518_mode_init_regs(struct sd *sd)
intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
if (!alt) {
- PERR("Couldn't get altsetting\n");
+ gspca_err(gspca_dev, "Couldn't get altsetting\n");
sd->gspca_dev.usb_err = -EIO;
return;
}
@@ -3861,8 +3870,8 @@ static void ov519_mode_init_regs(struct sd *sd)
}
break;
case SEN_OV7670: /* guesses, based on 7640 */
- PDEBUG(D_STREAM, "Setting framerate to %d fps",
- (sd->frame_rate == 0) ? 15 : sd->frame_rate);
+ gspca_dbg(gspca_dev, D_STREAM, "Setting framerate to %d fps\n",
+ (sd->frame_rate == 0) ? 15 : sd->frame_rate);
reg_w(sd, 0xa4, 0x10);
switch (sd->frame_rate) {
case 30:
@@ -4323,10 +4332,10 @@ static void ov511_pkt_scan(struct gspca_dev *gspca_dev,
/* Frame end */
if ((in[9] + 1) * 8 != gspca_dev->pixfmt.width ||
(in[10] + 1) * 8 != gspca_dev->pixfmt.height) {
- PERR("Invalid frame size, got: %dx%d, requested: %dx%d\n",
- (in[9] + 1) * 8, (in[10] + 1) * 8,
- gspca_dev->pixfmt.width,
- gspca_dev->pixfmt.height);
+ gspca_err(gspca_dev, "Invalid frame size, got: %dx%d, requested: %dx%d\n",
+ (in[9] + 1) * 8, (in[10] + 1) * 8,
+ gspca_dev->pixfmt.width,
+ gspca_dev->pixfmt.height);
gspca_dev->last_packet_type = DISCARD_PACKET;
return;
}
@@ -4374,8 +4383,8 @@ static void ov518_pkt_scan(struct gspca_dev *gspca_dev,
except that they may contain part of the footer), are
numbered 0 */
else if (sd->packet_nr == 0 || data[len]) {
- PERR("Invalid packet nr: %d (expect: %d)",
- (int)data[len], (int)sd->packet_nr);
+ gspca_err(gspca_dev, "Invalid packet nr: %d (expect: %d)\n",
+ (int)data[len], (int)sd->packet_nr);
gspca_dev->last_packet_type = DISCARD_PACKET;
return;
}
@@ -4918,7 +4927,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
if (hdl->error) {
- PERR("Could not initialize controls\n");
+ gspca_err(gspca_dev, "Could not initialize controls\n");
return hdl->error;
}
if (gspca_dev->autogain)
diff --git a/drivers/media/usb/gspca/ov534.c b/drivers/media/usb/gspca/ov534.c
index 32849ff86b09..f293921a1f2b 100644
--- a/drivers/media/usb/gspca/ov534.c
+++ b/drivers/media/usb/gspca/ov534.c
@@ -612,7 +612,7 @@ static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_USBO, "SET 01 0000 %04x %02x", reg, val);
+ gspca_dbg(gspca_dev, D_USBO, "SET 01 0000 %04x %02x\n", reg, val);
gspca_dev->usb_buf[0] = val;
ret = usb_control_msg(udev,
usb_sndctrlpipe(udev, 0),
@@ -637,7 +637,8 @@ static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
0x01,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- PDEBUG(D_USBI, "GET 01 0000 %04x %02x", reg, gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "GET 01 0000 %04x %02x\n",
+ reg, gspca_dev->usb_buf[0]);
if (ret < 0) {
pr_err("read failed %d\n", ret);
gspca_dev->usb_err = ret;
@@ -651,7 +652,7 @@ static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
{
u8 data;
- PDEBUG(D_CONF, "led status: %d", status);
+ gspca_dbg(gspca_dev, D_CONF, "led status: %d\n", status);
data = ov534_reg_read(gspca_dev, 0x21);
data |= 0x80;
@@ -689,8 +690,8 @@ static int sccb_check_status(struct gspca_dev *gspca_dev)
case 0x03:
break;
default:
- PERR("sccb status 0x%02x, attempt %d/5",
- data, i + 1);
+ gspca_err(gspca_dev, "sccb status 0x%02x, attempt %d/5\n",
+ data, i + 1);
}
}
return 0;
@@ -698,7 +699,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev)
static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
{
- PDEBUG(D_USBO, "sccb write: %02x %02x", reg, val);
+ gspca_dbg(gspca_dev, D_USBO, "sccb write: %02x %02x\n", reg, val);
ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
@@ -800,7 +801,7 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
sccb_reg_write(gspca_dev, 0x0d, r->r0d);
ov534_reg_write(gspca_dev, 0xe5, r->re5);
- PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
+ gspca_dbg(gspca_dev, D_PROBE, "frame_rate: %d\n", r->fps);
}
static void sethue(struct gspca_dev *gspca_dev, s32 val)
@@ -1283,7 +1284,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8;
sccb_reg_read(gspca_dev, 0x0b);
sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
- PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor ID: %04x\n", sensor_id);
if ((sensor_id & 0xfff0) == 0x7670) {
sd->sensor = SENSOR_OV767x;
@@ -1407,19 +1408,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* Verify UVC header. Header length is always 12 */
if (data[0] != 12 || len < 12) {
- PDEBUG(D_PACK, "bad header");
+ gspca_dbg(gspca_dev, D_PACK, "bad header\n");
goto discard;
}
/* Check errors */
if (data[1] & UVC_STREAM_ERR) {
- PDEBUG(D_PACK, "payload error");
+ gspca_dbg(gspca_dev, D_PACK, "payload error\n");
goto discard;
}
/* Extract PTS and FID */
if (!(data[1] & UVC_STREAM_PTS)) {
- PDEBUG(D_PACK, "PTS not present");
+ gspca_dbg(gspca_dev, D_PACK, "PTS not present\n");
goto discard;
}
this_pts = (data[5] << 24) | (data[4] << 16)
@@ -1442,7 +1443,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
&& gspca_dev->image_len + len - 12 !=
gspca_dev->pixfmt.width *
gspca_dev->pixfmt.height * 2) {
- PDEBUG(D_PACK, "wrong sized frame");
+ gspca_dbg(gspca_dev, D_PACK, "wrong sized frame\n");
goto discard;
}
gspca_frame_add(gspca_dev, LAST_PACKET,
diff --git a/drivers/media/usb/gspca/ov534_9.c b/drivers/media/usb/gspca/ov534_9.c
index b2a92e518118..3d1364d2f83e 100644
--- a/drivers/media/usb/gspca/ov534_9.c
+++ b/drivers/media/usb/gspca/ov534_9.c
@@ -1133,7 +1133,7 @@ static void reg_w_i(struct gspca_dev *gspca_dev, u16 reg, u8 val)
static void reg_w(struct gspca_dev *gspca_dev, u16 reg, u8 val)
{
- PDEBUG(D_USBO, "reg_w [%04x] = %02x", reg, val);
+ gspca_dbg(gspca_dev, D_USBO, "reg_w [%04x] = %02x\n", reg, val);
reg_w_i(gspca_dev, reg, val);
}
@@ -1149,7 +1149,8 @@ static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg)
0x01,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- PDEBUG(D_USBI, "reg_r [%04x] -> %02x", reg, gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "reg_r [%04x] -> %02x\n",
+ reg, gspca_dev->usb_buf[0]);
if (ret < 0) {
pr_err("reg_r err %d\n", ret);
gspca_dev->usb_err = ret;
@@ -1174,9 +1175,9 @@ static int sccb_check_status(struct gspca_dev *gspca_dev)
case 0x03:
break;
default:
- PDEBUG(D_USBI|D_USBO,
- "sccb status 0x%02x, attempt %d/5",
- data, i + 1);
+ gspca_dbg(gspca_dev, D_USBI|D_USBO,
+ "sccb status 0x%02x, attempt %d/5\n",
+ data, i + 1);
}
}
return 0;
@@ -1184,7 +1185,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev)
static void sccb_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
{
- PDEBUG(D_USBO, "sccb_write [%02x] = %02x", reg, val);
+ gspca_dbg(gspca_dev, D_USBO, "sccb_write [%02x] = %02x\n", reg, val);
reg_w_i(gspca_dev, OV534_REG_SUBADDR, reg);
reg_w_i(gspca_dev, OV534_REG_WRITE, val);
reg_w_i(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
@@ -1238,7 +1239,7 @@ static void set_led(struct gspca_dev *gspca_dev, int status)
{
u8 data;
- PDEBUG(D_CONF, "led status: %d", status);
+ gspca_dbg(gspca_dev, D_CONF, "led status: %d\n", status);
data = reg_r(gspca_dev, 0x21);
data |= 0x80;
@@ -1423,7 +1424,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
sensor_id = sccb_read(gspca_dev, 0x0a) << 8;
sccb_read(gspca_dev, 0x0b);
sensor_id |= sccb_read(gspca_dev, 0x0b);
- PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor ID: %04x\n", sensor_id);
/* initialize */
if ((sensor_id & 0xfff0) == 0x9650) {
@@ -1651,19 +1652,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* Verify UVC header. Header length is always 12 */
if (data[0] != 12 || len < 12) {
- PDEBUG(D_PACK, "bad header");
+ gspca_dbg(gspca_dev, D_PACK, "bad header\n");
goto discard;
}
/* Check errors */
if (data[1] & UVC_STREAM_ERR) {
- PDEBUG(D_PACK, "payload error");
+ gspca_dbg(gspca_dev, D_PACK, "payload error\n");
goto discard;
}
/* Extract PTS and FID */
if (!(data[1] & UVC_STREAM_PTS)) {
- PDEBUG(D_PACK, "PTS not present");
+ gspca_dbg(gspca_dev, D_PACK, "PTS not present\n");
goto discard;
}
this_pts = (data[5] << 24) | (data[4] << 16)
diff --git a/drivers/media/usb/gspca/pac207.c b/drivers/media/usb/gspca/pac207.c
index 01c185d367e5..a1df7af8fef5 100644
--- a/drivers/media/usb/gspca/pac207.c
+++ b/drivers/media/usb/gspca/pac207.c
@@ -166,17 +166,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
idreg[1] = pac207_read_reg(gspca_dev, 0x0001);
idreg[0] = ((idreg[0] & 0x0f) << 4) | ((idreg[1] & 0xf0) >> 4);
idreg[1] = idreg[1] & 0x0f;
- PDEBUG(D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X",
- idreg[0], idreg[1]);
+ gspca_dbg(gspca_dev, D_PROBE, "Pixart Sensor ID 0x%02X Chips ID 0x%02X\n",
+ idreg[0], idreg[1]);
if (idreg[0] != 0x27) {
- PDEBUG(D_PROBE, "Error invalid sensor ID!");
+ gspca_dbg(gspca_dev, D_PROBE, "Error invalid sensor ID!\n");
return -ENODEV;
}
- PDEBUG(D_PROBE,
- "Pixart PAC207BCA Image Processor and Control Chip detected (vid/pid 0x%04X:0x%04X)",
- id->idVendor, id->idProduct);
+ gspca_dbg(gspca_dev, D_PROBE,
+ "Pixart PAC207BCA Image Processor and Control Chip detected (vid/pid 0x%04X:0x%04X)\n",
+ id->idVendor, id->idProduct);
cam = &gspca_dev->cam;
cam->cam_mode = sif_mode;
@@ -315,9 +315,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
mode = 0x02;
if (gspca_dev->pixfmt.width == 176) { /* 176x144 */
mode |= 0x01;
- PDEBUG(D_STREAM, "pac207_start mode 176x144");
+ gspca_dbg(gspca_dev, D_STREAM, "pac207_start mode 176x144\n");
} else { /* 352x288 */
- PDEBUG(D_STREAM, "pac207_start mode 352x288");
+ gspca_dbg(gspca_dev, D_STREAM, "pac207_start mode 352x288\n");
}
pac207_write_reg(gspca_dev, 0x41, mode);
diff --git a/drivers/media/usb/gspca/pac7302.c b/drivers/media/usb/gspca/pac7302.c
index 595535e143e6..b8ff201c7bb9 100644
--- a/drivers/media/usb/gspca/pac7302.c
+++ b/drivers/media/usb/gspca/pac7302.c
@@ -339,7 +339,7 @@ static void reg_w_var(struct gspca_dev *gspca_dev,
break;
default:
if (len > USB_BUF_SZ) {
- PERR("Incorrect variable sequence");
+ gspca_err(gspca_dev, "Incorrect variable sequence\n");
return;
}
while (len > 0) {
diff --git a/drivers/media/usb/gspca/pac7311.c b/drivers/media/usb/gspca/pac7311.c
index 8bac2d9326bf..44db4f4afa22 100644
--- a/drivers/media/usb/gspca/pac7311.c
+++ b/drivers/media/usb/gspca/pac7311.c
@@ -258,7 +258,7 @@ static void reg_w_var(struct gspca_dev *gspca_dev,
break;
default:
if (len > USB_BUF_SZ) {
- PERR("Incorrect variable sequence");
+ gspca_err(gspca_dev, "Incorrect variable sequence\n");
return;
}
while (len > 0) {
diff --git a/drivers/media/usb/gspca/pac_common.h b/drivers/media/usb/gspca/pac_common.h
index 4047bcb6c2b5..31f2a42af4dd 100644
--- a/drivers/media/usb/gspca/pac_common.h
+++ b/drivers/media/usb/gspca/pac_common.h
@@ -107,10 +107,9 @@ static unsigned char *pac_find_sof(struct gspca_dev *gspca_dev, u8 *sof_read,
switch (m[i]) {
case 0x96:
/* Pattern found */
- PDEBUG(D_FRAM,
- "SOF found, bytes to analyze: %u."
- " Frame starts at byte #%u",
- len, i + 1);
+ gspca_dbg(gspca_dev, D_FRAM,
+ "SOF found, bytes to analyze: %u - Frame starts at byte #%u\n",
+ len, i + 1);
*sof_read = 0;
return m + i + 1;
break;
diff --git a/drivers/media/usb/gspca/sn9c2028.c b/drivers/media/usb/gspca/sn9c2028.c
index 5d32dd359d84..a1f7189545e1 100644
--- a/drivers/media/usb/gspca/sn9c2028.c
+++ b/drivers/media/usb/gspca/sn9c2028.c
@@ -69,8 +69,9 @@ static int sn9c2028_command(struct gspca_dev *gspca_dev, u8 *command)
{
int rc;
- PDEBUG(D_USBO, "sending command %02x%02x%02x%02x%02x%02x", command[0],
- command[1], command[2], command[3], command[4], command[5]);
+ gspca_dbg(gspca_dev, D_USBO, "sending command %02x%02x%02x%02x%02x%02x\n",
+ command[0], command[1], command[2],
+ command[3], command[4], command[5]);
memcpy(gspca_dev->usb_buf, command, 6);
rc = usb_control_msg(gspca_dev->dev,
@@ -100,7 +101,8 @@ static int sn9c2028_read1(struct gspca_dev *gspca_dev)
pr_err("read1 error %d\n", rc);
return (rc < 0) ? rc : -EIO;
}
- PDEBUG(D_USBI, "read1 response %02x", gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "read1 response %02x\n",
+ gspca_dev->usb_buf[0]);
return gspca_dev->usb_buf[0];
}
@@ -117,8 +119,8 @@ static int sn9c2028_read4(struct gspca_dev *gspca_dev, u8 *reading)
return (rc < 0) ? rc : -EIO;
}
memcpy(reading, gspca_dev->usb_buf, 4);
- PDEBUG(D_USBI, "read4 response %02x%02x%02x%02x", reading[0],
- reading[1], reading[2], reading[3]);
+ gspca_dbg(gspca_dev, D_USBI, "read4 response %02x%02x%02x%02x\n",
+ reading[0], reading[1], reading[2], reading[3]);
return rc;
}
@@ -175,32 +177,32 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam = &gspca_dev->cam;
- PDEBUG(D_PROBE, "SN9C2028 camera detected (vid/pid 0x%04X:0x%04X)",
- id->idVendor, id->idProduct);
+ gspca_dbg(gspca_dev, D_PROBE, "SN9C2028 camera detected (vid/pid 0x%04X:0x%04X)\n",
+ id->idVendor, id->idProduct);
sd->model = id->idProduct;
switch (sd->model) {
case 0x7005:
- PDEBUG(D_PROBE, "Genius Smart 300 camera");
+ gspca_dbg(gspca_dev, D_PROBE, "Genius Smart 300 camera\n");
break;
case 0x7003:
- PDEBUG(D_PROBE, "Genius Videocam Live v2");
+ gspca_dbg(gspca_dev, D_PROBE, "Genius Videocam Live v2\n");
break;
case 0x8000:
- PDEBUG(D_PROBE, "DC31VC");
+ gspca_dbg(gspca_dev, D_PROBE, "DC31VC\n");
break;
case 0x8001:
- PDEBUG(D_PROBE, "Spy camera");
+ gspca_dbg(gspca_dev, D_PROBE, "Spy camera\n");
break;
case 0x8003:
- PDEBUG(D_PROBE, "CIF camera");
+ gspca_dbg(gspca_dev, D_PROBE, "CIF camera\n");
break;
case 0x8008:
- PDEBUG(D_PROBE, "Mini-Shotz ms-350 camera");
+ gspca_dbg(gspca_dev, D_PROBE, "Mini-Shotz ms-350 camera\n");
break;
case 0x800a:
- PDEBUG(D_PROBE, "Vivitar 3350b type camera");
+ gspca_dbg(gspca_dev, D_PROBE, "Vivitar 3350b type camera\n");
cam->input_flags = V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
break;
}
@@ -849,13 +851,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
result = sn9c2028_read1(gspca_dev);
if (result < 0)
- PERR("Camera Stop read failed");
+ gspca_err(gspca_dev, "Camera Stop read failed\n");
memset(data, 0, 6);
data[0] = 0x14;
result = sn9c2028_command(gspca_dev, data);
if (result < 0)
- PERR("Camera Stop command failed");
+ gspca_err(gspca_dev, "Camera Stop command failed\n");
}
static void do_autogain(struct gspca_dev *gspca_dev, int avg_lum)
diff --git a/drivers/media/usb/gspca/sn9c2028.h b/drivers/media/usb/gspca/sn9c2028.h
index 85761aa7c8b2..29f1571f9242 100644
--- a/drivers/media/usb/gspca/sn9c2028.h
+++ b/drivers/media/usb/gspca/sn9c2028.h
@@ -43,10 +43,9 @@ static unsigned char *sn9c2028_find_sof(struct gspca_dev *gspca_dev,
if (sd->sof_read == 12)
sd->avg_lum = (m[i] << 8) + sd->avg_lum_l;
if (sd->sof_read == sizeof(sn9c2028_sof_marker)) {
- PDEBUG(D_FRAM,
- "SOF found, bytes to analyze: %u."
- " Frame starts at byte #%u",
- len, i + 1);
+ gspca_dbg(gspca_dev, D_FRAM,
+ "SOF found, bytes to analyze: %u - Frame starts at byte #%u\n",
+ len, i + 1);
sd->sof_read = 0;
return m + i + 1;
}
diff --git a/drivers/media/usb/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c
index c605f78d6186..cfa2a04d9f3f 100644
--- a/drivers/media/usb/gspca/sn9c20x.c
+++ b/drivers/media/usb/gspca/sn9c20x.c
@@ -2153,7 +2153,7 @@ static void qual_upd(struct work_struct *work)
/* 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_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", qual);
gspca_dev->usb_err = 0;
set_quality(gspca_dev, qual);
mutex_unlock(&gspca_dev->usb_lock);
diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c
index 5eeaf16ac5e8..df8d8482b795 100644
--- a/drivers/media/usb/gspca/sonixj.c
+++ b/drivers/media/usb/gspca/sonixj.c
@@ -1155,7 +1155,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_err < 0)
return;
if (len > USB_BUF_SZ) {
- PERR("reg_r: buffer overflow\n");
+ gspca_err(gspca_dev, "reg_r: buffer overflow\n");
return;
}
@@ -1166,7 +1166,8 @@ static void reg_r(struct gspca_dev *gspca_dev,
value, 0,
gspca_dev->usb_buf, len,
500);
- PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "reg_r [%02x] -> %02x\n",
+ value, gspca_dev->usb_buf[0]);
if (ret < 0) {
pr_err("reg_r err %d\n", ret);
gspca_dev->usb_err = ret;
@@ -1181,7 +1182,7 @@ static void reg_w1(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
+ gspca_dbg(gspca_dev, D_USBO, "reg_w1 [%04x] = %02x\n", value, data);
gspca_dev->usb_buf[0] = data;
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -1205,11 +1206,11 @@ static void reg_w(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
- value, buffer[0], buffer[1]);
+ gspca_dbg(gspca_dev, D_USBO, "reg_w [%04x] = %02x %02x ..\n",
+ value, buffer[0], buffer[1]);
if (len > USB_BUF_SZ) {
- PERR("reg_w: buffer overflow\n");
+ gspca_err(gspca_dev, "reg_w: buffer overflow\n");
return;
}
@@ -1235,7 +1236,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
+ gspca_dbg(gspca_dev, D_USBO, "i2c_w1 [%02x] = %02x\n", reg, val);
switch (sd->sensor) {
case SENSOR_ADCM1700:
case SENSOR_OM6802:
@@ -1276,8 +1277,8 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
- buffer[2], buffer[3]);
+ gspca_dbg(gspca_dev, D_USBO, "i2c_w8 [%02x] = %02x ..\n",
+ buffer[2], buffer[3]);
memcpy(gspca_dev->usb_buf, buffer, 8);
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -1349,7 +1350,7 @@ static void hv7131r_probe(struct gspca_dev *gspca_dev)
if (gspca_dev->usb_buf[0] == 0x02 /* chip ID (02 is R) */
&& gspca_dev->usb_buf[1] == 0x09
&& gspca_dev->usb_buf[2] == 0x01) {
- PDEBUG(D_PROBE, "Sensor HV7131R found");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor HV7131R found\n");
return;
}
pr_warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x\n",
@@ -1396,18 +1397,19 @@ static void mi0360_probe(struct gspca_dev *gspca_dev)
return;
switch (val) {
case 0x8221:
- PDEBUG(D_PROBE, "Sensor mi0360b");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor mi0360b\n");
sd->sensor = SENSOR_MI0360B;
break;
case 0x823a:
- PDEBUG(D_PROBE, "Sensor mt9v111");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor mt9v111\n");
sd->sensor = SENSOR_MT9V111;
break;
case 0x8243:
- PDEBUG(D_PROBE, "Sensor mi0360");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor mi0360\n");
break;
default:
- PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
+ gspca_dbg(gspca_dev, D_PROBE, "Unknown sensor %04x - forced to mi0360\n",
+ val);
break;
}
}
@@ -1432,10 +1434,10 @@ static void ov7630_probe(struct gspca_dev *gspca_dev)
/*fixme: only valid for 0c45:613e?*/
gspca_dev->cam.input_flags =
V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
- PDEBUG(D_PROBE, "Sensor soi768");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor soi768\n");
return;
}
- PDEBUG(D_PROBE, "Sensor ov%04x", val);
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor ov%04x\n", val);
}
static void ov7648_probe(struct gspca_dev *gspca_dev)
@@ -1452,7 +1454,7 @@ static void ov7648_probe(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x01, 0x29);
reg_w1(gspca_dev, 0x17, 0x42);
if ((val & 0xff00) == 0x7600) { /* ov76xx */
- PDEBUG(D_PROBE, "Sensor ov%04x", val);
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor ov%04x\n", val);
return;
}
@@ -1467,7 +1469,7 @@ static void ov7648_probe(struct gspca_dev *gspca_dev)
if (gspca_dev->usb_err < 0)
return;
if (val == 0x1030) { /* po1030 */
- PDEBUG(D_PROBE, "Sensor po1030");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor po1030\n");
sd->sensor = SENSOR_PO1030;
return;
}
@@ -1490,7 +1492,7 @@ static void po2030n_probe(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x01, 0x29); /* reset */
reg_w1(gspca_dev, 0x17, 0x42);
if (val == 0x99) { /* gc0307 (?) */
- PDEBUG(D_PROBE, "Sensor gc0307");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor gc0307\n");
sd->sensor = SENSOR_GC0307;
return;
}
@@ -1506,7 +1508,7 @@ static void po2030n_probe(struct gspca_dev *gspca_dev)
if (gspca_dev->usb_err < 0)
return;
if (val == 0x2030) {
- PDEBUG(D_PROBE, "Sensor po2030n");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor po2030n\n");
/* sd->sensor = SENSOR_PO2030N; */
} else {
pr_err("Unknown sensor ID %04x\n", val);
@@ -1558,7 +1560,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
regF1 = gspca_dev->usb_buf[0];
if (gspca_dev->usb_err < 0)
return gspca_dev->usb_err;
- PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
+ gspca_dbg(gspca_dev, D_PROBE, "Sonix chip id: %02x\n", regF1);
if (gspca_dev->audio)
regGpio[1] |= 0x04; /* with audio */
switch (sd->bridge) {
@@ -1758,10 +1760,10 @@ static u32 expo_adjust(struct gspca_dev *gspca_dev,
| ((expo & 0x0003) << 4);
i2c_w8(gspca_dev, expoMo10);
i2c_w8(gspca_dev, gainMo);
- PDEBUG(D_FRAM, "set exposure %d",
- ((expoMo10[3] & 0x07) << 10)
- | (expoMof[3] << 2)
- | ((expoMo10[3] & 0x30) >> 4));
+ gspca_dbg(gspca_dev, D_FRAM, "set exposure %d\n",
+ ((expoMo10[3] & 0x07) << 10)
+ | (expoMof[3] << 2)
+ | ((expoMo10[3] & 0x30) >> 4));
break;
}
case SENSOR_MT9V111: {
@@ -1789,7 +1791,7 @@ static u32 expo_adjust(struct gspca_dev *gspca_dev,
gainOm[3] = expo >> 2;
i2c_w8(gspca_dev, gainOm);
reg_w1(gspca_dev, 0x96, expo >> 5);
- PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
+ gspca_dbg(gspca_dev, D_FRAM, "set exposure %d\n", gainOm[3]);
break;
}
}
@@ -2162,7 +2164,7 @@ static void qual_upd(struct work_struct *work)
/* 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_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", sd->quality);
gspca_dev->usb_err = 0;
setjpegqual(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
@@ -2584,7 +2586,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
sd->ag_cnt = AG_CNT_START;
delta = atomic_read(&sd->avg_lum);
- PDEBUG(D_FRAM, "mean lum %d", delta);
+ gspca_dbg(gspca_dev, D_FRAM, "mean lum %d\n", delta);
if (sd->sensor == SENSOR_PO2030N) {
gspca_expo_autogain(gspca_dev, delta, luma_mean, luma_delta,
diff --git a/drivers/media/usb/gspca/spca1528.c b/drivers/media/usb/gspca/spca1528.c
index 327ec901abe1..d25924e430f3 100644
--- a/drivers/media/usb/gspca/spca1528.c
+++ b/drivers/media/usb/gspca/spca1528.c
@@ -75,8 +75,8 @@ static void reg_r(struct gspca_dev *gspca_dev,
index,
gspca_dev->usb_buf, len,
500);
- PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", req, index,
- gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "GET %02x 0000 %04x %02x\n", req, index,
+ gspca_dev->usb_buf[0]);
if (ret < 0) {
pr_err("reg_r err %d\n", ret);
gspca_dev->usb_err = ret;
@@ -93,7 +93,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index);
+ gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n", req, value, index);
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -116,7 +116,8 @@ static void reg_wb(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_USBO, "SET %02x %04x %04x %02x", req, value, index, byte);
+ gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x %02x\n",
+ req, value, index, byte);
gspca_dev->usb_buf[0] = byte;
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
req,
@@ -142,7 +143,7 @@ static void wait_status_0(struct gspca_dev *gspca_dev)
w += 15;
msleep(w);
} while (--i > 0);
- PERR("wait_status_0 timeout");
+ gspca_err(gspca_dev, "wait_status_0 timeout\n");
gspca_dev->usb_err = -ETIME;
}
@@ -160,7 +161,7 @@ static void wait_status_1(struct gspca_dev *gspca_dev)
return;
}
} while (--i > 0);
- PERR("wait_status_1 timeout");
+ gspca_err(gspca_dev, "wait_status_1 timeout\n");
gspca_dev->usb_err = -ETIME;
}
@@ -216,8 +217,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
reg_r(gspca_dev, 0x20, 0x0000, 1);
reg_r(gspca_dev, 0x20, 0x0000, 5);
reg_r(gspca_dev, 0x23, 0x0000, 64);
- PDEBUG(D_PROBE, "%s%s", &gspca_dev->usb_buf[0x1c],
- &gspca_dev->usb_buf[0x30]);
+ gspca_dbg(gspca_dev, D_PROBE, "%s%s\n", &gspca_dev->usb_buf[0x1c],
+ &gspca_dev->usb_buf[0x30]);
reg_r(gspca_dev, 0x23, 0x0001, 64);
return gspca_dev->usb_err;
}
diff --git a/drivers/media/usb/gspca/spca500.c b/drivers/media/usb/gspca/spca500.c
index da2d9027914c..e90d2f3b4a67 100644
--- a/drivers/media/usb/gspca/spca500.c
+++ b/drivers/media/usb/gspca/spca500.c
@@ -328,7 +328,8 @@ static int reg_w(struct gspca_dev *gspca_dev,
{
int ret;
- PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
+ gspca_dbg(gspca_dev, D_USBO, "reg write: [0x%02x] = 0x%02x\n",
+ index, value);
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
req,
@@ -423,15 +424,15 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
static void spca500_ping310(struct gspca_dev *gspca_dev)
{
reg_r(gspca_dev, 0x0d04, 2);
- PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+ gspca_dbg(gspca_dev, D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x\n",
+ gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
}
static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
{
reg_r(gspca_dev, 0x0d05, 2);
- PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+ gspca_dbg(gspca_dev, D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x\n",
+ gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
spca500_ping310(gspca_dev);
@@ -485,7 +486,7 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev)
return err;
err = reg_r_wait(gspca_dev, 0x06, 0, 0);
if (err < 0) {
- PERR("reg_r_wait() failed");
+ gspca_err(gspca_dev, "reg_r_wait() failed\n");
return err;
}
/* all ok */
@@ -501,7 +502,7 @@ static int spca500_full_reset(struct gspca_dev *gspca_dev)
static int spca500_synch310(struct gspca_dev *gspca_dev)
{
if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
- PERR("Set packet size: set interface error");
+ gspca_err(gspca_dev, "Set packet size: set interface error\n");
goto error;
}
spca500_ping310(gspca_dev);
@@ -509,13 +510,14 @@ static int spca500_synch310(struct gspca_dev *gspca_dev)
reg_r(gspca_dev, 0x0d00, 1);
/* need alt setting here */
- PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
+ gspca_dbg(gspca_dev, D_PACK, "ClickSmart310 sync alt: %d\n",
+ gspca_dev->alt);
/* Windoze use pipe with altsetting 6 why 7 here */
if (usb_set_interface(gspca_dev->dev,
gspca_dev->iface,
gspca_dev->alt) < 0) {
- PERR("Set packet size: set interface error");
+ gspca_err(gspca_dev, "Set packet size: set interface error\n");
goto error;
}
return 0;
@@ -540,7 +542,7 @@ static void spca500_reinit(struct gspca_dev *gspca_dev)
err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
qtable_pocketdv);
if (err < 0)
- PERR("spca50x_setup_qtable failed on init");
+ gspca_err(gspca_dev, "spca50x_setup_qtable failed on init\n");
/* set qtable index */
reg_w(gspca_dev, 0x00, 0x8880, 2);
@@ -587,12 +589,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
/* initialisation of spca500 based cameras is deferred */
- PDEBUG(D_STREAM, "SPCA500 init");
+ gspca_dbg(gspca_dev, D_STREAM, "SPCA500 init\n");
if (sd->subtype == LogitechClickSmart310)
spca500_clksmart310_init(gspca_dev);
/* else
spca500_initialise(gspca_dev); */
- PDEBUG(D_STREAM, "SPCA500 init done");
+ gspca_dbg(gspca_dev, D_STREAM, "SPCA500 init done\n");
return 0;
}
@@ -619,10 +621,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* is there a sensor here ? */
reg_r(gspca_dev, 0x8a04, 1);
- PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
- gspca_dev->usb_buf[0]);
- PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
- gspca_dev->curr_mode, xmult, ymult);
+ gspca_dbg(gspca_dev, D_STREAM, "Spca500 Sensor Address 0x%02x\n",
+ gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
+ gspca_dev->curr_mode, xmult, ymult);
/* setup qtable */
switch (sd->subtype) {
@@ -636,7 +638,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
0x00, 0x8800, 0x8840,
qtable_creative_pccam);
if (err < 0)
- PERR("spca50x_setup_qtable failed");
+ gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
/* Init SDRAM - needed for SDRAM access */
reg_w(gspca_dev, 0x00, 0x870a, 0x04);
@@ -644,7 +646,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
msleep(500);
if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
- PERR("reg_r_wait() failed");
+ gspca_err(gspca_dev, "reg_r_wait() failed\n");
reg_r(gspca_dev, 0x816b, 1);
Data = gspca_dev->usb_buf[0];
@@ -657,13 +659,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* enable drop packet */
err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
if (err < 0)
- PERR("failed to enable drop packet");
+ gspca_err(gspca_dev, "failed to enable drop packet\n");
reg_w(gspca_dev, 0x00, 0x8880, 3);
err = spca50x_setup_qtable(gspca_dev,
0x00, 0x8800, 0x8840,
qtable_creative_pccam);
if (err < 0)
- PERR("spca50x_setup_qtable failed");
+ gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
/* Init SDRAM - needed for SDRAM access */
reg_w(gspca_dev, 0x00, 0x870a, 0x04);
@@ -672,7 +674,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
- PERR("reg_r_wait() failed");
+ gspca_err(gspca_dev, "reg_r_wait() failed\n");
reg_r(gspca_dev, 0x816b, 1);
Data = gspca_dev->usb_buf[0];
@@ -686,18 +688,18 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* do a full reset */
err = spca500_full_reset(gspca_dev);
if (err < 0)
- PERR("spca500_full_reset failed");
+ gspca_err(gspca_dev, "spca500_full_reset failed\n");
/* enable drop packet */
err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
if (err < 0)
- PERR("failed to enable drop packet");
+ gspca_err(gspca_dev, "failed to enable drop packet\n");
reg_w(gspca_dev, 0x00, 0x8880, 3);
err = spca50x_setup_qtable(gspca_dev,
0x00, 0x8800, 0x8840,
qtable_creative_pccam);
if (err < 0)
- PERR("spca50x_setup_qtable failed");
+ gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
spca500_setmode(gspca_dev, xmult, ymult);
reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
@@ -706,7 +708,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
- PERR("reg_r_wait() failed");
+ gspca_err(gspca_dev, "reg_r_wait() failed\n");
reg_r(gspca_dev, 0x816b, 1);
Data = gspca_dev->usb_buf[0];
@@ -719,7 +721,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* do a full reset */
err = spca500_full_reset(gspca_dev);
if (err < 0)
- PERR("spca500_full_reset failed");
+ gspca_err(gspca_dev, "spca500_full_reset failed\n");
/* enable drop packet */
reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
reg_w(gspca_dev, 0x00, 0x8880, 0);
@@ -727,7 +729,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
0x00, 0x8800, 0x8840,
qtable_kodak_ez200);
if (err < 0)
- PERR("spca50x_setup_qtable failed");
+ gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
spca500_setmode(gspca_dev, xmult, ymult);
reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
@@ -736,7 +738,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
- PERR("reg_r_wait() failed");
+ gspca_err(gspca_dev, "reg_r_wait() failed\n");
reg_r(gspca_dev, 0x816b, 1);
Data = gspca_dev->usb_buf[0];
@@ -762,7 +764,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
err = spca50x_setup_qtable(gspca_dev,
0x00, 0x8800, 0x8840, qtable_pocketdv);
if (err < 0)
- PERR("spca50x_setup_qtable failed");
+ gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
reg_w(gspca_dev, 0x00, 0x8880, 2);
/* familycam Quicksmart pocketDV stuff */
@@ -792,7 +794,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
0x00, 0x8800,
0x8840, qtable_creative_pccam);
if (err < 0)
- PERR("spca50x_setup_qtable failed");
+ gspca_err(gspca_dev, "spca50x_setup_qtable failed\n");
reg_w(gspca_dev, 0x00, 0x8880, 3);
reg_w(gspca_dev, 0x00, 0x800a, 0x00);
/* Init SDRAM - needed for SDRAM access */
@@ -820,8 +822,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
/* switch to video camera mode */
reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
reg_r(gspca_dev, 0x8000, 1);
- PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
- gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_STREAM, "stop SPCA500 done reg8000: 0x%2x\n",
+ gspca_dev->usb_buf[0]);
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
diff --git a/drivers/media/usb/gspca/spca501.c b/drivers/media/usb/gspca/spca501.c
index ae5a80987553..2cce74b166d8 100644
--- a/drivers/media/usb/gspca/spca501.c
+++ b/drivers/media/usb/gspca/spca501.c
@@ -1763,8 +1763,8 @@ static int reg_write(struct gspca_dev *gspca_dev,
req,
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500);
- PDEBUG(D_USBO, "reg write: 0x%02x 0x%02x 0x%02x",
- req, index, value);
+ gspca_dbg(gspca_dev, D_USBO, "reg write: 0x%02x 0x%02x 0x%02x\n",
+ req, index, value);
if (ret < 0)
pr_err("reg write: error %d\n", ret);
return ret;
@@ -1779,8 +1779,8 @@ static int write_vector(struct gspca_dev *gspca_dev, const __u16 data[][3])
ret = reg_write(gspca_dev, data[i][0], data[i][2],
data[i][1]);
if (ret < 0) {
- PERR("Reg write failed for 0x%02x,0x%02x,0x%02x",
- data[i][0], data[i][1], data[i][2]);
+ gspca_err(gspca_dev, "Reg write failed for 0x%02x,0x%02x,0x%02x\n",
+ data[i][0], data[i][1], data[i][2]);
return ret;
}
i++;
@@ -1852,7 +1852,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
goto error;
break;
}
- PDEBUG(D_STREAM, "Initializing SPCA501 finished");
+ gspca_dbg(gspca_dev, D_STREAM, "Initializing SPCA501 finished\n");
return 0;
error:
return -EINVAL;
diff --git a/drivers/media/usb/gspca/spca505.c b/drivers/media/usb/gspca/spca505.c
index 1553cc766c04..07aae9cd5a30 100644
--- a/drivers/media/usb/gspca/spca505.c
+++ b/drivers/media/usb/gspca/spca505.c
@@ -551,8 +551,8 @@ static int reg_write(struct gspca_dev *gspca_dev,
req,
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500);
- PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
- req, index, value, ret);
+ gspca_dbg(gspca_dev, D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d\n",
+ req, index, value, ret);
if (ret < 0)
pr_err("reg write: error %d\n", ret);
return ret;
@@ -650,7 +650,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
ret = reg_read(gspca_dev, 0x06, 0x16);
if (ret < 0) {
- PERR("register read failed err: %d", ret);
+ gspca_err(gspca_dev, "register read failed err: %d\n", ret);
return ret;
}
if (ret != 0x0101) {
diff --git a/drivers/media/usb/gspca/spca506.c b/drivers/media/usb/gspca/spca506.c
index 843c93f5acf3..6332b3f0b918 100644
--- a/drivers/media/usb/gspca/spca506.c
+++ b/drivers/media/usb/gspca/spca506.c
@@ -126,7 +126,7 @@ static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
__u8 setbit1 = 0x00;
__u8 videomask = 0x00;
- PDEBUG(D_STREAM, "** Open Set Norme **");
+ gspca_dbg(gspca_dev, D_STREAM, "** Open Set Norme **\n");
spca506_Initi2c(gspca_dev);
/* NTSC bit0 -> 1(525 l) PAL SECAM bit0 -> 0 (625 l) */
/* Composite channel bit1 -> 1 S-video bit 1 -> 0 */
@@ -153,8 +153,9 @@ static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
sd->norme = norme;
sd->channel = channel;
- PDEBUG(D_STREAM, "Set Video Byte to 0x%2x", videomask);
- PDEBUG(D_STREAM, "Set Norme: %08x Channel %d", norme, channel);
+ gspca_dbg(gspca_dev, D_STREAM, "Set Video Byte to 0x%2x\n", videomask);
+ gspca_dbg(gspca_dev, D_STREAM, "Set Norme: %08x Channel %d",
+ norme, channel);
}
static void spca506_GetNormeInput(struct gspca_dev *gspca_dev,
@@ -166,7 +167,8 @@ static void spca506_GetNormeInput(struct gspca_dev *gspca_dev,
we use your own copy in spca50x struct */
*norme = sd->norme;
*channel = sd->channel;
- PDEBUG(D_STREAM, "Get Norme: %d Channel %d", *norme, *channel);
+ gspca_dbg(gspca_dev, D_STREAM, "Get Norme: %d Channel %d\n",
+ *norme, *channel);
}
static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code,
@@ -174,7 +176,7 @@ static void spca506_Setsize(struct gspca_dev *gspca_dev, __u16 code,
{
struct usb_device *dev = gspca_dev->dev;
- PDEBUG(D_STREAM, "** SetSize **");
+ gspca_dbg(gspca_dev, D_STREAM, "** SetSize **\n");
reg_w(dev, 0x04, (0x18 | (code & 0x07)), 0x0000);
/* Soft snap 0x40 Hard 0x41 */
reg_w(dev, 0x04, 0x41, 0x0001);
@@ -317,7 +319,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x00, 0x60);
spca506_WriteI2c(gspca_dev, 0x05, 0x61);
spca506_WriteI2c(gspca_dev, 0x9f, 0x62);
- PDEBUG(D_STREAM, "** Close Init *");
+ gspca_dbg(gspca_dev, D_STREAM, "** Close Init *\n");
return 0;
}
@@ -445,7 +447,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(dev, 0x02, 0x01, 0x0000);
reg_w(dev, 0x03, 0x12, 0x0000);
reg_r(gspca_dev, 0x04, 0x0001, 2);
- PDEBUG(D_STREAM, "webcam started");
+ gspca_dbg(gspca_dev, D_STREAM, "webcam started\n");
spca506_GetNormeInput(gspca_dev, &norme, &channel);
spca506_SetNormeInput(gspca_dev, norme, channel);
return 0;
diff --git a/drivers/media/usb/gspca/spca508.c b/drivers/media/usb/gspca/spca508.c
index 1e0ba6b24e21..d80fd397eaf2 100644
--- a/drivers/media/usb/gspca/spca508.c
+++ b/drivers/media/usb/gspca/spca508.c
@@ -1247,8 +1247,8 @@ static int reg_write(struct gspca_dev *gspca_dev, u16 index, u16 value)
0, /* request */
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500);
- PDEBUG(D_USBO, "reg write i:0x%04x = 0x%02x",
- index, value);
+ gspca_dbg(gspca_dev, D_USBO, "reg write i:0x%04x = 0x%02x\n",
+ index, value);
if (ret < 0)
pr_err("reg write: error %d\n", ret);
return ret;
@@ -1269,8 +1269,8 @@ static int reg_read(struct gspca_dev *gspca_dev,
index,
gspca_dev->usb_buf, 1,
500); /* timeout */
- PDEBUG(D_USBI, "reg read i:%04x --> %02x",
- index, gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "reg read i:%04x --> %02x\n",
+ index, gspca_dev->usb_buf[0]);
if (ret < 0) {
pr_err("reg_read err %d\n", ret);
return ret;
@@ -1309,7 +1309,8 @@ static int ssi_w(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_buf[0] == 0)
break;
if (--retry <= 0) {
- PERR("ssi_w busy %02x", gspca_dev->usb_buf[0]);
+ gspca_err(gspca_dev, "ssi_w busy %02x\n",
+ gspca_dev->usb_buf[0]);
ret = -1;
break;
}
@@ -1365,14 +1366,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
* is a 508. */
data1 = reg_read(gspca_dev, 0x8104);
data2 = reg_read(gspca_dev, 0x8105);
- PDEBUG(D_PROBE, "Webcam Vendor ID: 0x%02x%02x", data2, data1);
+ gspca_dbg(gspca_dev, D_PROBE, "Webcam Vendor ID: 0x%02x%02x\n",
+ data2, data1);
data1 = reg_read(gspca_dev, 0x8106);
data2 = reg_read(gspca_dev, 0x8107);
- PDEBUG(D_PROBE, "Webcam Product ID: 0x%02x%02x", data2, data1);
+ gspca_dbg(gspca_dev, D_PROBE, "Webcam Product ID: 0x%02x%02x\n",
+ data2, data1);
data1 = reg_read(gspca_dev, 0x8621);
- PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
+ gspca_dbg(gspca_dev, D_PROBE, "Window 1 average luminance: %d\n",
+ data1);
cam = &gspca_dev->cam;
cam->cam_mode = sif_mode;
diff --git a/drivers/media/usb/gspca/spca561.c b/drivers/media/usb/gspca/spca561.c
index 4ff704cf9ed6..f389a8d0937d 100644
--- a/drivers/media/usb/gspca/spca561.c
+++ b/drivers/media/usb/gspca/spca561.c
@@ -290,7 +290,8 @@ static void reg_w_val(struct gspca_dev *gspca_dev, __u16 index, __u8 value)
0, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500);
- PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
+ gspca_dbg(gspca_dev, D_USBO, "reg write: 0x%02x:0x%02x\n",
+ index, value);
if (ret < 0)
pr_err("reg write: error %d\n", ret);
}
@@ -420,7 +421,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
data2 = gspca_dev->usb_buf[0];
product = (data2 << 8) | data1;
if (vendor != id->idVendor || product != id->idProduct) {
- PDEBUG(D_PROBE, "Bad vendor / product from device");
+ gspca_dbg(gspca_dev, D_PROBE, "Bad vendor / product from device\n");
return -EINVAL;
}
@@ -442,13 +443,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init_12a(struct gspca_dev *gspca_dev)
{
- PDEBUG(D_STREAM, "Chip revision: 012a");
+ gspca_dbg(gspca_dev, D_STREAM, "Chip revision: 012a\n");
init_161rev12A(gspca_dev);
return 0;
}
static int sd_init_72a(struct gspca_dev *gspca_dev)
{
- PDEBUG(D_STREAM, "Chip revision: 072a");
+ gspca_dbg(gspca_dev, D_STREAM, "Chip revision: 072a\n");
write_vector(gspca_dev, rev72a_reset);
msleep(200);
write_vector(gspca_dev, rev72a_init_data1);
@@ -679,25 +680,16 @@ static void do_autogain(struct gspca_dev *gspca_dev)
y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
/* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
/* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
- /* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
if (y < luma_mean - luma_delta ||
y > luma_mean + luma_delta) {
expotimes = i2c_read(gspca_dev, 0x09, 0x10);
pixelclk = 0x0800;
expotimes = expotimes & 0x07ff;
- /* PDEBUG(D_PACK,
- "Exposition Times 0x%03X Clock 0x%04X ",
- expotimes,pixelclk); */
gainG = i2c_read(gspca_dev, 0x35, 0x10);
- /* PDEBUG(D_PACK,
- "reading Gain register %d", gainG); */
expotimes += (luma_mean - y) >> spring;
gainG += (luma_mean - y) / 50;
- /* PDEBUG(D_PACK,
- "compute expotimes %d gain %d",
- expotimes,gainG); */
if (gainG > 0x3f)
gainG = 0x3f;
@@ -728,7 +720,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* This should never happen */
if (len < 2) {
- PERR("Short SOF packet, ignoring");
+ gspca_err(gspca_dev, "Short SOF packet, ignoring\n\n\n\n\n");
gspca_dev->last_packet_type = DISCARD_PACKET;
return;
}
diff --git a/drivers/media/usb/gspca/sq905.c b/drivers/media/usb/gspca/sq905.c
index f1da34a10ce8..cc8ff41b8ab3 100644
--- a/drivers/media/usb/gspca/sq905.c
+++ b/drivers/media/usb/gspca/sq905.c
@@ -246,9 +246,9 @@ static void sq905_dostream(struct work_struct *work)
ret = sq905_read_data(gspca_dev, buffer, data_len, 1);
if (ret < 0)
goto quit_stream;
- PDEBUG(D_PACK,
- "Got %d bytes out of %d for frame",
- data_len, bytes_left);
+ gspca_dbg(gspca_dev, D_PACK,
+ "Got %d bytes out of %d for frame\n",
+ data_len, bytes_left);
bytes_left -= data_len;
data = buffer;
if (!header_read) {
@@ -345,7 +345,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
ret = sq905_command(gspca_dev, SQ905_CLEAR);
if (ret < 0)
return ret;
- PDEBUG(D_CONF, "SQ905 camera ID %08x detected", ident);
+ gspca_dbg(gspca_dev, D_CONF, "SQ905 camera ID %08x detected\n", ident);
gspca_dev->cam.cam_mode = sq905_mode;
gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode);
if (!(ident & SQ905_HIRES_MASK))
@@ -369,20 +369,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
switch (gspca_dev->curr_mode) {
default:
/* case 2: */
- PDEBUG(D_STREAM, "Start streaming at high resolution");
+ gspca_dbg(gspca_dev, D_STREAM, "Start streaming at high resolution\n");
ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_HIGH);
break;
case 1:
- PDEBUG(D_STREAM, "Start streaming at medium resolution");
+ gspca_dbg(gspca_dev, D_STREAM, "Start streaming at medium resolution\n");
ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED);
break;
case 0:
- PDEBUG(D_STREAM, "Start streaming at low resolution");
+ gspca_dbg(gspca_dev, D_STREAM, "Start streaming at low resolution\n");
ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_LOW);
}
if (ret < 0) {
- PERR("Start streaming command failed");
+ gspca_err(gspca_dev, "Start streaming command failed\n");
return ret;
}
/* Start the workqueue function to do the streaming */
diff --git a/drivers/media/usb/gspca/sq905c.c b/drivers/media/usb/gspca/sq905c.c
index 8b4e4948a0cb..5e1269eb7c50 100644
--- a/drivers/media/usb/gspca/sq905c.c
+++ b/drivers/media/usb/gspca/sq905c.c
@@ -154,15 +154,16 @@ static void sq905c_dostream(struct work_struct *work)
usb_rcvbulkpipe(gspca_dev->dev, 0x81),
buffer, FRAME_HEADER_LEN, &act_len,
SQ905C_DATA_TIMEOUT);
- PDEBUG(D_STREAM,
- "Got %d bytes out of %d for header",
- act_len, FRAME_HEADER_LEN);
+ gspca_dbg(gspca_dev, D_STREAM,
+ "Got %d bytes out of %d for header\n",
+ act_len, FRAME_HEADER_LEN);
if (ret < 0 || act_len < FRAME_HEADER_LEN)
goto quit_stream;
/* size is read from 4 bytes starting 0x40, little endian */
bytes_left = buffer[0x40]|(buffer[0x41]<<8)|(buffer[0x42]<<16)
|(buffer[0x43]<<24);
- PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left);
+ gspca_dbg(gspca_dev, D_STREAM, "bytes_left = 0x%x\n",
+ bytes_left);
/* We keep the header. It has other information, too. */
packet_type = FIRST_PACKET;
gspca_frame_add(gspca_dev, packet_type,
@@ -176,9 +177,9 @@ static void sq905c_dostream(struct work_struct *work)
SQ905C_DATA_TIMEOUT);
if (ret < 0 || act_len < data_len)
goto quit_stream;
- PDEBUG(D_STREAM,
- "Got %d bytes out of %d for frame",
- data_len, bytes_left);
+ gspca_dbg(gspca_dev, D_STREAM,
+ "Got %d bytes out of %d for frame\n",
+ data_len, bytes_left);
bytes_left -= data_len;
if (bytes_left == 0)
packet_type = LAST_PACKET;
@@ -205,25 +206,25 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *dev = (struct sd *) gspca_dev;
int ret;
- PDEBUG(D_PROBE,
- "SQ9050 camera detected (vid/pid 0x%04X:0x%04X)",
- id->idVendor, id->idProduct);
+ gspca_dbg(gspca_dev, D_PROBE,
+ "SQ9050 camera detected (vid/pid 0x%04X:0x%04X)\n",
+ id->idVendor, id->idProduct);
ret = sq905c_command(gspca_dev, SQ905C_GET_ID, 0);
if (ret < 0) {
- PERR("Get version command failed");
+ gspca_err(gspca_dev, "Get version command failed\n");
return ret;
}
ret = sq905c_read(gspca_dev, 0xf5, 0, 20);
if (ret < 0) {
- PERR("Reading version command failed");
+ gspca_err(gspca_dev, "Reading version command failed\n");
return ret;
}
/* Note we leave out the usb id and the manufacturing date */
- PDEBUG(D_PROBE,
- "SQ9050 ID string: %02x - %*ph",
- gspca_dev->usb_buf[3], 6, gspca_dev->usb_buf + 14);
+ gspca_dbg(gspca_dev, D_PROBE,
+ "SQ9050 ID string: %02x - %*ph\n",
+ gspca_dev->usb_buf[3], 6, gspca_dev->usb_buf + 14);
cam->cam_mode = sq905c_mode;
cam->nmodes = 2;
@@ -267,19 +268,19 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* "Open the shutter" and set size, to start capture */
switch (gspca_dev->pixfmt.width) {
case 640:
- PDEBUG(D_STREAM, "Start streaming at high resolution");
+ gspca_dbg(gspca_dev, D_STREAM, "Start streaming at high resolution\n");
dev->cap_mode++;
ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_HI,
SQ905C_CAPTURE_INDEX);
break;
default: /* 320 */
- PDEBUG(D_STREAM, "Start streaming at medium resolution");
+ gspca_dbg(gspca_dev, D_STREAM, "Start streaming at medium resolution\n");
ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_MED,
SQ905C_CAPTURE_INDEX);
}
if (ret < 0) {
- PERR("Start streaming command failed");
+ gspca_err(gspca_dev, "Start streaming command failed\n");
return ret;
}
/* Start the workqueue function to do the streaming */
diff --git a/drivers/media/usb/gspca/sq930x.c b/drivers/media/usb/gspca/sq930x.c
index aa9a9411b801..d7cbcf2b3947 100644
--- a/drivers/media/usb/gspca/sq930x.c
+++ b/drivers/media/usb/gspca/sq930x.c
@@ -443,7 +443,7 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_USBO, "reg_w v: %04x i: %04x", value, index);
+ gspca_dbg(gspca_dev, D_USBO, "reg_w v: %04x i: %04x\n", value, index);
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
0x0c, /* request */
@@ -464,8 +464,8 @@ static void reg_wb(struct gspca_dev *gspca_dev, u16 value, u16 index,
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_USBO, "reg_wb v: %04x i: %04x %02x...%02x",
- value, index, *data, data[len - 1]);
+ gspca_dbg(gspca_dev, D_USBO, "reg_wb v: %04x i: %04x %02x...%02x\n",
+ value, index, *data, data[len - 1]);
memcpy(gspca_dev->usb_buf, data, len);
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -510,8 +510,8 @@ static void i2c_write(struct sd *sd,
*buf++ = cmd->val;
}
- PDEBUG(D_USBO, "i2c_w v: %04x i: %04x %02x...%02x",
- val, idx, gspca_dev->usb_buf[0], buf[-1]);
+ gspca_dbg(gspca_dev, D_USBO, "i2c_w v: %04x i: %04x %02x...%02x\n",
+ val, idx, gspca_dev->usb_buf[0], buf[-1]);
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
0x0c, /* request */
@@ -538,7 +538,7 @@ static void ucbus_write(struct gspca_dev *gspca_dev,
return;
if ((batchsize - 1) * 3 > USB_BUF_SZ) {
- PERR("Bug: usb_buf overflow\n");
+ gspca_err(gspca_dev, "Bug: usb_buf overflow\n");
gspca_dev->usb_err = -ENOMEM;
return;
}
@@ -560,12 +560,12 @@ static void ucbus_write(struct gspca_dev *gspca_dev,
*buf++ = cmd->bw_data;
}
if (buf != gspca_dev->usb_buf)
- PDEBUG(D_USBO, "ucbus v: %04x i: %04x %02x...%02x",
- val, idx,
- gspca_dev->usb_buf[0], buf[-1]);
+ gspca_dbg(gspca_dev, D_USBO, "ucbus v: %04x i: %04x %02x...%02x\n",
+ val, idx,
+ gspca_dev->usb_buf[0], buf[-1]);
else
- PDEBUG(D_USBO, "ucbus v: %04x i: %04x",
- val, idx);
+ gspca_dbg(gspca_dev, D_USBO, "ucbus v: %04x i: %04x\n",
+ val, idx);
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
0x0c, /* request */
@@ -691,7 +691,7 @@ static void mt9v111_init(struct gspca_dev *gspca_dev)
|| gspca_dev->usb_err != 0)
break;
if (--nwait < 0) {
- PDEBUG(D_PROBE, "mt9v111_init timeout");
+ gspca_dbg(gspca_dev, D_PROBE, "mt9v111_init timeout\n");
gspca_dev->usb_err = -ETIME;
return;
}
@@ -857,7 +857,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: %*ph", 8, gspca_dev->usb_buf);
+ gspca_dbg(gspca_dev, D_PROBE, "info: %*ph\n", 8, gspca_dev->usb_buf);
bridge_init(sd);
@@ -870,7 +870,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
cmos_probe(gspca_dev);
}
if (gspca_dev->usb_err >= 0) {
- PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name);
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor %s\n",
+ sensor_tb[sd->sensor].name);
global_init(sd, 1);
}
return gspca_dev->usb_err;
diff --git a/drivers/media/usb/gspca/stk014.c b/drivers/media/usb/gspca/stk014.c
index daf45db6c404..0d8f489ddef2 100644
--- a/drivers/media/usb/gspca/stk014.c
+++ b/drivers/media/usb/gspca/stk014.c
@@ -290,8 +290,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
set_par(gspca_dev, 0x01000000);
set_par(gspca_dev, 0x01000000);
if (gspca_dev->usb_err >= 0)
- PDEBUG(D_STREAM, "camera started alt: 0x%02x",
- gspca_dev->alt);
+ gspca_dbg(gspca_dev, D_STREAM, "camera started alt: 0x%02x\n",
+ gspca_dev->alt);
out:
return gspca_dev->usb_err;
}
@@ -312,7 +312,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x0640, 0);
reg_w(gspca_dev, 0x0650, 0);
reg_w(gspca_dev, 0x0660, 0);
- PDEBUG(D_STREAM, "camera stopped");
+ gspca_dbg(gspca_dev, D_STREAM, "camera stopped\n");
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
diff --git a/drivers/media/usb/gspca/stk1135.c b/drivers/media/usb/gspca/stk1135.c
index 3ab5ec2ca4bd..6f52a480c2d8 100644
--- a/drivers/media/usb/gspca/stk1135.c
+++ b/drivers/media/usb/gspca/stk1135.c
@@ -67,7 +67,8 @@ static u8 reg_r(struct gspca_dev *gspca_dev, u16 index)
gspca_dev->usb_buf, 1,
500);
- PDEBUG(D_USBI, "reg_r 0x%x=0x%02x", index, gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "reg_r 0x%x=0x%02x\n",
+ index, gspca_dev->usb_buf[0]);
if (ret < 0) {
pr_err("reg_r 0x%x err %d\n", index, ret);
gspca_dev->usb_err = ret;
@@ -93,7 +94,7 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 index, u8 val)
NULL,
0,
500);
- PDEBUG(D_USBO, "reg_w 0x%x:=0x%02x", index, val);
+ gspca_dbg(gspca_dev, D_USBO, "reg_w 0x%x:=0x%02x\n", index, val);
if (ret < 0) {
pr_err("reg_w 0x%x err %d\n", index, ret);
gspca_dev->usb_err = ret;
@@ -468,8 +469,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w_mask(gspca_dev, STK1135_REG_SCTRL, 0x80, 0x80);
if (gspca_dev->usb_err >= 0)
- PDEBUG(D_STREAM, "camera started alt: 0x%02x",
- gspca_dev->alt);
+ gspca_dbg(gspca_dev, D_STREAM, "camera started alt: 0x%02x\n",
+ gspca_dev->alt);
sd->pkt_seq = 0;
@@ -484,7 +485,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
stk1135_camera_disable(gspca_dev);
- PDEBUG(D_STREAM, "camera stopped");
+ gspca_dbg(gspca_dev, D_STREAM, "camera stopped\n");
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -499,7 +500,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
u8 seq;
if (len < 4) {
- PDEBUG(D_PACK, "received short packet (less than 4 bytes)");
+ gspca_dbg(gspca_dev, D_PACK, "received short packet (less than 4 bytes)\n");
return;
}
@@ -515,7 +516,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
if (!(hdr->flags & STK1135_HDR_FRAME_START)) {
seq = hdr->seq & STK1135_HDR_SEQ_MASK;
if (seq != sd->pkt_seq) {
- PDEBUG(D_PACK, "received out-of-sequence packet");
+ gspca_dbg(gspca_dev, D_PACK, "received out-of-sequence packet\n");
/* resync sequence and discard packet */
sd->pkt_seq = seq;
gspca_dev->last_packet_type = DISCARD_PACKET;
diff --git a/drivers/media/usb/gspca/stv0680.c b/drivers/media/usb/gspca/stv0680.c
index 29a65d05cbb2..3ff5ed74bd9f 100644
--- a/drivers/media/usb/gspca/stv0680.c
+++ b/drivers/media/usb/gspca/stv0680.c
@@ -82,8 +82,8 @@ static int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
static int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret)
{
stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */
- PERR("last error: %i, command = 0x%x",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+ gspca_err(gspca_dev, "last error: %i, command = 0x%x\n",
+ gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
return ret;
}
@@ -94,7 +94,7 @@ static int stv0680_get_video_mode(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0] = 0x0f;
if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) {
- PERR("Get_Camera_Mode failed");
+ gspca_err(gspca_dev, "Get_Camera_Mode failed\n");
return stv0680_handle_error(gspca_dev, -EIO);
}
@@ -112,13 +112,13 @@ static int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode)
gspca_dev->usb_buf[0] = mode;
if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) {
- PERR("Set_Camera_Mode failed");
+ gspca_err(gspca_dev, "Set_Camera_Mode failed\n");
return stv0680_handle_error(gspca_dev, -EIO);
}
/* Verify we got what we've asked for */
if (stv0680_get_video_mode(gspca_dev) != mode) {
- PERR("Error setting camera video mode!");
+ gspca_err(gspca_dev, "Error setting camera video mode!\n");
return -EIO;
}
@@ -142,7 +142,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* ping camera to be sure STV0680 is present */
if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
- PERR("STV(e): camera ping failed!!");
+ gspca_err(gspca_dev, "STV(e): camera ping failed!!\n");
return stv0680_handle_error(gspca_dev, -ENODEV);
}
@@ -152,7 +152,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 ||
gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) {
- PERR("Could not get descriptor 0200.");
+ gspca_err(gspca_dev, "Could not get descriptor 0200\n");
return stv0680_handle_error(gspca_dev, -ENODEV);
}
if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02)
@@ -163,17 +163,17 @@ static int sd_config(struct gspca_dev *gspca_dev,
return stv0680_handle_error(gspca_dev, -ENODEV);
if (!(gspca_dev->usb_buf[7] & 0x09)) {
- PERR("Camera supports neither CIF nor QVGA mode");
+ gspca_err(gspca_dev, "Camera supports neither CIF nor QVGA mode\n");
return -ENODEV;
}
if (gspca_dev->usb_buf[7] & 0x01)
- PDEBUG(D_PROBE, "Camera supports CIF mode");
+ gspca_dbg(gspca_dev, D_PROBE, "Camera supports CIF mode\n");
if (gspca_dev->usb_buf[7] & 0x02)
- PDEBUG(D_PROBE, "Camera supports VGA mode");
+ gspca_dbg(gspca_dev, D_PROBE, "Camera supports VGA mode\n");
if (gspca_dev->usb_buf[7] & 0x04)
- PDEBUG(D_PROBE, "Camera supports QCIF mode");
+ gspca_dbg(gspca_dev, D_PROBE, "Camera supports QCIF mode\n");
if (gspca_dev->usb_buf[7] & 0x08)
- PDEBUG(D_PROBE, "Camera supports QVGA mode");
+ gspca_dbg(gspca_dev, D_PROBE, "Camera supports QVGA mode\n");
if (gspca_dev->usb_buf[7] & 0x01)
sd->video_mode = 0x00; /* CIF */
@@ -181,12 +181,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->video_mode = 0x03; /* QVGA */
/* FW rev, ASIC rev, sensor ID */
- PDEBUG(D_PROBE, "Firmware rev is %i.%i",
- gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
- PDEBUG(D_PROBE, "ASIC rev is %i.%i",
- gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
- PDEBUG(D_PROBE, "Sensor ID is %i",
- (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
+ gspca_dbg(gspca_dev, D_PROBE, "Firmware rev is %i.%i\n",
+ gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
+ gspca_dbg(gspca_dev, D_PROBE, "ASIC rev is %i.%i",
+ gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor ID is %i",
+ (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
ret = stv0680_get_video_mode(gspca_dev);
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.c b/drivers/media/usb/gspca/stv06xx/stv06xx.c
index e72c3e1ab9ff..6080a35310ca 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx.c
@@ -51,8 +51,8 @@ int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data)
0x04, 0x40, address, 0, buf, len,
STV06XX_URB_MSG_TIMEOUT);
- PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d",
- i2c_data, address, err);
+ gspca_dbg(gspca_dev, D_CONF, "Written 0x%x to address 0x%x, status: %d\n",
+ i2c_data, address, err);
return (err < 0) ? err : 0;
}
@@ -70,8 +70,8 @@ int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data)
*i2c_data = buf[0];
- PDEBUG(D_CONF, "Reading 0x%x from address 0x%x, status %d",
- *i2c_data, address, err);
+ gspca_dbg(gspca_dev, D_CONF, "Reading 0x%x from address 0x%x, status %d\n",
+ *i2c_data, address, err);
return (err < 0) ? err : 0;
}
@@ -113,15 +113,16 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
struct usb_device *udev = sd->gspca_dev.dev;
__u8 *buf = sd->gspca_dev.usb_buf;
- PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
+ gspca_dbg(gspca_dev, D_CONF, "I2C: Command buffer contains %d entries\n",
+ len);
for (i = 0; i < len;) {
/* Build the command buffer */
memset(buf, 0, I2C_BUFFER_LENGTH);
for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) {
buf[j] = data[2*i];
buf[0x10 + j] = data[2*i+1];
- PDEBUG(D_CONF, "I2C: Writing 0x%02x to reg 0x%02x",
- data[2*i+1], data[2*i]);
+ gspca_dbg(gspca_dev, D_CONF, "I2C: Writing 0x%02x to reg 0x%02x\n",
+ data[2*i+1], data[2*i]);
}
buf[0x20] = sd->sensor->i2c_addr;
buf[0x21] = j - 1; /* Number of commands to send - 1 */
@@ -143,7 +144,8 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
struct usb_device *udev = sd->gspca_dev.dev;
__u8 *buf = sd->gspca_dev.usb_buf;
- PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
+ gspca_dbg(gspca_dev, D_CONF, "I2C: Command buffer contains %d entries\n",
+ len);
for (i = 0; i < len;) {
/* Build the command buffer */
@@ -152,8 +154,8 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
buf[j] = data[2*i];
buf[0x10 + j * 2] = data[2*i+1];
buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8;
- PDEBUG(D_CONF, "I2C: Writing 0x%04x to reg 0x%02x",
- data[2*i+1], data[2*i]);
+ gspca_dbg(gspca_dev, D_CONF, "I2C: Writing 0x%04x to reg 0x%02x\n",
+ data[2*i+1], data[2*i]);
}
buf[0x20] = sd->sensor->i2c_addr;
buf[0x21] = j - 1; /* Number of commands to send - 1 */
@@ -205,8 +207,8 @@ int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
else
*value = buf[0];
- PDEBUG(D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d",
- *value, address, err);
+ gspca_dbg(gspca_dev, D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d\n",
+ *value, address, err);
return (err < 0) ? err : 0;
}
@@ -249,7 +251,7 @@ static int stv06xx_init(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int err;
- PDEBUG(D_PROBE, "Initializing camera");
+ gspca_dbg(gspca_dev, D_PROBE, "Initializing camera\n");
/* Let the usb init settle for a bit
before performing the initialization */
@@ -268,7 +270,7 @@ static int stv06xx_init_controls(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_PROBE, "Initializing controls");
+ gspca_dbg(gspca_dev, D_PROBE, "Initializing controls\n");
gspca_dev->vdev.ctrl_handler = &gspca_dev->ctrl_handler;
return sd->sensor->init_controls(sd);
@@ -285,7 +287,7 @@ static int stv06xx_start(struct gspca_dev *gspca_dev)
intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
if (!alt) {
- PERR("Couldn't get altsetting");
+ gspca_err(gspca_dev, "Couldn't get altsetting\n");
return -EIO;
}
@@ -304,9 +306,9 @@ static int stv06xx_start(struct gspca_dev *gspca_dev)
out:
if (err < 0)
- PDEBUG(D_STREAM, "Starting stream failed");
+ gspca_dbg(gspca_dev, D_STREAM, "Starting stream failed\n");
else
- PDEBUG(D_STREAM, "Started streaming");
+ gspca_dbg(gspca_dev, D_STREAM, "Started streaming\n");
return (err < 0) ? err : 0;
}
@@ -343,7 +345,7 @@ static int stv06xx_isoc_nego(struct gspca_dev *gspca_dev)
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
if (ret < 0)
- PERR("set alt 1 err %d", ret);
+ gspca_err(gspca_dev, "set alt 1 err %d\n", ret);
return ret;
}
@@ -362,9 +364,9 @@ static void stv06xx_stopN(struct gspca_dev *gspca_dev)
out:
if (err < 0)
- PDEBUG(D_STREAM, "Failed to stop stream");
+ gspca_dbg(gspca_dev, D_STREAM, "Failed to stop stream\n");
else
- PDEBUG(D_STREAM, "Stopped streaming");
+ gspca_dbg(gspca_dev, D_STREAM, "Stopped streaming\n");
}
/*
@@ -385,7 +387,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_PACK, "Packet of length %d arrived", len);
+ gspca_dbg(gspca_dev, D_PACK, "Packet of length %d arrived\n", len);
/* A packet may contain several frames
loop until the whole packet is reached */
@@ -393,7 +395,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
int id, chunk_len;
if (len < 4) {
- PDEBUG(D_PACK, "Packet is smaller than 4 bytes");
+ gspca_dbg(gspca_dev, D_PACK, "Packet is smaller than 4 bytes\n");
return;
}
@@ -402,13 +404,14 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
/* Capture the chunk length */
chunk_len = (data[2] << 8) | data[3];
- PDEBUG(D_PACK, "Chunk id: %x, length: %d", id, chunk_len);
+ gspca_dbg(gspca_dev, D_PACK, "Chunk id: %x, length: %d\n",
+ id, chunk_len);
data += 4;
len -= 4;
if (len < chunk_len) {
- PERR("URB packet length is smaller than the specified chunk length");
+ gspca_err(gspca_dev, "URB packet length is smaller than the specified chunk length\n");
gspca_dev->last_packet_type = DISCARD_PACKET;
return;
}
@@ -421,7 +424,7 @@ static void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
case 0x0200:
case 0x4200:
frame_data:
- PDEBUG(D_PACK, "Frame data packet detected");
+ gspca_dbg(gspca_dev, D_PACK, "Frame data packet detected\n");
if (sd->to_skip) {
int skip = (sd->to_skip < chunk_len) ?
@@ -440,7 +443,7 @@ frame_data:
case 0x8005:
case 0xc001:
case 0xc005:
- PDEBUG(D_PACK, "Starting new frame");
+ gspca_dbg(gspca_dev, D_PACK, "Starting new frame\n");
/* Create a new frame, chunk length should be zero */
gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -450,40 +453,41 @@ frame_data:
sd->to_skip = gspca_dev->pixfmt.width * 4;
if (chunk_len)
- PERR("Chunk length is non-zero on a SOF");
+ gspca_err(gspca_dev, "Chunk length is non-zero on a SOF\n");
break;
case 0x8002:
case 0x8006:
case 0xc002:
- PDEBUG(D_PACK, "End of frame detected");
+ gspca_dbg(gspca_dev, D_PACK, "End of frame detected\n");
/* Complete the last frame (if any) */
gspca_frame_add(gspca_dev, LAST_PACKET,
NULL, 0);
if (chunk_len)
- PERR("Chunk length is non-zero on a EOF");
+ gspca_err(gspca_dev, "Chunk length is non-zero on a EOF\n");
break;
case 0x0005:
- PDEBUG(D_PACK, "Chunk 0x005 detected");
+ gspca_dbg(gspca_dev, D_PACK, "Chunk 0x005 detected\n");
/* Unknown chunk with 11 bytes of data,
occurs just before end of each frame
in compressed mode */
break;
case 0x0100:
- PDEBUG(D_PACK, "Chunk 0x0100 detected");
+ gspca_dbg(gspca_dev, D_PACK, "Chunk 0x0100 detected\n");
/* Unknown chunk with 2 bytes of data,
occurs 2-3 times per USB interrupt */
break;
case 0x42ff:
- PDEBUG(D_PACK, "Chunk 0x42ff detected");
+ gspca_dbg(gspca_dev, D_PACK, "Chunk 0x42ff detected\n");
/* Special chunk seen sometimes on the ST6422 */
break;
default:
- PDEBUG(D_PACK, "Unknown chunk 0x%04x detected", id);
+ gspca_dbg(gspca_dev, D_PACK, "Unknown chunk 0x%04x detected\n",
+ id);
/* Unknown chunk */
}
data += chunk_len;
@@ -539,7 +543,7 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_PROBE, "Configuring camera");
+ gspca_dbg(gspca_dev, D_PROBE, "Configuring camera\n");
sd->bridge = id->driver_info;
gspca_dev->sd_desc = &sd_desc;
@@ -575,7 +579,7 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
/* -- module initialisation -- */
static const struct usb_device_id device_table[] = {
- {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, /* QuickCam Express */
+ {USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 }, /* QuickCam Express */
{USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 }, /* LEGO cam / QuickCam Web */
{USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 }, /* Dexxa WebCam USB */
{USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 }, /* QuickCam Messenger */
@@ -598,7 +602,7 @@ static void sd_disconnect(struct usb_interface *intf)
struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
struct sd *sd = (struct sd *) gspca_dev;
void *priv = sd->sensor_priv;
- PDEBUG(D_PROBE, "Disconnecting the stv06xx device");
+ gspca_dbg(gspca_dev, D_PROBE, "Disconnecting the stv06xx device\n");
sd->sensor = NULL;
gspca_disconnect(intf);
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx.h b/drivers/media/usb/gspca/stv06xx/stv06xx.h
index f9d74e4d7cf9..480186706bba 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx.h
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx.h
@@ -59,7 +59,7 @@
/* Refers to the CIF 352x288 and QCIF 176x144 */
/* 1: 288 lines, 2: 144 lines */
-#define STV_Y_CTRL 0x15c3
+#define STV_Y_CTRL 0x15c3
#define STV_RESET 0x1620
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
index 28252f6c4afd..d8db2c89718f 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c
@@ -251,8 +251,8 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
if (err < 0)
return err;
}
- PDEBUG(D_CONF, "Writing exposure %d, rowexp %d, srowexp %d",
- val, rowexp, srowexp);
+ gspca_dbg(gspca_dev, D_CONF, "Writing exposure %d, rowexp %d, srowexp %d\n",
+ val, rowexp, srowexp);
return err;
}
@@ -276,7 +276,7 @@ static int hdcs_set_gains(struct sd *sd, u8 g)
static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
{
- PDEBUG(D_CONF, "Writing gain %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Writing gain %d\n", val);
return hdcs_set_gains((struct sd *) gspca_dev,
val & 0xff);
}
@@ -465,7 +465,7 @@ static int hdcs_start(struct sd *sd)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
- PDEBUG(D_STREAM, "Starting stream");
+ gspca_dbg(gspca_dev, D_STREAM, "Starting stream\n");
return hdcs_set_state(sd, HDCS_STATE_RUN);
}
@@ -474,7 +474,7 @@ static int hdcs_stop(struct sd *sd)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
- PDEBUG(D_STREAM, "Halting stream");
+ gspca_dbg(gspca_dev, D_STREAM, "Halting stream\n");
return hdcs_set_state(sd, HDCS_STATE_SLEEP);
}
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
index e1ce96e9405f..7374aeb0a67a 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c
@@ -229,7 +229,7 @@ static int pb0100_start(struct sd *sd)
}
err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3)|BIT(1));
- PDEBUG(D_STREAM, "Started stream, status: %d", err);
+ gspca_dbg(gspca_dev, D_STREAM, "Started stream, status: %d\n", err);
return (err < 0) ? err : 0;
}
@@ -247,7 +247,7 @@ static int pb0100_stop(struct sd *sd)
/* Set bit 1 to zero */
err = stv06xx_write_sensor(sd, PB_CONTROL, BIT(5)|BIT(3));
- PDEBUG(D_STREAM, "Halting stream");
+ gspca_dbg(gspca_dev, D_STREAM, "Halting stream\n");
out:
return (err < 0) ? err : 0;
}
@@ -332,7 +332,8 @@ static int pb0100_set_gain(struct gspca_dev *gspca_dev, __s32 val)
err = stv06xx_write_sensor(sd, PB_G1GAIN, val);
if (!err)
err = stv06xx_write_sensor(sd, PB_G2GAIN, val);
- PDEBUG(D_CONF, "Set green gain to %d, status: %d", val, err);
+ gspca_dbg(gspca_dev, D_CONF, "Set green gain to %d, status: %d\n",
+ val, err);
if (!err)
err = pb0100_set_red_balance(gspca_dev, ctrls->red->val);
@@ -355,7 +356,8 @@ static int pb0100_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
val = 255;
err = stv06xx_write_sensor(sd, PB_RGAIN, val);
- PDEBUG(D_CONF, "Set red gain to %d, status: %d", val, err);
+ gspca_dbg(gspca_dev, D_CONF, "Set red gain to %d, status: %d\n",
+ val, err);
return err;
}
@@ -373,7 +375,8 @@ static int pb0100_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
val = 255;
err = stv06xx_write_sensor(sd, PB_BGAIN, val);
- PDEBUG(D_CONF, "Set blue gain to %d, status: %d", val, err);
+ gspca_dbg(gspca_dev, D_CONF, "Set blue gain to %d, status: %d\n",
+ val, err);
return err;
}
@@ -384,7 +387,8 @@ static int pb0100_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
int err;
err = stv06xx_write_sensor(sd, PB_RINTTIME, val);
- PDEBUG(D_CONF, "Set exposure to %d, status: %d", val, err);
+ gspca_dbg(gspca_dev, D_CONF, "Set exposure to %d, status: %d\n",
+ val, err);
return err;
}
@@ -404,8 +408,8 @@ static int pb0100_set_autogain(struct gspca_dev *gspca_dev, __s32 val)
val = 0;
err = stv06xx_write_sensor(sd, PB_EXPGAIN, val);
- PDEBUG(D_CONF, "Set autogain to %d (natural: %d), status: %d",
- val, ctrls->natural->val, err);
+ gspca_dbg(gspca_dev, D_CONF, "Set autogain to %d (natural: %d), status: %d\n",
+ val, ctrls->natural->val, err);
return err;
}
@@ -426,7 +430,8 @@ static int pb0100_set_autogain_target(struct gspca_dev *gspca_dev, __s32 val)
if (!err)
err = stv06xx_write_sensor(sd, PB_R22, darkpixels);
- PDEBUG(D_CONF, "Set autogain target to %d, status: %d", val, err);
+ gspca_dbg(gspca_dev, D_CONF, "Set autogain target to %d, status: %d\n",
+ val, err);
return err;
}
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c
index 4b76070515b5..51a135c2f9f7 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_st6422.c
@@ -277,7 +277,7 @@ static int st6422_stop(struct sd *sd)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
- PDEBUG(D_STREAM, "Halting stream");
+ gspca_dbg(gspca_dev, D_STREAM, "Halting stream\n");
return 0;
}
diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c
index d265e6b00994..b2f16c2754fb 100644
--- a/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/usb/gspca/stv06xx/stv06xx_vv6410.c
@@ -129,7 +129,7 @@ static int vv6410_start(struct sd *sd)
u32 priv = cam->cam_mode[sd->gspca_dev.curr_mode].priv;
if (priv & VV6410_SUBSAMPLE) {
- PDEBUG(D_CONF, "Enabling subsampling");
+ gspca_dbg(gspca_dev, D_CONF, "Enabling subsampling\n");
stv06xx_write_bridge(sd, STV_Y_CTRL, 0x02);
stv06xx_write_bridge(sd, STV_X_CTRL, 0x06);
@@ -150,7 +150,7 @@ static int vv6410_start(struct sd *sd)
if (err < 0)
return err;
- PDEBUG(D_STREAM, "Starting stream");
+ gspca_dbg(gspca_dev, D_STREAM, "Starting stream\n");
return 0;
}
@@ -169,7 +169,7 @@ static int vv6410_stop(struct sd *sd)
if (err < 0)
return err;
- PDEBUG(D_STREAM, "Halting stream");
+ gspca_dbg(gspca_dev, D_STREAM, "Halting stream\n");
return 0;
}
@@ -203,7 +203,7 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
else
i2c_data &= ~VV6410_HFLIP;
- PDEBUG(D_CONF, "Set horizontal flip to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set horizontal flip to %d\n", val);
err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data);
return (err < 0) ? err : 0;
@@ -224,7 +224,7 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
else
i2c_data &= ~VV6410_VFLIP;
- PDEBUG(D_CONF, "Set vertical flip to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set vertical flip to %d\n", val);
err = stv06xx_write_sensor(sd, VV6410_DATAFORMAT, i2c_data);
return (err < 0) ? err : 0;
@@ -235,7 +235,7 @@ static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
int err;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(D_CONF, "Set analog gain to %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Set analog gain to %d\n", val);
err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
return (err < 0) ? err : 0;
@@ -252,8 +252,8 @@ static int vv6410_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
fine = val % VV6410_CIF_LINELENGTH;
coarse = min(512, val / VV6410_CIF_LINELENGTH);
- PDEBUG(D_CONF, "Set coarse exposure to %d, fine exposure to %d",
- coarse, fine);
+ gspca_dbg(gspca_dev, D_CONF, "Set coarse exposure to %d, fine exposure to %d\n",
+ coarse, fine);
err = stv06xx_write_sensor(sd, VV6410_FINEH, fine >> 8);
if (err < 0)
diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c
index 8c2785aea3cd..437a3367ab97 100644
--- a/drivers/media/usb/gspca/sunplus.c
+++ b/drivers/media/usb/gspca/sunplus.c
@@ -248,7 +248,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
int ret;
if (len > USB_BUF_SZ) {
- PERR("reg_r: buffer overflow\n");
+ gspca_err(gspca_dev, "reg_r: buffer overflow\n");
return;
}
if (gspca_dev->usb_err < 0)
@@ -311,8 +311,8 @@ static void reg_w_riv(struct gspca_dev *gspca_dev,
gspca_dev->usb_err = ret;
return;
}
- PDEBUG(D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x",
- req, index, value);
+ gspca_dbg(gspca_dev, D_USBO, "reg_w_riv: 0x%02x,0x%04x:0x%04x\n",
+ req, index, value);
}
static void write_vector(struct gspca_dev *gspca_dev,
@@ -343,12 +343,14 @@ static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
{
reg_w_riv(gspca_dev, req, idx, val);
reg_r(gspca_dev, 0x01, 0x0001, 1);
- PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_FRAM, "before wait 0x%04x\n",
+ gspca_dev->usb_buf[0]);
reg_w_riv(gspca_dev, req, idx, val);
msleep(200);
reg_r(gspca_dev, 0x01, 0x0001, 1);
- PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_FRAM, "after wait 0x%04x\n",
+ gspca_dev->usb_buf[0]);
}
static void spca504_read_info(struct gspca_dev *gspca_dev)
@@ -363,10 +365,10 @@ static void spca504_read_info(struct gspca_dev *gspca_dev)
reg_r(gspca_dev, 0, i, 1);
info[i] = gspca_dev->usb_buf[0];
}
- PDEBUG(D_STREAM,
- "Read info: %d %d %d %d %d %d. Should be 1,0,2,2,0,0",
- info[0], info[1], info[2],
- info[3], info[4], info[5]);
+ gspca_dbg(gspca_dev, D_STREAM,
+ "Read info: %d %d %d %d %d %d. Should be 1,0,2,2,0,0\n",
+ info[0], info[1], info[2],
+ info[3], info[4], info[5]);
}
static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
@@ -379,8 +381,8 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
reg_r(gspca_dev, 0x01, 0x0001, 1);
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x",
- gspca_dev->usb_buf[0], endcode);
+ gspca_dbg(gspca_dev, D_FRAM, "Status 0x%02x Need 0x%02x\n",
+ gspca_dev->usb_buf[0], endcode);
if (!count)
return;
count = 200;
@@ -391,8 +393,8 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
reg_r(gspca_dev, 0x01, 0x0001, 1);
status = gspca_dev->usb_buf[0];
if (status == endcode) {
- PDEBUG(D_FRAM, "status 0x%04x after wait %d",
- status, 200 - count);
+ gspca_dbg(gspca_dev, D_FRAM, "status 0x%04x after wait %d\n",
+ status, 200 - count);
break;
}
}
@@ -435,8 +437,8 @@ static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
data = gspca_dev->usb_buf;
reg_r(gspca_dev, 0x20, 0, 5);
- PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d",
- data[0], data[1], data[2], data[3], data[4]);
+ gspca_dbg(gspca_dev, D_STREAM, "FirmWare: %d %d %d %d %d\n",
+ data[0], data[1], data[2], data[3], data[4]);
reg_r(gspca_dev, 0x23, 0, 64);
reg_r(gspca_dev, 0x23, 1, 64);
}
@@ -651,7 +653,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
spca504B_WaitCmdStatus(gspca_dev);
break;
case BRIDGE_SPCA504C: /* pccam600 */
- PDEBUG(D_STREAM, "Opening SPCA504 (PC-CAM 600)");
+ gspca_dbg(gspca_dev, D_STREAM, "Opening SPCA504 (PC-CAM 600)\n");
reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0000);
reg_w_riv(gspca_dev, 0xe0, 0x0000, 0x0001); /* reset */
spca504_wait_status(gspca_dev);
@@ -666,7 +668,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
break;
default:
/* case BRIDGE_SPCA504: */
- PDEBUG(D_STREAM, "Opening SPCA504");
+ gspca_dbg(gspca_dev, D_STREAM, "Opening SPCA504\n");
if (sd->subtype == AiptekMiniPenCam13) {
spca504_read_info(gspca_dev);
diff --git a/drivers/media/usb/gspca/t613.c b/drivers/media/usb/gspca/t613.c
index 46fb76349000..0ae557cd15ef 100644
--- a/drivers/media/usb/gspca/t613.c
+++ b/drivers/media/usb/gspca/t613.c
@@ -490,7 +490,7 @@ static void setcolors(struct gspca_dev *gspca_dev, s32 val)
static void setgamma(struct gspca_dev *gspca_dev, s32 val)
{
- PDEBUG(D_CONF, "Gamma: %d", val);
+ gspca_dbg(gspca_dev, D_CONF, "Gamma: %d\n", val);
reg_w_ixbuf(gspca_dev, 0x90,
gamma_table[val], sizeof gamma_table[0]);
}
@@ -592,19 +592,19 @@ static int sd_init(struct gspca_dev *gspca_dev)
| reg_r(gspca_dev, 0x07);
switch (sensor_id & 0xff0f) {
case 0x0801:
- PDEBUG(D_PROBE, "sensor tas5130a");
+ gspca_dbg(gspca_dev, D_PROBE, "sensor tas5130a\n");
sd->sensor = SENSOR_TAS5130A;
break;
case 0x0802:
- PDEBUG(D_PROBE, "sensor lt168g");
+ gspca_dbg(gspca_dev, D_PROBE, "sensor lt168g\n");
sd->sensor = SENSOR_LT168G;
break;
case 0x0803:
- PDEBUG(D_PROBE, "sensor 'other'");
+ gspca_dbg(gspca_dev, D_PROBE, "sensor 'other'\n");
sd->sensor = SENSOR_OTHER;
break;
case 0x0807:
- PDEBUG(D_PROBE, "sensor om6802");
+ gspca_dbg(gspca_dev, D_PROBE, "sensor om6802\n");
sd->sensor = SENSOR_OM6802;
break;
default:
@@ -632,8 +632,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
i = 0;
while (read_indexs[i] != 0x00) {
test_byte = reg_r(gspca_dev, read_indexs[i]);
- PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
- test_byte);
+ gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n",
+ read_indexs[i], test_byte);
i++;
}
@@ -643,8 +643,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
if (sd->sensor == SENSOR_LT168G) {
test_byte = reg_r(gspca_dev, 0x80);
- PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
- test_byte);
+ gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n", 0x80,
+ test_byte);
reg_w(gspca_dev, 0x6c80);
}
@@ -665,8 +665,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
if (sd->sensor == SENSOR_LT168G) {
test_byte = reg_r(gspca_dev, 0x80);
- PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
- test_byte);
+ gspca_dbg(gspca_dev, D_STREAM, "Reg 0x%02x = 0x%02x\n", 0x80,
+ test_byte);
reg_w(gspca_dev, 0x6c80);
}
@@ -737,7 +737,7 @@ static void poll_sensor(struct gspca_dev *gspca_dev)
0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
0xc2, 0x80, 0xc3, 0x10};
- PDEBUG(D_STREAM, "[Sensor requires polling]");
+ gspca_dbg(gspca_dev, D_STREAM, "[Sensor requires polling]\n");
reg_w_buf(gspca_dev, poll1, sizeof poll1);
reg_w_buf(gspca_dev, poll2, sizeof poll2);
reg_w_buf(gspca_dev, noise03, sizeof noise03);
diff --git a/drivers/media/usb/gspca/topro.c b/drivers/media/usb/gspca/topro.c
index 983fc6b500af..82e2be14cad8 100644
--- a/drivers/media/usb/gspca/topro.c
+++ b/drivers/media/usb/gspca/topro.c
@@ -1453,7 +1453,7 @@ static void set_dqt(struct gspca_dev *gspca_dev, u8 q)
struct sd *sd = (struct sd *) gspca_dev;
/* update the jpeg quantization tables */
- PDEBUG(D_STREAM, "q %d -> %d", sd->quality, q);
+ gspca_dbg(gspca_dev, D_STREAM, "q %d -> %d\n", sd->quality, q);
sd->quality = q;
if (q > 16)
q = 16;
@@ -4053,7 +4053,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
ARRAY_SIZE(tp6810_preinit));
msleep(15);
reg_r(gspca_dev, TP6800_R18_GPIO_DATA);
- PDEBUG(D_PROBE, "gpio: %02x", gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_PROBE, "gpio: %02x\n", gspca_dev->usb_buf[0]);
/* values:
* 0x80: snapshot button
* 0x40: LED
@@ -4627,7 +4627,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
if (*data == 0xaa || *data == 0x00)
return;
if (*data > 0xc0) {
- PDEBUG(D_FRAM, "bad frame");
+ gspca_dbg(gspca_dev, D_FRAM, "bad frame\n");
gspca_dev->last_packet_type = DISCARD_PACKET;
return;
}
diff --git a/drivers/media/usb/gspca/touptek.c b/drivers/media/usb/gspca/touptek.c
index b8af4370d27c..d1b9032d7863 100644
--- a/drivers/media/usb/gspca/touptek.c
+++ b/drivers/media/usb/gspca/touptek.c
@@ -195,15 +195,15 @@ static const struct v4l2_pix_format vga_mode[] = {
static int val_reply(struct gspca_dev *gspca_dev, const char *reply, int rc)
{
if (rc < 0) {
- PERR("reply has error %d", rc);
+ gspca_err(gspca_dev, "reply has error %d\n", rc);
return -EIO;
}
if (rc != 1) {
- PERR("Bad reply size %d", rc);
+ gspca_err(gspca_dev, "Bad reply size %d\n", rc);
return -EIO;
}
if (reply[0] != 0x08) {
- PERR("Bad reply 0x%02x", (int)reply[0]);
+ gspca_err(gspca_dev, "Bad reply 0x%02x\n", (int)reply[0]);
return -EIO;
}
return 0;
@@ -214,21 +214,21 @@ static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
char *buff = gspca_dev->usb_buf;
int rc;
- PDEBUG(D_USBO,
- "reg_w bReq=0x0B, bReqT=0xC0, wVal=0x%04X, wInd=0x%04X\n",
- value, index);
+ gspca_dbg(gspca_dev, D_USBO,
+ "reg_w bReq=0x0B, bReqT=0xC0, wVal=0x%04X, wInd=0x%04X\n\n",
+ value, index);
rc = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0),
0x0B, 0xC0, value, index, buff, 1, 500);
- PDEBUG(D_USBO, "rc=%d, ret={0x%02x}", rc, (int)buff[0]);
+ gspca_dbg(gspca_dev, D_USBO, "rc=%d, ret={0x%02x}\n", rc, (int)buff[0]);
if (rc < 0) {
- PERR("Failed reg_w(0x0B, 0xC0, 0x%04X, 0x%04X) w/ rc %d\n",
- value, index, rc);
+ gspca_err(gspca_dev, "Failed reg_w(0x0B, 0xC0, 0x%04X, 0x%04X) w/ rc %d\n",
+ value, index, rc);
gspca_dev->usb_err = rc;
return;
}
if (val_reply(gspca_dev, buff, rc)) {
- PERR("Bad reply to reg_w(0x0B, 0xC0, 0x%04X, 0x%04X\n",
- value, index);
+ gspca_err(gspca_dev, "Bad reply to reg_w(0x0B, 0xC0, 0x%04X, 0x%04X\n",
+ value, index);
gspca_dev->usb_err = -EIO;
}
}
@@ -254,11 +254,11 @@ static void setexposure(struct gspca_dev *gspca_dev, s32 val)
else if (w == 3264)
value = val * 3 / 2;
else {
- PERR("Invalid width %u\n", w);
+ gspca_err(gspca_dev, "Invalid width %u\n", w);
gspca_dev->usb_err = -EINVAL;
return;
}
- PDEBUG(D_STREAM, "exposure: 0x%04X ms\n", value);
+ gspca_dbg(gspca_dev, D_STREAM, "exposure: 0x%04X ms\n\n", value);
/* Wonder if theres a good reason for sending it twice */
/* probably not but leave it in because...why not */
reg_w(gspca_dev, value, REG_COARSE_INTEGRATION_TIME_);
@@ -286,9 +286,9 @@ static void setggain(struct gspca_dev *gspca_dev, u16 global_gain)
u16 normalized;
normalized = gainify(global_gain);
- PDEBUG(D_STREAM, "gain G1/G2 (0x%04X): 0x%04X (src 0x%04X)\n",
- REG_GREEN1_GAIN,
- normalized, global_gain);
+ gspca_dbg(gspca_dev, D_STREAM, "gain G1/G2 (0x%04X): 0x%04X (src 0x%04X)\n\n",
+ REG_GREEN1_GAIN,
+ normalized, global_gain);
reg_w(gspca_dev, normalized, REG_GREEN1_GAIN);
reg_w(gspca_dev, normalized, REG_GREEN2_GAIN);
@@ -302,13 +302,13 @@ static void setbgain(struct gspca_dev *gspca_dev,
normalized = global_gain +
((u32)global_gain) * gain / GAIN_MAX;
if (normalized > GAIN_MAX) {
- PDEBUG(D_STREAM, "Truncating blue 0x%04X w/ value 0x%04X\n",
- GAIN_MAX, normalized);
+ gspca_dbg(gspca_dev, D_STREAM, "Truncating blue 0x%04X w/ value 0x%04X\n\n",
+ GAIN_MAX, normalized);
normalized = GAIN_MAX;
}
normalized = gainify(normalized);
- PDEBUG(D_STREAM, "gain B (0x%04X): 0x%04X w/ source 0x%04X\n",
- REG_BLUE_GAIN, normalized, gain);
+ gspca_dbg(gspca_dev, D_STREAM, "gain B (0x%04X): 0x%04X w/ source 0x%04X\n\n",
+ REG_BLUE_GAIN, normalized, gain);
reg_w(gspca_dev, normalized, REG_BLUE_GAIN);
}
@@ -321,13 +321,13 @@ static void setrgain(struct gspca_dev *gspca_dev,
normalized = global_gain +
((u32)global_gain) * gain / GAIN_MAX;
if (normalized > GAIN_MAX) {
- PDEBUG(D_STREAM, "Truncating gain 0x%04X w/ value 0x%04X\n",
- GAIN_MAX, normalized);
+ gspca_dbg(gspca_dev, D_STREAM, "Truncating gain 0x%04X w/ value 0x%04X\n\n",
+ GAIN_MAX, normalized);
normalized = GAIN_MAX;
}
normalized = gainify(normalized);
- PDEBUG(D_STREAM, "gain R (0x%04X): 0x%04X w / source 0x%04X\n",
- REG_RED_GAIN, normalized, gain);
+ gspca_dbg(gspca_dev, D_STREAM, "gain R (0x%04X): 0x%04X w / source 0x%04X\n\n",
+ REG_RED_GAIN, normalized, gain);
reg_w(gspca_dev, normalized, REG_RED_GAIN);
}
@@ -336,7 +336,7 @@ static void configure_wh(struct gspca_dev *gspca_dev)
{
unsigned int w = gspca_dev->pixfmt.width;
- PDEBUG(D_STREAM, "configure_wh\n");
+ gspca_dbg(gspca_dev, D_STREAM, "configure_wh\n\n");
if (w == 800) {
static const struct cmd reg_init_res[] = {
@@ -372,7 +372,7 @@ static void configure_wh(struct gspca_dev *gspca_dev)
reg_w_buf(gspca_dev,
reg_init_res, ARRAY_SIZE(reg_init_res));
} else {
- PERR("bad width %u\n", w);
+ gspca_err(gspca_dev, "bad width %u\n", w);
gspca_dev->usb_err = -EINVAL;
return;
}
@@ -392,7 +392,7 @@ static void configure_wh(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x0B4B, REG_FRAME_LENGTH_LINES_);
reg_w(gspca_dev, 0x1F40, REG_LINE_LENGTH_PCK_);
} else {
- PERR("bad width %u\n", w);
+ gspca_err(gspca_dev, "bad width %u\n", w);
gspca_dev->usb_err = -EINVAL;
return;
}
@@ -425,14 +425,15 @@ static void configure_encrypted(struct gspca_dev *gspca_dev)
{0x0100, REG_MODE_SELECT},
};
- PDEBUG(D_STREAM, "Encrypted begin, w = %u\n", gspca_dev->pixfmt.width);
+ gspca_dbg(gspca_dev, D_STREAM, "Encrypted begin, w = %u\n\n",
+ gspca_dev->pixfmt.width);
reg_w_buf(gspca_dev, reg_init_begin, ARRAY_SIZE(reg_init_begin));
configure_wh(gspca_dev);
reg_w_buf(gspca_dev, reg_init_end, ARRAY_SIZE(reg_init_end));
reg_w(gspca_dev, 0x0100, REG_GROUPED_PARAMETER_HOLD);
reg_w(gspca_dev, 0x0000, REG_GROUPED_PARAMETER_HOLD);
- PDEBUG(D_STREAM, "Encrypted end\n");
+ gspca_dbg(gspca_dev, D_STREAM, "Encrypted end\n\n");
}
static int configure(struct gspca_dev *gspca_dev)
@@ -440,7 +441,7 @@ static int configure(struct gspca_dev *gspca_dev)
int rc;
char *buff = gspca_dev->usb_buf;
- PDEBUG(D_STREAM, "configure()\n");
+ gspca_dbg(gspca_dev, D_STREAM, "configure()\n\n");
/*
* First driver sets a sort of encryption key
@@ -458,7 +459,7 @@ static int configure(struct gspca_dev *gspca_dev)
rc = usb_control_msg(gspca_dev->dev, usb_rcvctrlpipe(gspca_dev->dev, 0),
0x16, 0xC0, 0x0000, 0x0000, buff, 2, 500);
if (val_reply(gspca_dev, buff, rc)) {
- PERR("failed key req");
+ gspca_err(gspca_dev, "failed key req\n");
return -EIO;
}
@@ -475,21 +476,24 @@ static int configure(struct gspca_dev *gspca_dev)
rc = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
0x01, 0x40, 0x0001, 0x000F, NULL, 0, 500);
if (rc < 0) {
- PERR("failed to replay packet 176 w/ rc %d\n", rc);
+ gspca_err(gspca_dev, "failed to replay packet 176 w/ rc %d\n",
+ rc);
return rc;
}
rc = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
0x01, 0x40, 0x0000, 0x000F, NULL, 0, 500);
if (rc < 0) {
- PERR("failed to replay packet 178 w/ rc %d\n", rc);
+ gspca_err(gspca_dev, "failed to replay packet 178 w/ rc %d\n",
+ rc);
return rc;
}
rc = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
0x01, 0x40, 0x0001, 0x000F, NULL, 0, 500);
if (rc < 0) {
- PERR("failed to replay packet 180 w/ rc %d\n", rc);
+ gspca_err(gspca_dev, "failed to replay packet 180 w/ rc %d\n",
+ rc);
return rc;
}
@@ -511,11 +515,12 @@ static int configure(struct gspca_dev *gspca_dev)
rc = usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
0x01, 0x40, 0x0003, 0x000F, NULL, 0, 500);
if (rc < 0) {
- PERR("failed to replay final packet w/ rc %d\n", rc);
+ gspca_err(gspca_dev, "failed to replay final packet w/ rc %d\n",
+ rc);
return rc;
}
- PDEBUG(D_STREAM, "Configure complete\n");
+ gspca_dbg(gspca_dev, D_STREAM, "Configure complete\n\n");
return 0;
}
@@ -545,7 +550,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
rc = configure(gspca_dev);
if (rc < 0) {
- PERR("Failed configure");
+ gspca_err(gspca_dev, "Failed configure\n");
return rc;
}
/* First two frames have messed up gains
@@ -563,13 +568,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* can we finish a frame? */
if (sd->this_f + len == gspca_dev->pixfmt.sizeimage) {
gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
- PDEBUG(D_FRAM, "finish frame sz %u/%u w/ len %u\n",
- sd->this_f, gspca_dev->pixfmt.sizeimage, len);
+ gspca_dbg(gspca_dev, D_FRAM, "finish frame sz %u/%u w/ len %u\n\n",
+ sd->this_f, gspca_dev->pixfmt.sizeimage, len);
/* lost some data, discard the frame */
} else {
gspca_frame_add(gspca_dev, DISCARD_PACKET, NULL, 0);
- PDEBUG(D_FRAM, "abort frame sz %u/%u w/ len %u\n",
- sd->this_f, gspca_dev->pixfmt.sizeimage, len);
+ gspca_dbg(gspca_dev, D_FRAM, "abort frame sz %u/%u w/ len %u\n\n",
+ sd->this_f, gspca_dev->pixfmt.sizeimage, len);
}
sd->this_f = 0;
} else {
@@ -641,7 +646,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev)
V4L2_CID_RED_BALANCE, 0, 1023, 1, 295);
if (hdl->error) {
- PERR("Could not initialize controls\n");
+ gspca_err(gspca_dev, "Could not initialize controls\n");
return hdl->error;
}
return 0;
diff --git a/drivers/media/usb/gspca/vc032x.c b/drivers/media/usb/gspca/vc032x.c
index b935febf7146..6b11597977c9 100644
--- a/drivers/media/usb/gspca/vc032x.c
+++ b/drivers/media/usb/gspca/vc032x.c
@@ -2926,11 +2926,12 @@ static void reg_r(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_err < 0)
return;
if (len == 1)
- PDEBUG(D_USBI, "GET %02x 0001 %04x %02x", req, index,
- gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_USBI, "GET %02x 0001 %04x %02x\n",
+ req, index,
+ gspca_dev->usb_buf[0]);
else
- PDEBUG(D_USBI, "GET %02x 0001 %04x %*ph",
- req, index, 3, gspca_dev->usb_buf);
+ gspca_dbg(gspca_dev, D_USBI, "GET %02x 0001 %04x %*ph\n",
+ req, index, 3, gspca_dev->usb_buf);
}
static void reg_w_i(struct gspca_dev *gspca_dev,
@@ -2960,7 +2961,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
{
if (gspca_dev->usb_err < 0)
return;
- PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index);
+ gspca_dbg(gspca_dev, D_USBO, "SET %02x %04x %04x\n", req, value, index);
reg_w_i(gspca_dev, req, value, index);
}
@@ -2992,8 +2993,8 @@ static u16 read_sensor_register(struct gspca_dev *gspca_dev,
reg_r(gspca_dev, 0xa1, 0xb33c, 1);
hdata = gspca_dev->usb_buf[0];
if (hdata != 0 && mdata != 0 && ldata != 0)
- PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
- hdata, mdata, ldata);
+ gspca_dbg(gspca_dev, D_PROBE, "Read Sensor %02x%02x %02x\n",
+ hdata, mdata, ldata);
reg_r(gspca_dev, 0xa1, 0xb334, 1);
if (gspca_dev->usb_buf[0] == 0x02)
return (hdata << 8) + mdata;
@@ -3015,8 +3016,8 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
}
reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
- PDEBUG(D_PROBE, "vc032%d check sensor header %02x",
- sd->bridge == BRIDGE_VC0321 ? 1 : 3, gspca_dev->usb_buf[0]);
+ gspca_dbg(gspca_dev, D_PROBE, "vc032%d check sensor header %02x\n",
+ sd->bridge == BRIDGE_VC0321 ? 1 : 3, gspca_dev->usb_buf[0]);
if (sd->bridge == BRIDGE_VC0321) {
ptsensor_info = vc0321_probe_data;
n = ARRAY_SIZE(vc0321_probe_data);
@@ -3036,7 +3037,8 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
if (value == 0 && ptsensor_info->IdAdd == 0x82)
value = read_sensor_register(gspca_dev, 0x83);
if (value != 0) {
- PDEBUG(D_PROBE, "Sensor ID %04x (%d)", value, i);
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor ID %04x (%d)\n",
+ value, i);
if (value == ptsensor_info->VpId)
return ptsensor_info->sensorId;
@@ -3063,9 +3065,10 @@ static void i2c_write(struct gspca_dev *gspca_dev,
if (gspca_dev->usb_err < 0)
return;
if (size == 1)
- PDEBUG(D_USBO, "i2c_w %02x %02x", reg, *val);
+ gspca_dbg(gspca_dev, D_USBO, "i2c_w %02x %02x\n", reg, *val);
else
- PDEBUG(D_USBO, "i2c_w %02x %02x%02x", reg, *val, val[1]);
+ gspca_dbg(gspca_dev, D_USBO, "i2c_w %02x %02x%02x\n",
+ reg, *val, val[1]);
reg_r_i(gspca_dev, 0xa1, 0xb33f, 1);
/*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/
reg_w_i(gspca_dev, 0xa0, size, 0xb334);
@@ -3170,35 +3173,35 @@ static int sd_init(struct gspca_dev *gspca_dev)
pr_err("Unknown sensor...\n");
return -EINVAL;
case SENSOR_HV7131R:
- PDEBUG(D_PROBE, "Find Sensor HV7131R");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor HV7131R\n");
break;
case SENSOR_MI0360:
- PDEBUG(D_PROBE, "Find Sensor MI0360");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor MI0360\n");
sd->bridge = BRIDGE_VC0323;
break;
case SENSOR_MI1310_SOC:
- PDEBUG(D_PROBE, "Find Sensor MI1310_SOC");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor MI1310_SOC\n");
break;
case SENSOR_MI1320:
- PDEBUG(D_PROBE, "Find Sensor MI1320");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor MI1320\n");
break;
case SENSOR_MI1320_SOC:
- PDEBUG(D_PROBE, "Find Sensor MI1320_SOC");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor MI1320_SOC\n");
break;
case SENSOR_OV7660:
- PDEBUG(D_PROBE, "Find Sensor OV7660");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor OV7660\n");
break;
case SENSOR_OV7670:
- PDEBUG(D_PROBE, "Find Sensor OV7670");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor OV7670\n");
break;
case SENSOR_PO1200:
- PDEBUG(D_PROBE, "Find Sensor PO1200");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor PO1200\n");
break;
case SENSOR_PO3130NC:
- PDEBUG(D_PROBE, "Find Sensor PO3130NC");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor PO3130NC\n");
break;
case SENSOR_POxxxx:
- PDEBUG(D_PROBE, "Sensor POxxxx");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor POxxxx\n");
break;
}
sd->sensor = sensor;
@@ -3624,8 +3627,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
if (data[0] == 0xff && data[1] == 0xd8) {
- PDEBUG(D_PACK,
- "vc032x header packet found len %d", len);
+ gspca_dbg(gspca_dev, D_PACK,
+ "vc032x header packet found len %d\n", len);
gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
data += sd->image_offset;
len -= sd->image_offset;
diff --git a/drivers/media/usb/gspca/w996Xcf.c b/drivers/media/usb/gspca/w996Xcf.c
index 728d2322c433..abfab3de1866 100644
--- a/drivers/media/usb/gspca/w996Xcf.c
+++ b/drivers/media/usb/gspca/w996Xcf.c
@@ -245,7 +245,7 @@ static void w9968cf_smbus_read_ack(struct sd *sd)
sda = w9968cf_read_sb(sd);
w9968cf_write_sb(sd, 0x0012); /* SDE=1, SDA=1, SCL=0 */
if (sda >= 0 && (sda & 0x08)) {
- PDEBUG(D_USBI, "Did not receive i2c ACK");
+ gspca_dbg(gspca_dev, D_USBI, "Did not receive i2c ACK\n");
sd->gspca_dev.usb_err = -EIO;
}
}
@@ -297,7 +297,7 @@ static void w9968cf_i2c_w(struct sd *sd, u8 reg, u8 value)
w9968cf_write_fsb(sd, data);
- PDEBUG(D_USBO, "i2c 0x%02x -> [0x%02x]", value, reg);
+ gspca_dbg(gspca_dev, D_USBO, "i2c 0x%02x -> [0x%02x]\n", value, reg);
}
/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
@@ -331,9 +331,10 @@ static int w9968cf_i2c_r(struct sd *sd, u8 reg)
if (sd->gspca_dev.usb_err >= 0) {
ret = value;
- PDEBUG(D_USBI, "i2c [0x%02X] -> 0x%02X", reg, value);
+ gspca_dbg(gspca_dev, D_USBI, "i2c [0x%02X] -> 0x%02X\n",
+ reg, value);
} else
- PERR("i2c read [0x%02x] failed", reg);
+ gspca_err(gspca_dev, "i2c read [0x%02x] failed\n", reg);
return ret;
}
diff --git a/drivers/media/usb/gspca/xirlink_cit.c b/drivers/media/usb/gspca/xirlink_cit.c
index 68656e7986c7..58deb0c38826 100644
--- a/drivers/media/usb/gspca/xirlink_cit.c
+++ b/drivers/media/usb/gspca/xirlink_cit.c
@@ -704,7 +704,8 @@ static int cit_read_reg(struct gspca_dev *gspca_dev, u16 index, int verbose)
}
if (verbose)
- PDEBUG(D_PROBE, "Register %04x value: %02x", index, buf[0]);
+ gspca_dbg(gspca_dev, D_PROBE, "Register %04x value: %02x\n",
+ index, buf[0]);
return 0;
}
@@ -1471,10 +1472,11 @@ static int cit_get_clock_div(struct gspca_dev *gspca_dev)
fps[clock_div - 1] * 3 / 2)
clock_div--;
- PDEBUG(D_PROBE,
- "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)",
- packet_size, gspca_dev->pixfmt.width, gspca_dev->pixfmt.height,
- clock_div, fps[clock_div]);
+ gspca_dbg(gspca_dev, D_PROBE,
+ "PacketSize: %d, res: %dx%d -> using clockdiv: %d (%d fps)\n",
+ packet_size,
+ gspca_dev->pixfmt.width, gspca_dev->pixfmt.height,
+ clock_div, fps[clock_div]);
return clock_div;
}
@@ -2865,17 +2867,17 @@ static u8 *cit_find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
sd->sof_read = 0;
if (data[i] == 0xff) {
if (i >= 4)
- PDEBUG(D_FRAM,
- "header found at offset: %d: %02x %02x 00 %3ph\n",
- i - 1,
- data[i - 4],
- data[i - 3],
- &data[i]);
+ gspca_dbg(gspca_dev, D_FRAM,
+ "header found at offset: %d: %02x %02x 00 %3ph\n\n",
+ i - 1,
+ data[i - 4],
+ data[i - 3],
+ &data[i]);
else
- PDEBUG(D_FRAM,
- "header found at offset: %d: 00 %3ph\n",
- i - 1,
- &data[i]);
+ gspca_dbg(gspca_dev, D_FRAM,
+ "header found at offset: %d: 00 %3ph\n\n",
+ i - 1,
+ &data[i]);
return data + i + (sd->sof_len - 1);
}
break;
diff --git a/drivers/media/usb/gspca/zc3xx.c b/drivers/media/usb/gspca/zc3xx.c
index e2d486bd8c28..25b4dbe8e049 100644
--- a/drivers/media/usb/gspca/zc3xx.c
+++ b/drivers/media/usb/gspca/zc3xx.c
@@ -6041,7 +6041,7 @@ static int sif_probe(struct gspca_dev *gspca_dev)
msleep(150);
checkword = ((i2c_read(gspca_dev, 0x00) & 0x0f) << 4)
| ((i2c_read(gspca_dev, 0x01) & 0xf0) >> 4);
- PDEBUG(D_PROBE, "probe sif 0x%04x", checkword);
+ gspca_dbg(gspca_dev, D_PROBE, "probe sif 0x%04x\n", checkword);
if (checkword == 0x0007) {
send_unknown(gspca_dev, SENSOR_PAS106);
return 0x0f; /* PAS106 */
@@ -6129,7 +6129,7 @@ ov_check:
i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */
retword = i2c_read(gspca_dev, 0x0a) << 8;
retword |= i2c_read(gspca_dev, 0x0b);
- PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword);
+ gspca_dbg(gspca_dev, D_PROBE, "probe 2wr ov vga 0x%04x\n", retword);
switch (retword) {
case 0x7631: /* OV7630C */
reg_w(gspca_dev, 0x06, 0x0010);
@@ -6186,7 +6186,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x02, 0x0010);
retword = reg_r(gspca_dev, 0x000b) << 8;
retword |= reg_r(gspca_dev, 0x000a);
- PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
+ gspca_dbg(gspca_dev, D_PROBE, "probe 3wr vga 1 0x%04x\n", retword);
reg_r(gspca_dev, 0x0010);
if ((retword & 0xff00) == 0x6400)
return 0x02; /* TAS5130C */
@@ -6206,7 +6206,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x01, 0x0012);
retword = i2c_read(gspca_dev, 0x00);
if (retword != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type 0a");
+ gspca_dbg(gspca_dev, D_PROBE, "probe 3wr vga type 0a\n");
return 0x0a; /* PB0330 */
}
@@ -6220,7 +6220,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x01, 0x0012);
retword = i2c_read(gspca_dev, 0x00);
if (retword != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword);
+ gspca_dbg(gspca_dev, D_PROBE, "probe 3wr vga type %02x\n",
+ retword);
if (retword == 0x0011) /* gc0303 */
return 0x0303;
if (retword == 0x0029) /* gc0305 */
@@ -6251,12 +6252,13 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x05, 0x0012);
retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */
retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */
- PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
+ gspca_dbg(gspca_dev, D_PROBE, "probe 3wr vga 2 0x%04x\n", retword);
if (retword == 0x2030) {
u8 retbyte;
retbyte = i2c_read(gspca_dev, 0x02); /* revision number */
- PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
+ gspca_dbg(gspca_dev, D_PROBE, "sensor PO2030 rev 0x%02x\n",
+ retbyte);
send_unknown(gspca_dev, SENSOR_PO2030);
return retword;
@@ -6272,7 +6274,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0xd3, 0x008b);
retword = i2c_read(gspca_dev, 0x01);
if (retword != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
+ gspca_dbg(gspca_dev, D_PROBE, "probe 3wr vga type 0a ? ret: %04x\n",
+ retword);
return 0x16; /* adcm2700 (6100/6200) */
}
return -1;
@@ -6490,19 +6493,20 @@ static int sd_init(struct gspca_dev *gspca_dev)
sensor = zcxx_probeSensor(gspca_dev);
if (sensor >= 0)
- PDEBUG(D_PROBE, "probe sensor -> %04x", sensor);
+ gspca_dbg(gspca_dev, D_PROBE, "probe sensor -> %04x\n", sensor);
if ((unsigned) force_sensor < SENSOR_MAX) {
sd->sensor = force_sensor;
- PDEBUG(D_PROBE, "sensor forced to %d", force_sensor);
+ gspca_dbg(gspca_dev, D_PROBE, "sensor forced to %d\n",
+ force_sensor);
} else {
switch (sensor) {
case -1:
switch (sd->sensor) {
case SENSOR_MC501CB:
- PDEBUG(D_PROBE, "Sensor MC501CB");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor MC501CB\n");
break;
case SENSOR_GC0303:
- PDEBUG(D_PROBE, "Sensor GC0303");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor GC0303\n");
break;
default:
pr_warn("Unknown sensor - set to TAS5130C\n");
@@ -6512,100 +6516,101 @@ static int sd_init(struct gspca_dev *gspca_dev)
case 0:
/* check the sensor type */
sensor = i2c_read(gspca_dev, 0x00);
- PDEBUG(D_PROBE, "Sensor hv7131 type %d", sensor);
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor hv7131 type %d\n",
+ sensor);
switch (sensor) {
case 0: /* hv7131b */
case 1: /* hv7131e */
- PDEBUG(D_PROBE, "Find Sensor HV7131B");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor HV7131B\n");
sd->sensor = SENSOR_HV7131B;
break;
default:
/* case 2: * hv7131r */
- PDEBUG(D_PROBE, "Find Sensor HV7131R");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor HV7131R\n");
sd->sensor = SENSOR_HV7131R;
break;
}
break;
case 0x02:
- PDEBUG(D_PROBE, "Sensor TAS5130C");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor TAS5130C\n");
sd->sensor = SENSOR_TAS5130C;
break;
case 0x04:
- PDEBUG(D_PROBE, "Find Sensor CS2102");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor CS2102\n");
sd->sensor = SENSOR_CS2102;
break;
case 0x08:
- PDEBUG(D_PROBE, "Find Sensor HDCS2020");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor HDCS2020\n");
sd->sensor = SENSOR_HDCS2020;
break;
case 0x0a:
- PDEBUG(D_PROBE,
- "Find Sensor PB0330. Chip revision %x",
- sd->chip_revision);
+ gspca_dbg(gspca_dev, D_PROBE,
+ "Find Sensor PB0330. Chip revision %x\n",
+ sd->chip_revision);
sd->sensor = SENSOR_PB0330;
break;
case 0x0c:
- PDEBUG(D_PROBE, "Find Sensor ICM105A");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor ICM105A\n");
sd->sensor = SENSOR_ICM105A;
break;
case 0x0e:
- PDEBUG(D_PROBE, "Find Sensor PAS202B");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor PAS202B\n");
sd->sensor = SENSOR_PAS202B;
break;
case 0x0f:
- PDEBUG(D_PROBE, "Find Sensor PAS106");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor PAS106\n");
sd->sensor = SENSOR_PAS106;
break;
case 0x10:
case 0x12:
- PDEBUG(D_PROBE, "Find Sensor TAS5130C");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor TAS5130C\n");
sd->sensor = SENSOR_TAS5130C;
break;
case 0x11:
- PDEBUG(D_PROBE, "Find Sensor HV7131R");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor HV7131R\n");
sd->sensor = SENSOR_HV7131R;
break;
case 0x13:
case 0x15:
- PDEBUG(D_PROBE,
- "Sensor MT9V111. Chip revision %04x",
- sd->chip_revision);
+ gspca_dbg(gspca_dev, D_PROBE,
+ "Sensor MT9V111. Chip revision %04x\n",
+ sd->chip_revision);
sd->sensor = sd->bridge == BRIDGE_ZC301
? SENSOR_MT9V111_1
: SENSOR_MT9V111_3;
break;
case 0x14:
- PDEBUG(D_PROBE,
- "Find Sensor CS2102K?. Chip revision %x",
- sd->chip_revision);
+ gspca_dbg(gspca_dev, D_PROBE,
+ "Find Sensor CS2102K?. Chip revision %x\n",
+ sd->chip_revision);
sd->sensor = SENSOR_CS2102K;
break;
case 0x16:
- PDEBUG(D_PROBE, "Find Sensor ADCM2700");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor ADCM2700\n");
sd->sensor = SENSOR_ADCM2700;
break;
case 0x29:
- PDEBUG(D_PROBE, "Find Sensor GC0305");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor GC0305\n");
sd->sensor = SENSOR_GC0305;
break;
case 0x0303:
- PDEBUG(D_PROBE, "Sensor GC0303");
+ gspca_dbg(gspca_dev, D_PROBE, "Sensor GC0303\n");
sd->sensor = SENSOR_GC0303;
break;
case 0x2030:
- PDEBUG(D_PROBE, "Find Sensor PO2030");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor PO2030\n");
sd->sensor = SENSOR_PO2030;
break;
case 0x7620:
- PDEBUG(D_PROBE, "Find Sensor OV7620");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor OV7620\n");
sd->sensor = SENSOR_OV7620;
break;
case 0x7631:
- PDEBUG(D_PROBE, "Find Sensor OV7630C");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor OV7630C\n");
sd->sensor = SENSOR_OV7630C;
break;
case 0x7648:
- PDEBUG(D_PROBE, "Find Sensor OV7648");
+ gspca_dbg(gspca_dev, D_PROBE, "Find Sensor OV7648\n");
sd->sensor = SENSOR_OV7620; /* same sensor (?) */
break;
default:
diff --git a/drivers/media/usb/hdpvr/Makefile b/drivers/media/usb/hdpvr/Makefile
index 9b8d1463c526..644dd99ffce3 100644
--- a/drivers/media/usb/hdpvr/Makefile
+++ b/drivers/media/usb/hdpvr/Makefile
@@ -1,7 +1,3 @@
hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o hdpvr-i2c.o
obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o
-
-ccflags-y += -Idrivers/media/i2c
-
-ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c
index dbe29c6c4d8b..29ac7fc5b039 100644
--- a/drivers/media/usb/hdpvr/hdpvr-core.c
+++ b/drivers/media/usb/hdpvr/hdpvr-core.c
@@ -292,7 +292,7 @@ static int hdpvr_probe(struct usb_interface *interface,
/* register v4l2_device early so it can be used for printks */
if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
dev_err(&interface->dev, "v4l2_device_register failed\n");
- goto error;
+ goto error_free_dev;
}
mutex_init(&dev->io_mutex);
@@ -301,7 +301,7 @@ static int hdpvr_probe(struct usb_interface *interface,
dev->usbc_buf = kmalloc(64, GFP_KERNEL);
if (!dev->usbc_buf) {
v4l2_err(&dev->v4l2_dev, "Out of memory\n");
- goto error;
+ goto error_v4l2_unregister;
}
init_waitqueue_head(&dev->wait_buffer);
@@ -339,13 +339,13 @@ static int hdpvr_probe(struct usb_interface *interface,
}
if (!dev->bulk_in_endpointAddr) {
v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n");
- goto error;
+ goto error_put_usb;
}
/* init the device */
if (hdpvr_device_init(dev)) {
v4l2_err(&dev->v4l2_dev, "device init failed\n");
- goto error;
+ goto error_put_usb;
}
mutex_lock(&dev->io_mutex);
@@ -353,7 +353,7 @@ static int hdpvr_probe(struct usb_interface *interface,
mutex_unlock(&dev->io_mutex);
v4l2_err(&dev->v4l2_dev,
"allocating transfer buffers failed\n");
- goto error;
+ goto error_put_usb;
}
mutex_unlock(&dev->io_mutex);
@@ -361,19 +361,12 @@ static int hdpvr_probe(struct usb_interface *interface,
retval = hdpvr_register_i2c_adapter(dev);
if (retval < 0) {
v4l2_err(&dev->v4l2_dev, "i2c adapter register failed\n");
- goto error;
- }
-
- client = hdpvr_register_ir_rx_i2c(dev);
- if (!client) {
- v4l2_err(&dev->v4l2_dev, "i2c IR RX device register failed\n");
- retval = -ENODEV;
- goto reg_fail;
+ goto error_free_buffers;
}
- client = hdpvr_register_ir_tx_i2c(dev);
+ client = hdpvr_register_ir_i2c(dev);
if (!client) {
- v4l2_err(&dev->v4l2_dev, "i2c IR TX device register failed\n");
+ v4l2_err(&dev->v4l2_dev, "i2c IR device register failed\n");
retval = -ENODEV;
goto reg_fail;
}
@@ -394,13 +387,17 @@ static int hdpvr_probe(struct usb_interface *interface,
reg_fail:
#if IS_ENABLED(CONFIG_I2C)
i2c_del_adapter(&dev->i2c_adapter);
+error_free_buffers:
#endif
+ hdpvr_free_buffers(dev);
+error_put_usb:
+ usb_put_dev(dev->udev);
+ kfree(dev->usbc_buf);
+error_v4l2_unregister:
+ v4l2_device_unregister(&dev->v4l2_dev);
+error_free_dev:
+ kfree(dev);
error:
- if (dev) {
- flush_work(&dev->worker);
- /* this frees allocated memory */
- hdpvr_delete(dev);
- }
return retval;
}
diff --git a/drivers/media/usb/hdpvr/hdpvr-i2c.c b/drivers/media/usb/hdpvr/hdpvr-i2c.c
index 1db49ed5eaf1..4720d79b0282 100644
--- a/drivers/media/usb/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/usb/hdpvr/hdpvr-i2c.c
@@ -32,24 +32,11 @@
#define Z8F0811_IR_RX_I2C_ADDR 0x71
-struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev)
+struct i2c_client *hdpvr_register_ir_i2c(struct hdpvr_device *dev)
{
struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
- struct i2c_board_info hdpvr_ir_tx_i2c_board_info = {
- I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR),
- };
-
- init_data->name = "HD-PVR";
- hdpvr_ir_tx_i2c_board_info.platform_data = init_data;
-
- return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_tx_i2c_board_info);
-}
-
-struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev)
-{
- struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data;
- struct i2c_board_info hdpvr_ir_rx_i2c_board_info = {
- I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
+ struct i2c_board_info info = {
+ I2C_BOARD_INFO("ir_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR),
};
/* Our default information for ir-kbd-i2c.c to use */
@@ -59,9 +46,9 @@ struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev)
RC_PROTO_BIT_RC6_6A_32;
init_data->name = "HD-PVR";
init_data->polling_interval = 405; /* ms, duplicated from Windows */
- hdpvr_ir_rx_i2c_board_info.platform_data = init_data;
+ info.platform_data = init_data;
- return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info);
+ return i2c_new_device(&dev->i2c_adapter, &info);
}
static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c
index d0d638c2e900..660d4a65401f 100644
--- a/drivers/media/usb/hdpvr/hdpvr-video.c
+++ b/drivers/media/usb/hdpvr/hdpvr-video.c
@@ -941,18 +941,18 @@ static int hdpvr_s_ctrl(struct v4l2_ctrl *ctrl)
return 0;
case V4L2_CID_MPEG_VIDEO_ENCODING:
return 0;
-/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
-/* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
-/* opt->gop_mode |= 0x2; */
-/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
-/* opt->gop_mode); */
-/* } */
-/* if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
-/* opt->gop_mode &= ~0x2; */
-/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
-/* opt->gop_mode); */
-/* } */
-/* break; */
+/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
+/* opt->gop_mode |= 0x2; */
+/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
+/* opt->gop_mode); */
+/* } */
+/* if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
+/* opt->gop_mode &= ~0x2; */
+/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
+/* opt->gop_mode); */
+/* } */
+/* break; */
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE: {
uint peak_bitrate = dev->video_bitrate_peak->val / 100000;
uint bitrate = dev->video_bitrate->val / 100000;
@@ -1154,7 +1154,7 @@ static void hdpvr_device_release(struct video_device *vdev)
static const struct video_device hdpvr_video_template = {
.fops = &hdpvr_fops,
.release = hdpvr_device_release,
- .ioctl_ops = &hdpvr_ioctl_ops,
+ .ioctl_ops = &hdpvr_ioctl_ops,
.tvnorms = V4L2_STD_ALL,
};
diff --git a/drivers/media/usb/hdpvr/hdpvr.h b/drivers/media/usb/hdpvr/hdpvr.h
index a12e0af1d4e1..1d65b4185f57 100644
--- a/drivers/media/usb/hdpvr/hdpvr.h
+++ b/drivers/media/usb/hdpvr/hdpvr.h
@@ -232,15 +232,15 @@ enum {
/* :0 s 38 d3 0000 0000 0001 1 = 00 */
-/* ret = usb_control_msg(dev->udev, */
-/* usb_sndctrlpipe(dev->udev, 0), */
-/* 0xd3, 0x38, */
-/* 0, 0, */
-/* "\0", 1, */
-/* 1000); */
+/* ret = usb_control_msg(dev->udev, */
+/* usb_sndctrlpipe(dev->udev, 0), */
+/* 0xd3, 0x38, */
+/* 0, 0, */
+/* "\0", 1, */
+/* 1000); */
-/* info("control request returned %d", ret); */
-/* msleep(5000); */
+/* info("control request returned %d", ret); */
+/* msleep(5000); */
/* :0 s b8 81 1400 0003 0005 5 <
@@ -320,8 +320,7 @@ int hdpvr_cancel_queue(struct hdpvr_device *dev);
/* i2c adapter registration */
int hdpvr_register_i2c_adapter(struct hdpvr_device *dev);
-struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev);
-struct i2c_client *hdpvr_register_ir_tx_i2c(struct hdpvr_device *dev);
+struct i2c_client *hdpvr_register_ir_i2c(struct hdpvr_device *dev);
/*========================================================================*/
/* buffer management */
diff --git a/drivers/media/usb/pulse8-cec/pulse8-cec.c b/drivers/media/usb/pulse8-cec/pulse8-cec.c
index 50146f263d90..350635826aae 100644
--- a/drivers/media/usb/pulse8-cec/pulse8-cec.c
+++ b/drivers/media/usb/pulse8-cec/pulse8-cec.c
@@ -329,7 +329,7 @@ static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio,
u8 cmd[2];
int err;
struct tm tm;
- time_t date;
+ time64_t date;
pulse8->vers = 0;
@@ -349,7 +349,7 @@ static int pulse8_setup(struct pulse8 *pulse8, struct serio *serio,
if (err)
return err;
date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- time_to_tm(date, 0, &tm);
+ time64_to_tm(date, 0, &tm);
dev_info(pulse8->dev, "Firmware build date %04ld.%02d.%02d %02d:%02d:%02d\n",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
diff --git a/drivers/media/usb/pvrusb2/Makefile b/drivers/media/usb/pvrusb2/Makefile
index 0d84064036b2..9facf6873404 100644
--- a/drivers/media/usb/pvrusb2/Makefile
+++ b/drivers/media/usb/pvrusb2/Makefile
@@ -17,7 +17,5 @@ pvrusb2-objs := pvrusb2-i2c-core.o \
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.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/usb/pvrusb2/pvrusb2-devattr.c b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
index 51b3312eaea1..71537097c13f 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-devattr.c
@@ -319,12 +319,12 @@ static struct tda829x_config tda829x_no_probe = {
};
static struct tda18271_std_map hauppauge_tda18271_dvbt_std_map = {
- .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x37, },
- .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6,
- .if_lvl = 1, .rfagc_top = 0x37, },
+ .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4,
+ .if_lvl = 1, .rfagc_top = 0x37, },
+ .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5,
+ .if_lvl = 1, .rfagc_top = 0x37, },
+ .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6,
+ .if_lvl = 1, .rfagc_top = 0x37, },
};
static struct tda18271_config hauppauge_tda18271_dvb_config = {
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
index 56c750535ee7..4b32b2141169 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -18,7 +18,7 @@
#include <linux/freezer.h>
#include <linux/slab.h>
#include <linux/mm.h>
-#include "dvbdev.h"
+#include <media/dvbdev.h>
#include "pvrusb2-debug.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-hdw.h"
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
index b500c86d4178..e7f71fb94a6e 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
+++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.h
@@ -2,10 +2,10 @@
#ifndef __PVRUSB2_DVB_H__
#define __PVRUSB2_DVB_H__
-#include "dvb_frontend.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
-#include "dmxdev.h"
+#include <media/dvb_frontend.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dmxdev.h>
#include "pvrusb2-context.h"
#define PVR2_DVB_BUFFER_COUNT 32
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
index 8289ee482f49..e0353161ccd6 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
@@ -2351,7 +2351,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
if (hdw_desc == NULL) {
pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_create: No device description pointer, unable to continue.");
- pvr2_trace(PVR2_TRACE_INIT, "If you have a new device type, please contact Mike Isely <isely@pobox.com> to get it included in the driver\n");
+ pvr2_trace(PVR2_TRACE_INIT,
+ "If you have a new device type, please contact Mike Isely <isely@pobox.com> to get it included in the driver");
goto fail;
}
@@ -3648,6 +3649,12 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
hdw);
hdw->ctl_write_urb->actual_length = 0;
hdw->ctl_write_pend_flag = !0;
+ if (usb_urb_ep_type_check(hdw->ctl_write_urb)) {
+ pvr2_trace(
+ PVR2_TRACE_ERROR_LEGS,
+ "Invalid write control endpoint");
+ return -EINVAL;
+ }
status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
if (status < 0) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
@@ -3672,6 +3679,12 @@ status);
hdw);
hdw->ctl_read_urb->actual_length = 0;
hdw->ctl_read_pend_flag = !0;
+ if (usb_urb_ep_type_check(hdw->ctl_read_urb)) {
+ pvr2_trace(
+ PVR2_TRACE_ERROR_LEGS,
+ "Invalid read control endpoint");
+ return -EINVAL;
+ }
status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
if (status < 0) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
index ff7b4d1d385d..f3003ca05f4b 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-i2c-core.c
@@ -585,17 +585,10 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
init_data->type = RC_PROTO_BIT_RC5 | RC_PROTO_BIT_RC6_MCE |
RC_PROTO_BIT_RC6_6A_32;
init_data->name = hdw->hdw_desc->description;
- /* IR Receiver */
- info.addr = 0x71;
- info.platform_data = init_data;
- strlcpy(info.type, "ir_rx_z8f0811_haup", I2C_NAME_SIZE);
- pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
- info.type, info.addr);
- i2c_new_device(&hdw->i2c_adap, &info);
- /* IR Trasmitter */
- info.addr = 0x70;
+ /* IR Transceiver */
+ info.addr = 0x71;
info.platform_data = init_data;
- strlcpy(info.type, "ir_tx_z8f0811_haup", I2C_NAME_SIZE);
+ strlcpy(info.type, "ir_z8f0811_haup", I2C_NAME_SIZE);
pvr2_trace(PVR2_TRACE_INFO, "Binding %s to i2c address 0x%02x.",
info.type, info.addr);
i2c_new_device(&hdw->i2c_adap, &info);
diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
index 11cdfe356801..ad6290e1b699 100644
--- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -78,18 +78,6 @@ static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
module_param_array(vbi_nr, int, NULL, 0444);
MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
-static struct v4l2_fmtdesc pvr_fmtdesc [] = {
- {
- .index = 0,
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- .flags = V4L2_FMT_FLAG_COMPRESSED,
- .description = "MPEG1/2",
- // This should really be V4L2_PIX_FMT_MPEG, but xawtv
- // breaks when I do that.
- .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
- }
-};
-
#define PVR_FORMAT_PIX 0
#define PVR_FORMAT_VBI 1
@@ -99,17 +87,11 @@ static struct v4l2_format pvr_format [] = {
.fmt = {
.pix = {
.width = 720,
- .height = 576,
- // This should really be V4L2_PIX_FMT_MPEG,
- // but xawtv breaks when I do that.
- .pixelformat = 0, // V4L2_PIX_FMT_MPEG,
+ .height = 576,
+ .pixelformat = V4L2_PIX_FMT_MPEG,
.field = V4L2_FIELD_INTERLACED,
- .bytesperline = 0, // doesn't make sense
- // here
- //FIXME : Don't know what to put here...
- .sizeimage = (32*1024),
- .colorspace = 0, // doesn't make sense here
- .priv = 0
+ /* FIXME : Don't know what to put here... */
+ .sizeimage = 32 * 1024,
}
}
},
@@ -153,6 +135,8 @@ static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *
case VFL_TYPE_RADIO:
cap->device_caps = V4L2_CAP_RADIO;
break;
+ default:
+ return -EINVAL;
}
cap->device_caps |= V4L2_CAP_TUNER | V4L2_CAP_READWRITE;
return 0;
@@ -407,11 +391,11 @@ static int pvr2_g_frequency(struct file *file, void *priv, struct v4l2_frequency
static int pvr2_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fd)
{
- /* Only one format is supported : mpeg.*/
- if (fd->index != 0)
+ /* Only one format is supported: MPEG. */
+ if (fd->index)
return -EINVAL;
- memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
+ fd->pixelformat = V4L2_PIX_FMT_MPEG;
return 0;
}
diff --git a/drivers/media/usb/pwc/pwc.h b/drivers/media/usb/pwc/pwc.h
index 3c73bdaae450..67010010d2a2 100644
--- a/drivers/media/usb/pwc/pwc.h
+++ b/drivers/media/usb/pwc/pwc.h
@@ -50,7 +50,7 @@
/* Version block */
#define PWC_VERSION "10.0.15"
-#define PWC_NAME "pwc"
+#define PWC_NAME "pwc"
#define PFX PWC_NAME ": "
@@ -120,10 +120,10 @@
#define MAX_ISO_BUFS 3
#define ISO_FRAMES_PER_DESC 10
#define ISO_MAX_FRAME_SIZE 960
-#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
+#define ISO_BUFFER_SIZE (ISO_FRAMES_PER_DESC * ISO_MAX_FRAME_SIZE)
/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
-#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
+#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
/* Absolute minimum and maximum number of buffers available for mmap() */
#define MIN_FRAMES 2
diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c
index 7fee5766587a..8c2a86d71e8a 100644
--- a/drivers/media/usb/s2255/s2255drv.c
+++ b/drivers/media/usb/s2255/s2255drv.c
@@ -350,7 +350,7 @@ static void s2255_fillbuff(struct s2255_vc *vc, struct s2255_buffer *buf,
int jpgsize);
static int s2255_set_mode(struct s2255_vc *vc, struct s2255_mode *mode);
static int s2255_board_shutdown(struct s2255_dev *dev);
-static void s2255_fwload_start(struct s2255_dev *dev, int reset);
+static void s2255_fwload_start(struct s2255_dev *dev);
static void s2255_destroy(struct s2255_dev *dev);
static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
u16 index, u16 value, void *buf,
@@ -476,7 +476,7 @@ static void planar422p_to_yuv_packed(const unsigned char *in,
static void s2255_reset_dsppower(struct s2255_dev *dev)
{
s2255_vendor_req(dev, 0x40, 0x0000, 0x0001, NULL, 0, 1);
- msleep(20);
+ msleep(50);
s2255_vendor_req(dev, 0x50, 0x0000, 0x0000, NULL, 0, 1);
msleep(600);
s2255_vendor_req(dev, 0x10, 0x0000, 0x0000, NULL, 0, 1);
@@ -1450,7 +1450,7 @@ static int s2255_open(struct file *file)
case S2255_FW_FAILED:
s2255_dev_err(&dev->udev->dev,
"firmware load failed. retrying.\n");
- s2255_fwload_start(dev, 1);
+ s2255_fwload_start(dev);
wait_event_timeout(dev->fw_data->wait_fw,
((atomic_read(&dev->fw_data->fw_state)
== S2255_FW_SUCCESS) ||
@@ -2209,10 +2209,9 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
return;
}
-static void s2255_fwload_start(struct s2255_dev *dev, int reset)
+static void s2255_fwload_start(struct s2255_dev *dev)
{
- if (reset)
- s2255_reset_dsppower(dev);
+ s2255_reset_dsppower(dev);
dev->fw_data->fw_size = dev->fw_data->fw->size;
atomic_set(&dev->fw_data->fw_state, S2255_FW_NOTLOADED);
memcpy(dev->fw_data->pfw_data,
@@ -2337,7 +2336,7 @@ static int s2255_probe(struct usb_interface *interface,
retval = s2255_board_init(dev);
if (retval)
goto errorBOARDINIT;
- s2255_fwload_start(dev, 0);
+ s2255_fwload_start(dev);
/* loads v4l specific */
retval = s2255_probe_v4l(dev);
if (retval)
diff --git a/drivers/media/usb/siano/Makefile b/drivers/media/usb/siano/Makefile
index 758b6a090c59..7d48864e2782 100644
--- a/drivers/media/usb/siano/Makefile
+++ b/drivers/media/usb/siano/Makefile
@@ -1,6 +1,5 @@
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/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
index d07349cf9489..f13e4b01b5a5 100644
--- a/drivers/media/usb/siano/smsusb.c
+++ b/drivers/media/usb/siano/smsusb.c
@@ -61,7 +61,7 @@ struct smsusb_device_t {
struct usb_device *udev;
struct smscore_device_t *coredev;
- struct smsusb_urb_t surbs[MAX_URBS];
+ struct smsusb_urb_t surbs[MAX_URBS];
int response_alignment;
int buffer_size;
diff --git a/drivers/media/usb/stk1160/Makefile b/drivers/media/usb/stk1160/Makefile
index 613471528749..b943db01ccf7 100644
--- a/drivers/media/usb/stk1160/Makefile
+++ b/drivers/media/usb/stk1160/Makefile
@@ -1,10 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
-stk1160-y := stk1160-core.o \
+stk1160-y := stk1160-core.o \
stk1160-v4l.o \
stk1160-video.o \
stk1160-i2c.o \
stk1160-ac97.o
obj-$(CONFIG_VIDEO_STK1160) += stk1160.o
-
-ccflags-y += -Idrivers/media/i2c
diff --git a/drivers/media/usb/stkwebcam/stk-sensor.c b/drivers/media/usb/stkwebcam/stk-sensor.c
index c1d4505f84ea..9a7dbeff1337 100644
--- a/drivers/media/usb/stkwebcam/stk-sensor.c
+++ b/drivers/media/usb/stkwebcam/stk-sensor.c
@@ -397,12 +397,12 @@ int stk_sensor_init(struct stk_camera *dev)
/* V4L2_PIX_FMT_UYVY */
static struct regval ov_fmt_uyvy[] = {
{REG_TSLB, TSLB_YLAST|0x08 },
- { 0x4f, 0x80 }, /* "matrix coefficient 1" */
- { 0x50, 0x80 }, /* "matrix coefficient 2" */
+ { 0x4f, 0x80 }, /* "matrix coefficient 1" */
+ { 0x50, 0x80 }, /* "matrix coefficient 2" */
{ 0x51, 0 }, /* vb */
- { 0x52, 0x22 }, /* "matrix coefficient 4" */
- { 0x53, 0x5e }, /* "matrix coefficient 5" */
- { 0x54, 0x80 }, /* "matrix coefficient 6" */
+ { 0x52, 0x22 }, /* "matrix coefficient 4" */
+ { 0x53, 0x5e }, /* "matrix coefficient 5" */
+ { 0x54, 0x80 }, /* "matrix coefficient 6" */
{REG_COM13, COM13_UVSAT|COM13_CMATRIX},
{REG_COM15, COM15_R00FF },
{0xff, 0xff}, /* END MARKER */
@@ -410,12 +410,12 @@ static struct regval ov_fmt_uyvy[] = {
/* V4L2_PIX_FMT_YUYV */
static struct regval ov_fmt_yuyv[] = {
{REG_TSLB, 0 },
- { 0x4f, 0x80 }, /* "matrix coefficient 1" */
- { 0x50, 0x80 }, /* "matrix coefficient 2" */
+ { 0x4f, 0x80 }, /* "matrix coefficient 1" */
+ { 0x50, 0x80 }, /* "matrix coefficient 2" */
{ 0x51, 0 }, /* vb */
- { 0x52, 0x22 }, /* "matrix coefficient 4" */
- { 0x53, 0x5e }, /* "matrix coefficient 5" */
- { 0x54, 0x80 }, /* "matrix coefficient 6" */
+ { 0x52, 0x22 }, /* "matrix coefficient 4" */
+ { 0x53, 0x5e }, /* "matrix coefficient 5" */
+ { 0x54, 0x80 }, /* "matrix coefficient 6" */
{REG_COM13, COM13_UVSAT|COM13_CMATRIX},
{REG_COM15, COM15_R00FF },
{0xff, 0xff}, /* END MARKER */
@@ -426,13 +426,13 @@ static struct regval ov_fmt_rgbr[] = {
{ REG_RGB444, 0 }, /* No RGB444 please */
{REG_TSLB, 0x00},
{ REG_COM1, 0x0 },
- { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
- { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
- { 0x50, 0xb3 }, /* "matrix coefficient 2" */
+ { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
+ { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
+ { 0x50, 0xb3 }, /* "matrix coefficient 2" */
{ 0x51, 0 }, /* vb */
- { 0x52, 0x3d }, /* "matrix coefficient 4" */
- { 0x53, 0xa7 }, /* "matrix coefficient 5" */
- { 0x54, 0xe4 }, /* "matrix coefficient 6" */
+ { 0x52, 0x3d }, /* "matrix coefficient 4" */
+ { 0x53, 0xa7 }, /* "matrix coefficient 5" */
+ { 0x54, 0xe4 }, /* "matrix coefficient 6" */
{ REG_COM13, COM13_GAMMA },
{ REG_COM15, COM15_RGB565|COM15_R00FF },
{ 0xff, 0xff },
@@ -443,13 +443,13 @@ static struct regval ov_fmt_rgbp[] = {
{ REG_RGB444, 0 }, /* No RGB444 please */
{REG_TSLB, TSLB_BYTEORD },
{ REG_COM1, 0x0 },
- { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
- { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
- { 0x50, 0xb3 }, /* "matrix coefficient 2" */
+ { REG_COM9, 0x38 }, /* 16x gain ceiling; 0x8 is reserved bit */
+ { 0x4f, 0xb3 }, /* "matrix coefficient 1" */
+ { 0x50, 0xb3 }, /* "matrix coefficient 2" */
{ 0x51, 0 }, /* vb */
- { 0x52, 0x3d }, /* "matrix coefficient 4" */
- { 0x53, 0xa7 }, /* "matrix coefficient 5" */
- { 0x54, 0xe4 }, /* "matrix coefficient 6" */
+ { 0x52, 0x3d }, /* "matrix coefficient 4" */
+ { 0x53, 0xa7 }, /* "matrix coefficient 5" */
+ { 0x54, 0xe4 }, /* "matrix coefficient 6" */
{ REG_COM13, COM13_GAMMA },
{ REG_COM15, COM15_RGB565|COM15_R00FF },
{ 0xff, 0xff },
diff --git a/drivers/media/usb/stkwebcam/stk-webcam.c b/drivers/media/usb/stkwebcam/stk-webcam.c
index cba0916d33e5..17ad978c0172 100644
--- a/drivers/media/usb/stkwebcam/stk-webcam.c
+++ b/drivers/media/usb/stkwebcam/stk-webcam.c
@@ -1241,7 +1241,6 @@ static void stk_v4l_dev_release(struct video_device *vd)
if (dev->sio_bufs != NULL || dev->isobufs != NULL)
pr_err("We are leaking memory\n");
usb_put_intf(dev->interface);
- kfree(dev);
}
static const struct video_device stk_v4l_data = {
@@ -1391,6 +1390,7 @@ static void stk_camera_disconnect(struct usb_interface *interface)
video_unregister_device(&dev->vdev);
v4l2_ctrl_handler_free(&dev->hdl);
v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev);
}
#ifdef CONFIG_PM
diff --git a/drivers/media/usb/tm6000/Makefile b/drivers/media/usb/tm6000/Makefile
index 05322a72e862..744c039e621a 100644
--- a/drivers/media/usb/tm6000/Makefile
+++ b/drivers/media/usb/tm6000/Makefile
@@ -10,7 +10,5 @@ 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/i2c
ccflags-y += -Idrivers/media/tuners
-ccflags-y += -Idrivers/media/dvb-core
ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/tm6000/tm6000-alsa.c b/drivers/media/usb/tm6000/tm6000-alsa.c
index 3717a6844ea8..f18cffae4c85 100644
--- a/drivers/media/usb/tm6000/tm6000-alsa.c
+++ b/drivers/media/usb/tm6000/tm6000-alsa.c
@@ -1,14 +1,8 @@
-/*
- *
- * Support for audio capture for tm5600/6000/6010
- * (c) 2007-2008 Mauro Carvalho Chehab
- *
- * Based on cx88-alsa.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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// Support for audio capture for tm5600/6000/6010
+// Copyright (c) 2007-2008 Mauro Carvalho Chehab <mchehab@kernel.org>
+//
+// Based on cx88-alsa.c
#include <linux/module.h>
#include <linux/init.h>
@@ -57,7 +51,7 @@ MODULE_PARM_DESC(index, "Index value for tm6000x capture interface(s).");
MODULE_DESCRIPTION("ALSA driver module for tm5600/tm6000/tm6010 based TV cards");
MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
MODULE_SUPPORTED_DEVICE("{{Trident,tm5600},{{Trident,tm6000},{{Trident,tm6010}");
static unsigned int debug;
module_param(debug, int, 0644);
diff --git a/drivers/media/usb/tm6000/tm6000-cards.c b/drivers/media/usb/tm6000/tm6000-cards.c
index 77347541904d..4d5f4cc4887e 100644
--- a/drivers/media/usb/tm6000/tm6000-cards.c
+++ b/drivers/media/usb/tm6000/tm6000-cards.c
@@ -1,17 +1,7 @@
-/*
- * tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.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
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
+// SPDX-License-Identifier: GPL-2.0
+// tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+//
+// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
#include <linux/init.h>
#include <linux/module.h>
@@ -23,7 +13,6 @@
#include <media/v4l2-common.h>
#include <media/tuner.h>
#include <media/i2c/tvaudio.h>
-#include <media/i2c-addr.h>
#include <media/rc-map.h>
#include "tm6000.h"
@@ -1405,4 +1394,4 @@ module_usb_driver(tm6000_usb_driver);
MODULE_DESCRIPTION("Trident TVMaster TM5600/TM6000/TM6010 USB2 adapter");
MODULE_AUTHOR("Mauro Carvalho Chehab");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/usb/tm6000/tm6000-core.c b/drivers/media/usb/tm6000/tm6000-core.c
index 8c265bd80faa..23a1332d98e6 100644
--- a/drivers/media/usb/tm6000/tm6000-core.c
+++ b/drivers/media/usb/tm6000/tm6000-core.c
@@ -1,20 +1,10 @@
-/*
- * tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- * - DVB-T 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 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+//
+// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
+//
+// Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com>
+// - DVB-T support
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/drivers/media/usb/tm6000/tm6000-i2c.c b/drivers/media/usb/tm6000/tm6000-i2c.c
index cbcc1472f1c7..c9a62bbff27a 100644
--- a/drivers/media/usb/tm6000/tm6000-i2c.c
+++ b/drivers/media/usb/tm6000/tm6000-i2c.c
@@ -1,20 +1,10 @@
-/*
- * tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- * - Fix SMBus Read Byte command
- *
- * This program is free software; 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+//
+// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
+//
+// Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com>
+// - Fix SMBus Read Byte command
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/drivers/media/usb/tm6000/tm6000-regs.h b/drivers/media/usb/tm6000/tm6000-regs.h
index ab3fb74c476c..21587fcf11e3 100644
--- a/drivers/media/usb/tm6000/tm6000-regs.h
+++ b/drivers/media/usb/tm6000/tm6000-regs.h
@@ -1,16 +1,8 @@
/*
- * tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices
+ * SPDX-License-Identifier: GPL-2.0
+ * tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices
*
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.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
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
*/
/*
diff --git a/drivers/media/usb/tm6000/tm6000-stds.c b/drivers/media/usb/tm6000/tm6000-stds.c
index aa43810d17f9..c0c75951246b 100644
--- a/drivers/media/usb/tm6000/tm6000-stds.c
+++ b/drivers/media/usb/tm6000/tm6000-stds.c
@@ -1,17 +1,7 @@
-/*
- * tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2007 Mauro Carvalho Chehab
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+//
+// Copyright (c) 2007 Mauro Carvalho Chehab <mchehab@kernel.org>
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/drivers/media/usb/tm6000/tm6000-usb-isoc.h b/drivers/media/usb/tm6000/tm6000-usb-isoc.h
index 6a13a27c55d7..5c615b0a7a46 100644
--- a/drivers/media/usb/tm6000/tm6000-usb-isoc.h
+++ b/drivers/media/usb/tm6000/tm6000-usb-isoc.h
@@ -1,16 +1,8 @@
/*
- * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+ * SPDX-License-Identifier: GPL-2.0
+ * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices
*
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.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
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
*/
#include <linux/videodev2.h>
diff --git a/drivers/media/usb/tm6000/tm6000-video.c b/drivers/media/usb/tm6000/tm6000-video.c
index 317bf5a3933e..96266fa4738c 100644
--- a/drivers/media/usb/tm6000/tm6000-video.c
+++ b/drivers/media/usb/tm6000/tm6000-video.c
@@ -1,20 +1,10 @@
-/*
- * tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices
- *
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
- *
- * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
- * - Fixed module load/unload
- *
- * This program is free software; 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.
- */
+// SPDX-License-Identifier: GPL-2.0
+// tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+//
+// Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
+//
+// Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com>
+// - Fixed module load/unload
#include <linux/module.h>
#include <linux/delay.h>
@@ -1323,6 +1313,8 @@ static int __tm6000_open(struct file *file)
case VFL_TYPE_RADIO:
radio = 1;
break;
+ default:
+ return -EINVAL;
}
/* If more than one user, mutex should be added */
diff --git a/drivers/media/usb/tm6000/tm6000.h b/drivers/media/usb/tm6000/tm6000.h
index 7ec478d75f55..e1e45770e28d 100644
--- a/drivers/media/usb/tm6000/tm6000.h
+++ b/drivers/media/usb/tm6000/tm6000.h
@@ -1,19 +1,11 @@
/*
- * tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices
+ * SPDX-License-Identifier: GPL-2.0
+ * tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices
*
- * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
+ * Copyright (c) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org>
*
- * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com>
+ * Copyright (c) 2007 Michel Ludwig <michel.ludwig@gmail.com>
* - DVB-T 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 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/videodev2.h>
@@ -27,9 +19,9 @@
#include <media/v4l2-fh.h>
#include <linux/dvb/frontend.h>
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dmxdev.h"
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dmxdev.h>
/* Inputs */
enum tm6000_itype {
@@ -185,7 +177,7 @@ struct tm6000_core {
struct tm6000_capabilities caps;
/* Used to load alsa/dvb */
- struct work_struct request_module_wk;
+ struct work_struct request_module_wk;
/* Tuner configuration */
int tuner_type; /* type of the tuner */
diff --git a/drivers/media/usb/ttusb-budget/Makefile b/drivers/media/usb/ttusb-budget/Makefile
index f47bbf62dcde..fe4372dddd0e 100644
--- a/drivers/media/usb/ttusb-budget/Makefile
+++ b/drivers/media/usb/ttusb-budget/Makefile
@@ -1,3 +1,3 @@
obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o
-ccflags-y += -Idrivers/media/dvb-core/ -Idrivers/media/dvb-frontends
+ccflags-y += -Idrivers/media/dvb-frontends
diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
index a142b9dc0feb..eed56895c2b9 100644
--- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
@@ -22,10 +22,10 @@
#include <linux/mutex.h>
#include <linux/firmware.h>
-#include "dvb_frontend.h"
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_net.h"
+#include <media/dvb_frontend.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
#include "ves1820.h"
#include "cx22700.h"
#include "tda1004x.h"
@@ -102,7 +102,6 @@ struct ttusb {
unsigned int isoc_in_pipe;
void *iso_buffer;
- dma_addr_t iso_dma_handle;
struct urb *iso_urb[ISO_BUF_COUNT];
@@ -792,26 +791,17 @@ static void ttusb_free_iso_urbs(struct ttusb *ttusb)
for (i = 0; i < ISO_BUF_COUNT; i++)
usb_free_urb(ttusb->iso_urb[i]);
-
- pci_free_consistent(NULL,
- ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF *
- ISO_BUF_COUNT, ttusb->iso_buffer,
- ttusb->iso_dma_handle);
+ kfree(ttusb->iso_buffer);
}
static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
{
int i;
- ttusb->iso_buffer = pci_zalloc_consistent(NULL,
- ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
- &ttusb->iso_dma_handle);
-
- if (!ttusb->iso_buffer) {
- dprintk("%s: pci_alloc_consistent - not enough memory\n",
- __func__);
+ ttusb->iso_buffer = kcalloc(FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
+ ISO_FRAME_SIZE, GFP_KERNEL);
+ if (!ttusb->iso_buffer)
return -ENOMEM;
- }
for (i = 0; i < ISO_BUF_COUNT; i++) {
struct urb *urb;
diff --git a/drivers/media/usb/ttusb-dec/Makefile b/drivers/media/usb/ttusb-dec/Makefile
index 5352740d2353..dde9168b5e5f 100644
--- a/drivers/media/usb/ttusb-dec/Makefile
+++ b/drivers/media/usb/ttusb-dec/Makefile
@@ -1,3 +1 @@
obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o
-
-ccflags-y += -Idrivers/media/dvb-core/
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c
index cdefb5dfbbdc..a8900f5571f7 100644
--- a/drivers/media/usb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c
@@ -30,10 +30,10 @@
#include <linux/mutex.h>
-#include "dmxdev.h"
-#include "dvb_demux.h"
-#include "dvb_frontend.h"
-#include "dvb_net.h"
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_frontend.h>
+#include <media/dvb_net.h>
#include "ttusbdecfe.h"
static int debug;
@@ -127,7 +127,6 @@ struct ttusb_dec {
struct urb *irq_urb;
dma_addr_t irq_dma_handle;
void *iso_buffer;
- dma_addr_t iso_dma_handle;
struct urb *iso_urb[ISO_BUF_COUNT];
int iso_stream_count;
struct mutex iso_mutex;
@@ -1185,11 +1184,7 @@ static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec)
for (i = 0; i < ISO_BUF_COUNT; i++)
usb_free_urb(dec->iso_urb[i]);
-
- pci_free_consistent(NULL,
- ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *
- ISO_BUF_COUNT),
- dec->iso_buffer, dec->iso_dma_handle);
+ kfree(dec->iso_buffer);
}
static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
@@ -1198,15 +1193,10 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
dprintk("%s\n", __func__);
- dec->iso_buffer = pci_zalloc_consistent(NULL,
- ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT),
- &dec->iso_dma_handle);
-
- if (!dec->iso_buffer) {
- dprintk("%s: pci_alloc_consistent - not enough memory\n",
- __func__);
+ dec->iso_buffer = kcalloc(FRAMES_PER_ISO_BUF * ISO_BUF_COUNT,
+ ISO_FRAME_SIZE, GFP_KERNEL);
+ if (!dec->iso_buffer)
return -ENOMEM;
- }
for (i = 0; i < ISO_BUF_COUNT; i++) {
struct urb *urb;
diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.c b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
index 09693caa15e2..6ea05d909024 100644
--- a/drivers/media/usb/ttusb-dec/ttusbdecfe.c
+++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.c
@@ -15,7 +15,7 @@
*
*/
-#include "dvb_frontend.h"
+#include <media/dvb_frontend.h>
#include "ttusbdecfe.h"
diff --git a/drivers/media/usb/usbtv/Kconfig b/drivers/media/usb/usbtv/Kconfig
index b833c5b9094e..14a0941fa0d0 100644
--- a/drivers/media/usb/usbtv/Kconfig
+++ b/drivers/media/usb/usbtv/Kconfig
@@ -1,11 +1,11 @@
config VIDEO_USBTV
- tristate "USBTV007 video capture support"
- depends on VIDEO_V4L2 && SND
- select SND_PCM
- select VIDEOBUF2_VMALLOC
+ tristate "USBTV007 video capture support"
+ depends on VIDEO_V4L2 && SND
+ select SND_PCM
+ select VIDEOBUF2_VMALLOC
- ---help---
- This is a video4linux2 driver for USBTV007 based video capture devices.
+ ---help---
+ This is a video4linux2 driver for USBTV007 based video capture devices.
- To compile this driver as a module, choose M here: the
- module will be called usbtv
+ To compile this driver as a module, choose M here: the
+ module will be called usbtv
diff --git a/drivers/media/usb/usbvision/Makefile b/drivers/media/usb/usbvision/Makefile
index 9b3a5581df42..494d030b4979 100644
--- a/drivers/media/usb/usbvision/Makefile
+++ b/drivers/media/usb/usbvision/Makefile
@@ -2,5 +2,4 @@ usbvision-objs := usbvision-core.o usbvision-video.o usbvision-i2c.o usbvision-
obj-$(CONFIG_VIDEO_USBVISION) += usbvision.o
-ccflags-y += -Idrivers/media/i2c
ccflags-y += -Idrivers/media/tuners
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index 960272d3c924..0f5954a1fea2 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -72,7 +72,6 @@
#define DRIVER_NAME "usbvision"
#define DRIVER_ALIAS "USBVision"
#define DRIVER_DESC "USBVision USB Video Device Driver for Linux"
-#define DRIVER_LICENSE "GPL"
#define USBVISION_VERSION_STRING "0.9.11"
#define ENABLE_HEXDUMP 0 /* Enable if you need it */
@@ -141,7 +140,7 @@ MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1
/* Misc stuff */
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
+MODULE_LICENSE("GPL");
MODULE_VERSION(USBVISION_VERSION_STRING);
MODULE_ALIAS(DRIVER_ALIAS);
diff --git a/drivers/media/usb/uvc/Makefile b/drivers/media/usb/uvc/Makefile
index a4fe5b5d533f..4f9eee4f81ab 100644
--- a/drivers/media/usb/uvc/Makefile
+++ b/drivers/media/usb/uvc/Makefile
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
uvcvideo-objs := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \
- uvc_status.o uvc_isight.o uvc_debugfs.o
+ uvc_status.o uvc_isight.o uvc_debugfs.o uvc_metadata.o
ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
uvcvideo-objs += uvc_entity.o
endif
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 28b91b7d756f..fd387bf3f02d 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -24,6 +24,7 @@
#include <asm/unaligned.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
#include "uvcvideo.h"
@@ -94,6 +95,11 @@ static struct uvc_format_desc uvc_fmts[] = {
.fcc = V4L2_PIX_FMT_GREY,
},
{
+ .name = "Greyscale 8-bit (D3DFMT_L8)",
+ .guid = UVC_GUID_FORMAT_D3DFMT_L8,
+ .fcc = V4L2_PIX_FMT_GREY,
+ },
+ {
.name = "Greyscale 10-bit (Y10 )",
.guid = UVC_GUID_FORMAT_Y10,
.fcc = V4L2_PIX_FMT_Y10,
@@ -957,11 +963,11 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
* Size of this descriptor, in bytes: 24+p+n*2
* ----------------------------------------------------------
* 23+p+n bmControlsType N Bitmap
- * Individual bits in the set are defined:
- * 0: Absolute
- * 1: Relative
+ * Individual bits in the set are defined:
+ * 0: Absolute
+ * 1: Relative
*
- * This bitset is mapped exactly the same as bmControls.
+ * This bitset is mapped exactly the same as bmControls.
* ----------------------------------------------------------
* 23+p+n*2 bReserved 1 Boolean
* ----------------------------------------------------------
@@ -1877,6 +1883,7 @@ static void uvc_unregister_video(struct uvc_device *dev)
continue;
video_unregister_device(&stream->vdev);
+ video_unregister_device(&stream->meta.vdev);
uvc_debugfs_cleanup_stream(stream);
}
@@ -1884,63 +1891,95 @@ static void uvc_unregister_video(struct uvc_device *dev)
kref_put(&dev->ref, uvc_delete);
}
-static int uvc_register_video(struct uvc_device *dev,
- struct uvc_streaming *stream)
+int uvc_register_video_device(struct uvc_device *dev,
+ struct uvc_streaming *stream,
+ struct video_device *vdev,
+ struct uvc_video_queue *queue,
+ enum v4l2_buf_type type,
+ const struct v4l2_file_operations *fops,
+ const struct v4l2_ioctl_ops *ioctl_ops)
{
- struct video_device *vdev = &stream->vdev;
int ret;
/* Initialize the video buffers queue. */
- ret = uvc_queue_init(&stream->queue, stream->type, !uvc_no_drop_param);
+ ret = uvc_queue_init(queue, type, !uvc_no_drop_param);
if (ret)
return ret;
- /* Initialize the streaming interface with default streaming
- * parameters.
- */
- ret = uvc_video_init(stream);
- if (ret < 0) {
- uvc_printk(KERN_ERR, "Failed to initialize the device "
- "(%d).\n", ret);
- return ret;
- }
-
- uvc_debugfs_init_stream(stream);
-
/* Register the device with V4L. */
- /* We already hold a reference to dev->udev. The video device will be
+ /*
+ * We already hold a reference to dev->udev. The video device will be
* unregistered before the reference is released, so we don't need to
* get another one.
*/
vdev->v4l2_dev = &dev->vdev;
- vdev->fops = &uvc_fops;
- vdev->ioctl_ops = &uvc_ioctl_ops;
+ vdev->fops = fops;
+ vdev->ioctl_ops = ioctl_ops;
vdev->release = uvc_release;
vdev->prio = &stream->chain->prio;
- if (stream->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+ if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
vdev->vfl_dir = VFL_DIR_TX;
+ else
+ vdev->vfl_dir = VFL_DIR_RX;
+
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ default:
+ vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ break;
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
+ break;
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
+ break;
+ }
+
strlcpy(vdev->name, dev->name, sizeof vdev->name);
- /* Set the driver data before calling video_register_device, otherwise
- * uvc_v4l2_open might race us.
+ /*
+ * Set the driver data before calling video_register_device, otherwise
+ * the file open() handler might race us.
*/
video_set_drvdata(vdev, stream);
ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
if (ret < 0) {
- uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",
+ uvc_printk(KERN_ERR, "Failed to register %s device (%d).\n",
+ v4l2_type_names[type], ret);
+ return ret;
+ }
+
+ kref_get(&dev->ref);
+ return 0;
+}
+
+static int uvc_register_video(struct uvc_device *dev,
+ struct uvc_streaming *stream)
+{
+ int ret;
+
+ /* Initialize the streaming interface with default parameters. */
+ ret = uvc_video_init(stream);
+ if (ret < 0) {
+ uvc_printk(KERN_ERR, "Failed to initialize the device (%d).\n",
ret);
return ret;
}
if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE;
+ stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE
+ | V4L2_CAP_META_CAPTURE;
else
stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT;
- kref_get(&dev->ref);
- return 0;
+ uvc_debugfs_init_stream(stream);
+
+ /* Register the device with V4L. */
+ return uvc_register_video_device(dev, stream, &stream->vdev,
+ &stream->queue, stream->type,
+ &uvc_fops, &uvc_ioctl_ops);
}
/*
@@ -1969,6 +2008,11 @@ static int uvc_register_terms(struct uvc_device *dev,
if (ret < 0)
return ret;
+ /* Register a metadata node, but ignore a possible failure,
+ * complete registration of video nodes anyway.
+ */
+ uvc_meta_register(stream);
+
term->vdev = &stream->vdev;
}
@@ -2001,11 +2045,19 @@ static int uvc_register_chains(struct uvc_device *dev)
* USB probe, disconnect, suspend and resume
*/
+struct uvc_device_info {
+ u32 quirks;
+ u32 meta_format;
+};
+
static int uvc_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
struct uvc_device *dev;
+ const struct uvc_device_info *info =
+ (const struct uvc_device_info *)id->driver_info;
+ u32 quirks = info ? info->quirks : 0;
int function;
int ret;
@@ -2032,7 +2084,9 @@ static int uvc_probe(struct usb_interface *intf,
dev->intf = usb_get_intf(intf);
dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
dev->quirks = (uvc_quirks_param == -1)
- ? id->driver_info : uvc_quirks_param;
+ ? quirks : uvc_quirks_param;
+ if (info)
+ dev->meta_format = info->meta_format;
if (udev->product != NULL)
strlcpy(dev->name, udev->product, sizeof dev->name);
@@ -2073,7 +2127,7 @@ static int uvc_probe(struct usb_interface *intf,
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct));
- if (dev->quirks != id->driver_info) {
+ if (dev->quirks != quirks) {
uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module "
"parameter for testing purpose.\n", dev->quirks);
uvc_printk(KERN_INFO, "Please report required quirks to the "
@@ -2271,6 +2325,28 @@ MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
* Driver initialization and cleanup
*/
+static const struct uvc_device_info uvc_quirk_probe_minmax = {
+ .quirks = UVC_QUIRK_PROBE_MINMAX,
+};
+
+static const struct uvc_device_info uvc_quirk_fix_bandwidth = {
+ .quirks = UVC_QUIRK_FIX_BANDWIDTH,
+};
+
+static const struct uvc_device_info uvc_quirk_probe_def = {
+ .quirks = UVC_QUIRK_PROBE_DEF,
+};
+
+static const struct uvc_device_info uvc_quirk_stream_no_fid = {
+ .quirks = UVC_QUIRK_STREAM_NO_FID,
+};
+
+static const struct uvc_device_info uvc_quirk_force_y8 = {
+ .quirks = UVC_QUIRK_FORCE_Y8,
+};
+
+#define UVC_QUIRK_INFO(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q}
+
/*
* The Logitech cameras listed below have their interface class set to
* VENDOR_SPEC because they don't announce themselves as UVC devices, even
@@ -2285,7 +2361,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
/* Genius eFace 2025 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2294,7 +2370,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
/* Microsoft Lifecam NX-6000 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2303,7 +2379,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
/* Microsoft Lifecam NX-3000 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2312,7 +2388,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_DEF },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
/* Microsoft Lifecam VX-7000 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2321,7 +2397,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
/* Logitech Quickcam Fusion */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2378,7 +2454,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_RESTORE_CTRLS_ON_INIT },
+ .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) },
/* Chicony CNF7129 (Asus EEE 100HE) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2387,7 +2463,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_RESTRICT_FRAME_RATE },
+ .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_RESTRICT_FRAME_RATE) },
/* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2396,7 +2472,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
/* Dell XPS m1530 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2405,7 +2481,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_DEF },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
/* Dell SP2008WFP Monitor */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2414,7 +2490,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_DEF },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
/* Dell Alienware X51 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2423,7 +2499,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_DEF },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
/* Dell Studio Hybrid 140g (OmniVision webcam) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2432,7 +2508,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_DEF },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
/* Dell XPS M1330 (OmniVision OV7670 webcam) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2441,7 +2517,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_DEF },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
/* Apple Built-In iSight */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2450,8 +2526,8 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX
- | UVC_QUIRK_BUILTIN_ISIGHT },
+ .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+ | UVC_QUIRK_BUILTIN_ISIGHT) },
/* Apple Built-In iSight via iBridge */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2460,7 +2536,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_DEF },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
/* Foxlink ("HP Webcam" on HP Mini 5103) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2469,7 +2545,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
/* Genesys Logic USB 2.0 PC Camera */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2478,7 +2554,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
/* Hercules Classic Silver */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2487,7 +2563,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
/* ViMicro Vega */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2496,7 +2572,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
/* ViMicro - Minoru3D */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2505,7 +2581,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
/* ViMicro Venus - Minoru3D */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2514,7 +2590,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
/* Ophir Optronics - SPCAM 620U */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2523,7 +2599,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
/* MT6227 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2532,8 +2608,8 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX
- | UVC_QUIRK_PROBE_DEF },
+ .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+ | UVC_QUIRK_PROBE_DEF) },
/* IMC Networks (Medion Akoya) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2542,7 +2618,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
/* JMicron USB2.0 XGA WebCam */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2551,7 +2627,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
/* Syntek (HP Spartan) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2560,7 +2636,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
/* Syntek (Samsung Q310) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2569,7 +2645,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
/* Syntek (Packard Bell EasyNote MX52 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2578,7 +2654,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
/* Syntek (Asus F9SG) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2587,7 +2663,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
/* Syntek (Asus U3S) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2596,7 +2672,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
/* Syntek (JAOtech Smart Terminal) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2605,7 +2681,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
/* Miricle 307K */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2614,7 +2690,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
/* Lenovo Thinkpad SL400/SL500 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2623,7 +2699,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STREAM_NO_FID },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
/* Aveo Technology USB 2.0 Camera */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2632,8 +2708,8 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX
- | UVC_QUIRK_PROBE_EXTRAFIELDS },
+ .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+ | UVC_QUIRK_PROBE_EXTRAFIELDS) },
/* Aveo Technology USB 2.0 Camera (Tasco USB Microscope) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2650,7 +2726,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS },
+ .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_EXTRAFIELDS) },
/* Manta MM-353 Plako */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2659,7 +2735,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
/* FSC WebCam V30S */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2668,7 +2744,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
/* Arkmicro unbranded */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2677,7 +2753,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_DEF },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
/* The Imaging Source USB CCD cameras */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2696,7 +2772,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_STATUS_INTERVAL },
+ .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_STATUS_INTERVAL) },
/* MSI StarCam 370i */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2705,7 +2781,16 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
+ /* Generalplus Technology Inc. 808 Camera */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x1b3f,
+ .idProduct = 0x2002,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
/* SiGma Micro USB Web Camera */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2714,8 +2799,8 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_PROBE_MINMAX
- | UVC_QUIRK_IGNORE_SELECTOR_UNIT },
+ .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
+ | UVC_QUIRK_IGNORE_SELECTOR_UNIT) },
/* Oculus VR Positional Tracker DK2 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2724,7 +2809,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VIDEO,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FORCE_Y8 },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_force_y8 },
/* Oculus VR Rift Sensor */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2733,7 +2818,7 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
- .driver_info = UVC_QUIRK_FORCE_Y8 },
+ .driver_info = (kernel_ulong_t)&uvc_quirk_force_y8 },
/* Generic USB Video Class */
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
diff --git a/drivers/media/usb/uvc/uvc_isight.c b/drivers/media/usb/uvc/uvc_isight.c
index 8510e7259e76..5059fbf41020 100644
--- a/drivers/media/usb/uvc/uvc_isight.c
+++ b/drivers/media/usb/uvc/uvc_isight.c
@@ -27,11 +27,11 @@
*
* Offset Size (bytes) Description
* ------------------------------------------------------------------
- * 0x00 1 Header length
- * 0x01 1 Flags (UVC-compliant)
- * 0x02 4 Always equal to '11223344'
- * 0x06 8 Always equal to 'deadbeefdeadface'
- * 0x0e 16 Unknown
+ * 0x00 1 Header length
+ * 0x01 1 Flags (UVC-compliant)
+ * 0x02 4 Always equal to '11223344'
+ * 0x06 8 Always equal to 'deadbeefdeadface'
+ * 0x0e 16 Unknown
*
* The header can be prefixed by an optional, unknown-purpose byte.
*/
@@ -100,7 +100,7 @@ static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
}
void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
- struct uvc_buffer *buf)
+ struct uvc_buffer *buf, struct uvc_buffer *meta_buf)
{
int ret, i;
diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c
new file mode 100644
index 000000000000..cd1aec19cc5b
--- /dev/null
+++ b/drivers/media/usb/uvc/uvc_metadata.c
@@ -0,0 +1,179 @@
+/*
+ * uvc_metadata.c -- USB Video Class driver - Metadata handling
+ *
+ * Copyright (C) 2016
+ * Guennadi Liakhovetski (guennadi.liakhovetski@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/list.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-vmalloc.h>
+
+#include "uvcvideo.h"
+
+/* -----------------------------------------------------------------------------
+ * V4L2 ioctls
+ */
+
+static int uvc_meta_v4l2_querycap(struct file *file, void *fh,
+ struct v4l2_capability *cap)
+{
+ struct v4l2_fh *vfh = file->private_data;
+ struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
+ struct uvc_video_chain *chain = stream->chain;
+
+ strlcpy(cap->driver, "uvcvideo", sizeof(cap->driver));
+ strlcpy(cap->card, vfh->vdev->name, sizeof(cap->card));
+ usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
+ cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
+ | chain->caps;
+
+ return 0;
+}
+
+static int uvc_meta_v4l2_get_format(struct file *file, void *fh,
+ struct v4l2_format *format)
+{
+ struct v4l2_fh *vfh = file->private_data;
+ struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
+ struct v4l2_meta_format *fmt = &format->fmt.meta;
+
+ if (format->type != vfh->vdev->queue->type)
+ return -EINVAL;
+
+ memset(fmt, 0, sizeof(*fmt));
+
+ fmt->dataformat = stream->meta.format;
+ fmt->buffersize = UVC_METATADA_BUF_SIZE;
+
+ return 0;
+}
+
+static int uvc_meta_v4l2_try_format(struct file *file, void *fh,
+ struct v4l2_format *format)
+{
+ struct v4l2_fh *vfh = file->private_data;
+ struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
+ struct uvc_device *dev = stream->dev;
+ struct v4l2_meta_format *fmt = &format->fmt.meta;
+ u32 fmeta = fmt->dataformat;
+
+ if (format->type != vfh->vdev->queue->type)
+ return -EINVAL;
+
+ memset(fmt, 0, sizeof(*fmt));
+
+ fmt->dataformat = fmeta == dev->meta_format ? fmeta : V4L2_META_FMT_UVC;
+ fmt->buffersize = UVC_METATADA_BUF_SIZE;
+
+ return 0;
+}
+
+static int uvc_meta_v4l2_set_format(struct file *file, void *fh,
+ struct v4l2_format *format)
+{
+ struct v4l2_fh *vfh = file->private_data;
+ struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
+ struct v4l2_meta_format *fmt = &format->fmt.meta;
+ int ret;
+
+ ret = uvc_meta_v4l2_try_format(file, fh, format);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * We could in principle switch at any time, also during streaming.
+ * Metadata buffers would still be perfectly parseable, but it's more
+ * consistent and cleaner to disallow that.
+ */
+ mutex_lock(&stream->mutex);
+
+ if (uvc_queue_allocated(&stream->queue))
+ ret = -EBUSY;
+ else
+ stream->meta.format = fmt->dataformat;
+
+ mutex_unlock(&stream->mutex);
+
+ return ret;
+}
+
+static int uvc_meta_v4l2_enum_formats(struct file *file, void *fh,
+ struct v4l2_fmtdesc *fdesc)
+{
+ struct v4l2_fh *vfh = file->private_data;
+ struct uvc_streaming *stream = video_get_drvdata(vfh->vdev);
+ struct uvc_device *dev = stream->dev;
+ u32 index = fdesc->index;
+
+ if (fdesc->type != vfh->vdev->queue->type ||
+ index > 1U || (index && !dev->meta_format))
+ return -EINVAL;
+
+ memset(fdesc, 0, sizeof(*fdesc));
+
+ fdesc->type = vfh->vdev->queue->type;
+ fdesc->index = index;
+ fdesc->pixelformat = index ? dev->meta_format : V4L2_META_FMT_UVC;
+
+ return 0;
+}
+
+static const struct v4l2_ioctl_ops uvc_meta_ioctl_ops = {
+ .vidioc_querycap = uvc_meta_v4l2_querycap,
+ .vidioc_g_fmt_meta_cap = uvc_meta_v4l2_get_format,
+ .vidioc_s_fmt_meta_cap = uvc_meta_v4l2_set_format,
+ .vidioc_try_fmt_meta_cap = uvc_meta_v4l2_try_format,
+ .vidioc_enum_fmt_meta_cap = uvc_meta_v4l2_enum_formats,
+ .vidioc_reqbufs = vb2_ioctl_reqbufs,
+ .vidioc_querybuf = vb2_ioctl_querybuf,
+ .vidioc_qbuf = vb2_ioctl_qbuf,
+ .vidioc_dqbuf = vb2_ioctl_dqbuf,
+ .vidioc_create_bufs = vb2_ioctl_create_bufs,
+ .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
+ .vidioc_streamon = vb2_ioctl_streamon,
+ .vidioc_streamoff = vb2_ioctl_streamoff,
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 File Operations
+ */
+
+static const struct v4l2_file_operations uvc_meta_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = video_ioctl2,
+ .open = v4l2_fh_open,
+ .release = vb2_fop_release,
+ .poll = vb2_fop_poll,
+ .mmap = vb2_fop_mmap,
+};
+
+int uvc_meta_register(struct uvc_streaming *stream)
+{
+ struct uvc_device *dev = stream->dev;
+ struct video_device *vdev = &stream->meta.vdev;
+ struct uvc_video_queue *queue = &stream->meta.queue;
+
+ stream->meta.format = V4L2_META_FMT_UVC;
+
+ /*
+ * The video interface queue uses manual locking and thus does not set
+ * the queue pointer. Set it manually here.
+ */
+ vdev->queue = &queue->queue;
+
+ return uvc_register_video_device(dev, stream, vdev, queue,
+ V4L2_BUF_TYPE_META_CAPTURE,
+ &uvc_meta_fops, &uvc_meta_ioctl_ops);
+}
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index 692c463f14f7..fecccb5e7628 100644
--- a/drivers/media/usb/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -79,8 +79,19 @@ static int uvc_queue_setup(struct vb2_queue *vq,
unsigned int sizes[], struct device *alloc_devs[])
{
struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
- struct uvc_streaming *stream = uvc_queue_to_stream(queue);
- unsigned size = stream->ctrl.dwMaxVideoFrameSize;
+ struct uvc_streaming *stream;
+ unsigned int size;
+
+ switch (vq->type) {
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ size = UVC_METATADA_BUF_SIZE;
+ break;
+
+ default:
+ stream = uvc_queue_to_stream(queue);
+ size = stream->ctrl.dwMaxVideoFrameSize;
+ break;
+ }
/*
* When called with plane sizes, validate them. The driver supports
@@ -114,7 +125,7 @@ static int uvc_buffer_prepare(struct vb2_buffer *vb)
buf->error = 0;
buf->mem = vb2_plane_vaddr(vb, 0);
buf->length = vb2_plane_size(vb, 0);
- if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (vb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
buf->bytesused = 0;
else
buf->bytesused = vb2_get_plane_payload(vb, 0);
@@ -177,10 +188,10 @@ static int uvc_start_streaming(struct vb2_queue *vq, unsigned int count)
static void uvc_stop_streaming(struct vb2_queue *vq)
{
struct uvc_video_queue *queue = vb2_get_drv_priv(vq);
- struct uvc_streaming *stream = uvc_queue_to_stream(queue);
unsigned long flags;
- uvc_video_enable(stream, 0);
+ if (vq->type != V4L2_BUF_TYPE_META_CAPTURE)
+ uvc_video_enable(uvc_queue_to_stream(queue), 0);
spin_lock_irqsave(&queue->irqlock, flags);
uvc_queue_return_buffers(queue, UVC_BUF_STATE_ERROR);
@@ -198,20 +209,39 @@ static const struct vb2_ops uvc_queue_qops = {
.stop_streaming = uvc_stop_streaming,
};
+static const struct vb2_ops uvc_meta_queue_qops = {
+ .queue_setup = uvc_queue_setup,
+ .buf_prepare = uvc_buffer_prepare,
+ .buf_queue = uvc_buffer_queue,
+ .wait_prepare = vb2_ops_wait_prepare,
+ .wait_finish = vb2_ops_wait_finish,
+ .stop_streaming = uvc_stop_streaming,
+};
+
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 | VB2_DMABUF;
+ 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;
queue->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
| V4L2_BUF_FLAG_TSTAMP_SRC_SOE;
queue->queue.lock = &queue->mutex;
+
+ switch (type) {
+ case V4L2_BUF_TYPE_META_CAPTURE:
+ queue->queue.ops = &uvc_meta_queue_qops;
+ break;
+ default:
+ queue->queue.io_modes |= VB2_DMABUF;
+ queue->queue.ops = &uvc_queue_qops;
+ break;
+ }
+
ret = vb2_queue_init(&queue->queue);
if (ret)
return ret;
diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c
index f552ab997956..1ef20e74b7ac 100644
--- a/drivers/media/usb/uvc/uvc_status.c
+++ b/drivers/media/usb/uvc/uvc_status.c
@@ -93,8 +93,9 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len)
data[1], data[3] ? "pressed" : "released", len);
uvc_input_report_key(dev, KEY_CAMERA, data[3]);
} else {
- uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x "
- "len %d.\n", data[1], data[2], data[3], len);
+ uvc_trace(UVC_TRACE_STATUS,
+ "Stream %u error event %02x len %d.\n",
+ data[1], data[2], len);
}
}
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index 381f614b2f4c..a13ad4e178be 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -568,10 +568,6 @@ static int uvc_ioctl_querycap(struct file *file, void *fh,
usb_make_path(stream->dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
| chain->caps;
- if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
- else
- cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
return 0;
}
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index fb86d6af398d..5441553f74e1 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -369,12 +369,12 @@ static int uvc_commit_video(struct uvc_streaming *stream,
* Clocks and timestamps
*/
-static inline void uvc_video_get_ts(struct timespec *ts)
+static inline ktime_t uvc_video_get_time(void)
{
if (uvc_clock_param == CLOCK_MONOTONIC)
- ktime_get_ts(ts);
+ return ktime_get();
else
- ktime_get_real_ts(ts);
+ return ktime_get_real();
}
static void
@@ -386,7 +386,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
bool has_pts = false;
bool has_scr = false;
unsigned long flags;
- struct timespec ts;
+ ktime_t time;
u16 host_sof;
u16 dev_sof;
@@ -436,7 +436,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
stream->clock.last_sof = dev_sof;
host_sof = usb_get_current_frame_number(stream->dev->udev);
- uvc_video_get_ts(&ts);
+ time = uvc_video_get_time();
/* The UVC specification allows device implementations that can't obtain
* the USB frame number to keep their own frame counters as long as they
@@ -473,7 +473,7 @@ uvc_video_clock_decode(struct uvc_streaming *stream, struct uvc_buffer *buf,
sample->dev_stc = get_unaligned_le32(&data[header_size - 6]);
sample->dev_sof = dev_sof;
sample->host_sof = host_sof;
- sample->host_ts = ts;
+ sample->host_time = time;
/* Update the sliding window head and count. */
stream->clock.head = (stream->clock.head + 1) % stream->clock.size;
@@ -613,14 +613,12 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
struct uvc_clock_sample *first;
struct uvc_clock_sample *last;
unsigned long flags;
- struct timespec ts;
+ u64 timestamp;
u32 delta_stc;
u32 y1, y2;
u32 x1, x2;
u32 mean;
u32 sof;
- u32 div;
- u32 rem;
u64 y;
if (!uvc_hw_timestamps_param)
@@ -667,9 +665,8 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
if (x1 == x2)
goto done;
- ts = timespec_sub(last->host_ts, first->host_ts);
y1 = NSEC_PER_SEC;
- y2 = (ts.tv_sec + 1) * NSEC_PER_SEC + ts.tv_nsec;
+ y2 = (u32)ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1;
/* Interpolated and host SOF timestamps can wrap around at slightly
* different times. Handle this by adding or removing 2048 to or from
@@ -686,24 +683,18 @@ void uvc_video_clock_update(struct uvc_streaming *stream,
- (u64)y2 * (u64)x1;
y = div_u64(y, x2 - x1);
- div = div_u64_rem(y, NSEC_PER_SEC, &rem);
- ts.tv_sec = first->host_ts.tv_sec - 1 + div;
- ts.tv_nsec = first->host_ts.tv_nsec + rem;
- if (ts.tv_nsec >= NSEC_PER_SEC) {
- ts.tv_sec++;
- ts.tv_nsec -= NSEC_PER_SEC;
- }
+ timestamp = ktime_to_ns(first->host_time) + y - y1;
uvc_trace(UVC_TRACE_CLOCK, "%s: SOF %u.%06llu y %llu ts %llu "
"buf ts %llu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %u)\n",
stream->dev->name,
sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536),
- y, timespec_to_ns(&ts), vbuf->vb2_buf.timestamp,
+ y, timestamp, vbuf->vb2_buf.timestamp,
x1, first->host_sof, first->dev_sof,
x2, last->host_sof, last->dev_sof, y1, y2);
/* Update the V4L2 buffer. */
- vbuf->vb2_buf.timestamp = timespec_to_ns(&ts);
+ vbuf->vb2_buf.timestamp = timestamp;
done:
spin_unlock_irqrestore(&clock->lock, flags);
@@ -725,7 +716,7 @@ static void uvc_video_stats_decode(struct uvc_streaming *stream,
if (stream->stats.stream.nb_frames == 0 &&
stream->stats.frame.nb_packets == 0)
- ktime_get_ts(&stream->stats.stream.start_ts);
+ stream->stats.stream.start_ts = ktime_get();
switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) {
case UVC_STREAM_PTS | UVC_STREAM_SCR:
@@ -865,16 +856,13 @@ size_t uvc_video_stats_dump(struct uvc_streaming *stream, char *buf,
{
unsigned int scr_sof_freq;
unsigned int duration;
- struct timespec ts;
size_t count = 0;
- ts = timespec_sub(stream->stats.stream.stop_ts,
- stream->stats.stream.start_ts);
-
/* Compute the SCR.SOF frequency estimate. At the nominal 1kHz SOF
* frequency this will not overflow before more than 1h.
*/
- duration = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
+ duration = ktime_ms_delta(stream->stats.stream.stop_ts,
+ stream->stats.stream.start_ts);
if (duration != 0)
scr_sof_freq = stream->stats.stream.scr_sof_count * 1000
/ duration;
@@ -915,7 +903,7 @@ static void uvc_video_stats_start(struct uvc_streaming *stream)
static void uvc_video_stats_stop(struct uvc_streaming *stream)
{
- ktime_get_ts(&stream->stats.stream.stop_ts);
+ stream->stats.stream.stop_ts = ktime_get();
}
/* ------------------------------------------------------------------------
@@ -1010,8 +998,6 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
* when the EOF bit is set to force synchronisation on the next packet.
*/
if (buf->state != UVC_BUF_STATE_ACTIVE) {
- struct timespec ts;
-
if (fid == stream->last_fid) {
uvc_trace(UVC_TRACE_FRAME, "Dropping payload (out of "
"sync).\n");
@@ -1021,11 +1007,9 @@ static int uvc_video_decode_start(struct uvc_streaming *stream,
return -ENODATA;
}
- uvc_video_get_ts(&ts);
-
buf->buf.field = V4L2_FIELD_NONE;
buf->buf.sequence = stream->sequence;
- buf->buf.vb2_buf.timestamp = timespec_to_ns(&ts);
+ buf->buf.vb2_buf.timestamp = uvc_video_get_time();
/* TODO: Handle PTS and SCR. */
buf->state = UVC_BUF_STATE_ACTIVE;
@@ -1077,6 +1061,7 @@ static void uvc_video_decode_data(struct uvc_streaming *stream,
/* Complete the current frame if the buffer size was exceeded. */
if (len > maxlen) {
uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
+ buf->error = 1;
buf->state = UVC_BUF_STATE_READY;
}
}
@@ -1135,6 +1120,84 @@ static int uvc_video_encode_data(struct uvc_streaming *stream,
}
/* ------------------------------------------------------------------------
+ * Metadata
+ */
+
+/*
+ * Additionally to the payload headers we also want to provide the user with USB
+ * Frame Numbers and system time values. The resulting buffer is thus composed
+ * of blocks, containing a 64-bit timestamp in nanoseconds, a 16-bit USB Frame
+ * Number, and a copy of the payload header.
+ *
+ * Ideally we want to capture all payload headers for each frame. However, their
+ * number is unknown and unbound. We thus drop headers that contain no vendor
+ * data and that either contain no SCR value or an SCR value identical to the
+ * previous header.
+ */
+static void uvc_video_decode_meta(struct uvc_streaming *stream,
+ struct uvc_buffer *meta_buf,
+ const u8 *mem, unsigned int length)
+{
+ struct uvc_meta_buf *meta;
+ size_t len_std = 2;
+ bool has_pts, has_scr;
+ unsigned long flags;
+ unsigned int sof;
+ ktime_t time;
+ const u8 *scr;
+
+ if (!meta_buf || length == 2)
+ return;
+
+ if (meta_buf->length - meta_buf->bytesused <
+ length + sizeof(meta->ns) + sizeof(meta->sof)) {
+ meta_buf->error = 1;
+ return;
+ }
+
+ has_pts = mem[1] & UVC_STREAM_PTS;
+ has_scr = mem[1] & UVC_STREAM_SCR;
+
+ if (has_pts) {
+ len_std += 4;
+ scr = mem + 6;
+ } else {
+ scr = mem + 2;
+ }
+
+ if (has_scr)
+ len_std += 6;
+
+ if (stream->meta.format == V4L2_META_FMT_UVC)
+ length = len_std;
+
+ if (length == len_std && (!has_scr ||
+ !memcmp(scr, stream->clock.last_scr, 6)))
+ return;
+
+ meta = (struct uvc_meta_buf *)((u8 *)meta_buf->mem + meta_buf->bytesused);
+ local_irq_save(flags);
+ time = uvc_video_get_time();
+ sof = usb_get_current_frame_number(stream->dev->udev);
+ local_irq_restore(flags);
+ put_unaligned(ktime_to_ns(time), &meta->ns);
+ put_unaligned(sof, &meta->sof);
+
+ if (has_scr)
+ memcpy(stream->clock.last_scr, scr, 6);
+
+ memcpy(&meta->length, mem, length);
+ meta_buf->bytesused += length + sizeof(meta->ns) + sizeof(meta->sof);
+
+ uvc_trace(UVC_TRACE_FRAME,
+ "%s(): t-sys %lluns, SOF %u, len %u, flags 0x%x, PTS %u, STC %u frame SOF %u\n",
+ __func__, time, meta->sof, meta->length, meta->flags,
+ has_pts ? *(u32 *)meta->buf : 0,
+ has_scr ? *(u32 *)scr : 0,
+ has_scr ? *(u32 *)(scr + 4) & 0x7ff : 0);
+}
+
+/* ------------------------------------------------------------------------
* URB handling
*/
@@ -1152,8 +1215,29 @@ static void uvc_video_validate_buffer(const struct uvc_streaming *stream,
/*
* Completion handler for video URBs.
*/
+
+static void uvc_video_next_buffers(struct uvc_streaming *stream,
+ struct uvc_buffer **video_buf, struct uvc_buffer **meta_buf)
+{
+ if (*meta_buf) {
+ struct vb2_v4l2_buffer *vb2_meta = &(*meta_buf)->buf;
+ const struct vb2_v4l2_buffer *vb2_video = &(*video_buf)->buf;
+
+ vb2_meta->sequence = vb2_video->sequence;
+ vb2_meta->field = vb2_video->field;
+ vb2_meta->vb2_buf.timestamp = vb2_video->vb2_buf.timestamp;
+
+ (*meta_buf)->state = UVC_BUF_STATE_READY;
+ if (!(*meta_buf)->error)
+ (*meta_buf)->error = (*video_buf)->error;
+ *meta_buf = uvc_queue_next_buffer(&stream->meta.queue,
+ *meta_buf);
+ }
+ *video_buf = uvc_queue_next_buffer(&stream->queue, *video_buf);
+}
+
static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream,
- struct uvc_buffer *buf)
+ struct uvc_buffer *buf, struct uvc_buffer *meta_buf)
{
u8 *mem;
int ret, i;
@@ -1175,14 +1259,15 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream,
urb->iso_frame_desc[i].actual_length);
if (ret == -EAGAIN) {
uvc_video_validate_buffer(stream, buf);
- buf = uvc_queue_next_buffer(&stream->queue,
- buf);
+ uvc_video_next_buffers(stream, &buf, &meta_buf);
}
} while (ret == -EAGAIN);
if (ret < 0)
continue;
+ uvc_video_decode_meta(stream, meta_buf, mem, ret);
+
/* Decode the payload data. */
uvc_video_decode_data(stream, buf, mem + ret,
urb->iso_frame_desc[i].actual_length - ret);
@@ -1193,13 +1278,13 @@ static void uvc_video_decode_isoc(struct urb *urb, struct uvc_streaming *stream,
if (buf->state == UVC_BUF_STATE_READY) {
uvc_video_validate_buffer(stream, buf);
- buf = uvc_queue_next_buffer(&stream->queue, buf);
+ uvc_video_next_buffers(stream, &buf, &meta_buf);
}
}
}
static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
- struct uvc_buffer *buf)
+ struct uvc_buffer *buf, struct uvc_buffer *meta_buf)
{
u8 *mem;
int len, ret;
@@ -1222,8 +1307,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
do {
ret = uvc_video_decode_start(stream, buf, mem, len);
if (ret == -EAGAIN)
- buf = uvc_queue_next_buffer(&stream->queue,
- buf);
+ uvc_video_next_buffers(stream, &buf, &meta_buf);
} while (ret == -EAGAIN);
/* If an error occurred skip the rest of the payload. */
@@ -1233,6 +1317,8 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
memcpy(stream->bulk.header, mem, ret);
stream->bulk.header_size = ret;
+ uvc_video_decode_meta(stream, meta_buf, mem, ret);
+
mem += ret;
len -= ret;
}
@@ -1256,7 +1342,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
uvc_video_decode_end(stream, buf, stream->bulk.header,
stream->bulk.payload_size);
if (buf->state == UVC_BUF_STATE_READY)
- uvc_queue_next_buffer(&stream->queue, buf);
+ uvc_video_next_buffers(stream, &buf, &meta_buf);
}
stream->bulk.header_size = 0;
@@ -1266,7 +1352,7 @@ static void uvc_video_decode_bulk(struct urb *urb, struct uvc_streaming *stream,
}
static void uvc_video_encode_bulk(struct urb *urb, struct uvc_streaming *stream,
- struct uvc_buffer *buf)
+ struct uvc_buffer *buf, struct uvc_buffer *meta_buf)
{
u8 *mem = urb->transfer_buffer;
int len = stream->urb_size, ret;
@@ -1312,7 +1398,10 @@ static void uvc_video_complete(struct urb *urb)
{
struct uvc_streaming *stream = urb->context;
struct uvc_video_queue *queue = &stream->queue;
+ struct uvc_video_queue *qmeta = &stream->meta.queue;
+ struct vb2_queue *vb2_qmeta = stream->meta.vdev.queue;
struct uvc_buffer *buf = NULL;
+ struct uvc_buffer *buf_meta = NULL;
unsigned long flags;
int ret;
@@ -1331,6 +1420,8 @@ static void uvc_video_complete(struct urb *urb)
case -ECONNRESET: /* usb_unlink_urb() called. */
case -ESHUTDOWN: /* The endpoint is being disabled. */
uvc_queue_cancel(queue, urb->status == -ESHUTDOWN);
+ if (vb2_qmeta)
+ uvc_queue_cancel(qmeta, urb->status == -ESHUTDOWN);
return;
}
@@ -1340,7 +1431,15 @@ static void uvc_video_complete(struct urb *urb)
queue);
spin_unlock_irqrestore(&queue->irqlock, flags);
- stream->decode(urb, stream, buf);
+ if (vb2_qmeta) {
+ spin_lock_irqsave(&qmeta->irqlock, flags);
+ if (!list_empty(&qmeta->irqqueue))
+ buf_meta = list_first_entry(&qmeta->irqqueue,
+ struct uvc_buffer, queue);
+ spin_unlock_irqrestore(&qmeta->irqlock, flags);
+ }
+
+ stream->decode(urb, stream, buf, buf_meta);
if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n",
@@ -1469,13 +1568,13 @@ static unsigned int uvc_endpoint_max_bpi(struct usb_device *dev,
case USB_SPEED_HIGH:
psize = usb_endpoint_maxp(&ep->desc);
mult = usb_endpoint_maxp_mult(&ep->desc);
- return (psize & 0x07ff) * mult;
+ return psize * mult;
case USB_SPEED_WIRELESS:
psize = usb_endpoint_maxp(&ep->desc);
return psize;
default:
psize = usb_endpoint_maxp(&ep->desc);
- return psize & 0x07ff;
+ return psize;
}
}
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 9b44a7cd5ec1..d9e7c70788d0 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -154,6 +154,11 @@
{ 'I', 'N', 'V', 'I', 0xdb, 0x57, 0x49, 0x5e, \
0x8e, 0x3f, 0xf4, 0x79, 0x53, 0x2b, 0x94, 0x6f}
+#define UVC_GUID_FORMAT_D3DFMT_L8 \
+ {0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \
+ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+
+
/* ------------------------------------------------------------------------
* Driver specific constants.
*/
@@ -452,8 +457,8 @@ struct uvc_stats_frame {
};
struct uvc_stats_stream {
- struct timespec start_ts; /* Stream start timestamp */
- struct timespec stop_ts; /* Stream stop timestamp */
+ ktime_t start_ts; /* Stream start timestamp */
+ ktime_t stop_ts; /* Stream stop timestamp */
unsigned int nb_frames; /* Number of frames */
@@ -474,6 +479,8 @@ struct uvc_stats_stream {
unsigned int max_sof; /* Maximum STC.SOF value */
};
+#define UVC_METATADA_BUF_SIZE 1024
+
struct uvc_streaming {
struct list_head list;
struct uvc_device *dev;
@@ -505,7 +512,13 @@ struct uvc_streaming {
unsigned int frozen : 1;
struct uvc_video_queue queue;
void (*decode) (struct urb *urb, struct uvc_streaming *video,
- struct uvc_buffer *buf);
+ struct uvc_buffer *buf, struct uvc_buffer *meta_buf);
+
+ struct {
+ struct video_device vdev;
+ struct uvc_video_queue queue;
+ __u32 format;
+ } meta;
/* Context data used by the bulk completion handler. */
struct {
@@ -536,8 +549,8 @@ struct uvc_streaming {
struct uvc_clock_sample {
u32 dev_stc;
u16 dev_sof;
- struct timespec host_ts;
u16 host_sof;
+ ktime_t host_time;
} *samples;
unsigned int head;
@@ -547,6 +560,8 @@ struct uvc_streaming {
u16 last_sof;
u16 sof_offset;
+ u8 last_scr[6];
+
spinlock_t lock;
} clock;
};
@@ -556,6 +571,7 @@ struct uvc_device {
struct usb_interface *intf;
unsigned long warnings;
__u32 quirks;
+ __u32 meta_format;
int intfnum;
char name[32];
@@ -710,6 +726,15 @@ extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
void uvc_video_clock_update(struct uvc_streaming *stream,
struct vb2_v4l2_buffer *vbuf,
struct uvc_buffer *buf);
+int uvc_meta_register(struct uvc_streaming *stream);
+
+int uvc_register_video_device(struct uvc_device *dev,
+ struct uvc_streaming *stream,
+ struct video_device *vdev,
+ struct uvc_video_queue *queue,
+ enum v4l2_buf_type type,
+ const struct v4l2_file_operations *fops,
+ const struct v4l2_ioctl_ops *ioctl_ops);
/* Status */
extern int uvc_status_init(struct uvc_device *dev);
@@ -764,7 +789,7 @@ extern struct usb_host_endpoint *uvc_find_endpoint(
/* Quirks support */
void uvc_video_decode_isight(struct urb *urb, struct uvc_streaming *stream,
- struct uvc_buffer *buf);
+ struct uvc_buffer *buf, struct uvc_buffer *meta_buf);
/* debugfs and statistics */
void uvc_debugfs_init(void);
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index a35c33686abf..bf52fbd07aed 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -41,8 +41,8 @@ config VIDEO_TUNER
# Used by drivers that need v4l2-mem2mem.ko
config V4L2_MEM2MEM_DEV
- tristate
- depends on VIDEOBUF2_CORE
+ tristate
+ depends on VIDEOBUF2_CORE
# Used by LED subsystem flash drivers
config V4L2_FLASH_LED_CLASS
@@ -79,35 +79,3 @@ config VIDEOBUF_DMA_CONTIG
config VIDEOBUF_DVB
tristate
select VIDEOBUF_GEN
-
-# Used by drivers that need Videobuf2 modules
-config VIDEOBUF2_CORE
- select DMA_SHARED_BUFFER
- tristate
-
-config VIDEOBUF2_MEMOPS
- tristate
- select FRAME_VECTOR
-
-config VIDEOBUF2_DMA_CONTIG
- tristate
- depends on HAS_DMA
- select VIDEOBUF2_CORE
- select VIDEOBUF2_MEMOPS
- select DMA_SHARED_BUFFER
-
-config VIDEOBUF2_VMALLOC
- tristate
- select VIDEOBUF2_CORE
- select VIDEOBUF2_MEMOPS
- select DMA_SHARED_BUFFER
-
-config VIDEOBUF2_DMA_SG
- tristate
- depends on HAS_DMA
- select VIDEOBUF2_CORE
- select VIDEOBUF2_MEMOPS
-
-config VIDEOBUF2_DVB
- tristate
- select VIDEOBUF2_CORE
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 77303286aef7..80de2cb9c476 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -33,14 +33,6 @@ 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 videobuf2-v4l2.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_VIDEOBUF2_DVB) += videobuf2-dvb.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/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c
index e5acfab470a5..2b08d03b251d 100644
--- a/drivers/media/v4l2-core/v4l2-async.c
+++ b/drivers/media/v4l2-core/v4l2-async.c
@@ -68,12 +68,12 @@ static bool match_i2c(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
static bool match_devname(struct v4l2_subdev *sd,
struct v4l2_async_subdev *asd)
{
- return !strcmp(asd->match.device_name.name, dev_name(sd->dev));
+ return !strcmp(asd->match.device_name, dev_name(sd->dev));
}
static bool match_fwnode(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
{
- return sd->fwnode == asd->match.fwnode.fwnode;
+ return sd->fwnode == asd->match.fwnode;
}
static bool match_custom(struct v4l2_subdev *sd, struct v4l2_async_subdev *asd)
@@ -319,7 +319,7 @@ static bool __v4l2_async_notifier_fwnode_has_async_subdev(
if (asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
continue;
- if (asd->match.fwnode.fwnode == fwnode)
+ if (asd->match.fwnode == fwnode)
return true;
}
@@ -330,7 +330,7 @@ static bool __v4l2_async_notifier_fwnode_has_async_subdev(
if (sd->asd->match_type != V4L2_ASYNC_MATCH_FWNODE)
continue;
- if (sd->asd->match.fwnode.fwnode == fwnode)
+ if (sd->asd->match.fwnode == fwnode)
return true;
}
@@ -355,8 +355,8 @@ static bool v4l2_async_notifier_fwnode_has_async_subdev(
struct v4l2_async_subdev *other_asd = notifier->subdevs[j];
if (other_asd->match_type == V4L2_ASYNC_MATCH_FWNODE &&
- asd->match.fwnode.fwnode ==
- other_asd->match.fwnode.fwnode)
+ asd->match.fwnode ==
+ other_asd->match.fwnode)
return true;
}
@@ -395,7 +395,7 @@ static int __v4l2_async_notifier_register(struct v4l2_async_notifier *notifier)
break;
case V4L2_ASYNC_MATCH_FWNODE:
if (v4l2_async_notifier_fwnode_has_async_subdev(
- notifier, asd->match.fwnode.fwnode, i)) {
+ notifier, asd->match.fwnode, i)) {
dev_err(dev,
"fwnode has already been registered or in notifier's subdev list\n");
ret = -EEXIST;
@@ -510,7 +510,7 @@ void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier)
switch (asd->match_type) {
case V4L2_ASYNC_MATCH_FWNODE:
- fwnode_handle_put(asd->match.fwnode.fwnode);
+ fwnode_handle_put(asd->match.fwnode);
break;
default:
WARN_ON_ONCE(true);
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index a5ea1f517291..8650ad92b64d 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -320,20 +320,6 @@ static unsigned int clamp_align(unsigned int x, unsigned int min,
return x;
}
-/* Bound an image to have a width between wmin and wmax, and height between
- * hmin and hmax, inclusive. Additionally, the width will be a multiple of
- * 2^walign, the height will be a multiple of 2^halign, and the overall size
- * (width*height) will be a multiple of 2^salign. The image may be shrunk
- * or enlarged to fit the alignment constraints.
- *
- * The width or height maximum must not be smaller than the corresponding
- * minimum. The alignments must not be so high there are no possible image
- * sizes within the allowed bounds. wmin and hmin must be at least 1
- * (don't use 0). If you don't care about a certain alignment, specify 0,
- * as 2^0 is 1 and one byte alignment is equivalent to no alignment. If
- * you only want to adjust downward, specify a maximum that's the same as
- * the initial value.
- */
void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
unsigned int walign,
u32 *h, unsigned int hmin, unsigned int hmax,
@@ -371,18 +357,19 @@ void v4l_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
}
EXPORT_SYMBOL_GPL(v4l_bound_align_image);
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
- const struct v4l2_discrete_probe *probe,
- s32 width, s32 height)
+const struct v4l2_frmsize_discrete *
+v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,
+ size_t num_sizes,
+ s32 width, s32 height)
{
int i;
u32 error, min_error = UINT_MAX;
const struct v4l2_frmsize_discrete *size, *best = NULL;
- if (!probe)
- return best;
+ if (!sizes)
+ return NULL;
- for (i = 0, size = probe->sizes; i < probe->num_sizes; i++, size++) {
+ for (i = 0, size = sizes; i < num_sizes; i++, size++) {
error = abs(size->width - width) + abs(size->height - height);
if (error < min_error) {
min_error = error;
diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 821f2aa299ae..5198c9eeb348 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -18,8 +18,18 @@
#include <linux/videodev2.h>
#include <linux/v4l2-subdev.h>
#include <media/v4l2-dev.h>
+#include <media/v4l2-fh.h>
+#include <media/v4l2-ctrls.h>
#include <media/v4l2-ioctl.h>
+/* Use the same argument order as copy_in_user */
+#define assign_in_user(to, from) \
+({ \
+ typeof(*from) __assign_tmp; \
+ \
+ get_user(__assign_tmp, from) || put_user(__assign_tmp, to); \
+})
+
static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret = -ENOIOCTLCMD;
@@ -33,12 +43,12 @@ static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct v4l2_clip32 {
struct v4l2_rect c;
- compat_caddr_t next;
+ compat_caddr_t next;
};
struct v4l2_window32 {
struct v4l2_rect w;
- __u32 field; /* enum v4l2_field */
+ __u32 field; /* enum v4l2_field */
__u32 chromakey;
compat_caddr_t clips; /* actually struct v4l2_clip32 * */
__u32 clipcount;
@@ -46,135 +56,75 @@ struct v4l2_window32 {
__u8 global_alpha;
};
-static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
-{
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_window32)) ||
- copy_from_user(&kp->w, &up->w, sizeof(up->w)) ||
- get_user(kp->field, &up->field) ||
- get_user(kp->chromakey, &up->chromakey) ||
- get_user(kp->clipcount, &up->clipcount) ||
- get_user(kp->global_alpha, &up->global_alpha))
- return -EFAULT;
- if (kp->clipcount > 2048)
- return -EINVAL;
- if (kp->clipcount) {
- struct v4l2_clip32 __user *uclips;
- struct v4l2_clip __user *kclips;
- int n = kp->clipcount;
- compat_caddr_t p;
-
- if (get_user(p, &up->clips))
- return -EFAULT;
- uclips = compat_ptr(p);
- kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip));
- kp->clips = kclips;
- while (--n >= 0) {
- if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
- return -EFAULT;
- if (put_user(n ? kclips + 1 : NULL, &kclips->next))
- return -EFAULT;
- uclips += 1;
- kclips += 1;
- }
- } else
- kp->clips = NULL;
- return 0;
-}
-
-static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up)
-{
- if (copy_to_user(&up->w, &kp->w, sizeof(kp->w)) ||
- put_user(kp->field, &up->field) ||
- put_user(kp->chromakey, &up->chromakey) ||
- put_user(kp->clipcount, &up->clipcount) ||
- put_user(kp->global_alpha, &up->global_alpha))
- return -EFAULT;
- return 0;
-}
-
-static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
-{
- if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format)))
- return -EFAULT;
- return 0;
-}
-
-static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
- struct v4l2_pix_format_mplane __user *up)
-{
- if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
- return -EFAULT;
- return 0;
-}
-
-static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
- return -EFAULT;
- return 0;
-}
-
-static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
- struct v4l2_pix_format_mplane __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
- return -EFAULT;
- return 0;
-}
-
-static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
+static int get_v4l2_window32(struct v4l2_window __user *kp,
+ struct v4l2_window32 __user *up,
+ void __user *aux_buf, u32 aux_space)
{
- if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
+ struct v4l2_clip32 __user *uclips;
+ struct v4l2_clip __user *kclips;
+ compat_caddr_t p;
+ u32 clipcount;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+ copy_in_user(&kp->w, &up->w, sizeof(up->w)) ||
+ assign_in_user(&kp->field, &up->field) ||
+ assign_in_user(&kp->chromakey, &up->chromakey) ||
+ assign_in_user(&kp->global_alpha, &up->global_alpha) ||
+ get_user(clipcount, &up->clipcount) ||
+ put_user(clipcount, &kp->clipcount))
return -EFAULT;
- return 0;
-}
+ if (clipcount > 2048)
+ return -EINVAL;
+ if (!clipcount)
+ return put_user(NULL, &kp->clips);
-static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)))
+ if (get_user(p, &up->clips))
return -EFAULT;
- return 0;
-}
-
-static inline int get_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
-{
- if (copy_from_user(kp, up, sizeof(struct v4l2_sliced_vbi_format)))
+ uclips = compat_ptr(p);
+ if (aux_space < clipcount * sizeof(*kclips))
return -EFAULT;
- return 0;
-}
-
-static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format)))
+ kclips = aux_buf;
+ if (put_user(kclips, &kp->clips))
return -EFAULT;
- return 0;
-}
-static inline int get_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sdr_format __user *up)
-{
- if (copy_from_user(kp, up, sizeof(struct v4l2_sdr_format)))
- return -EFAULT;
- return 0;
-}
-
-static inline int put_v4l2_sdr_format(struct v4l2_sdr_format *kp, struct v4l2_sdr_format __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_sdr_format)))
- return -EFAULT;
+ while (clipcount--) {
+ if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c)))
+ return -EFAULT;
+ if (put_user(clipcount ? kclips + 1 : NULL, &kclips->next))
+ return -EFAULT;
+ uclips++;
+ kclips++;
+ }
return 0;
}
-static inline int get_v4l2_meta_format(struct v4l2_meta_format *kp, struct v4l2_meta_format __user *up)
+static int put_v4l2_window32(struct v4l2_window __user *kp,
+ struct v4l2_window32 __user *up)
{
- if (copy_from_user(kp, up, sizeof(struct v4l2_meta_format)))
+ struct v4l2_clip __user *kclips = kp->clips;
+ struct v4l2_clip32 __user *uclips;
+ compat_caddr_t p;
+ u32 clipcount;
+
+ if (copy_in_user(&up->w, &kp->w, sizeof(kp->w)) ||
+ assign_in_user(&up->field, &kp->field) ||
+ assign_in_user(&up->chromakey, &kp->chromakey) ||
+ assign_in_user(&up->global_alpha, &kp->global_alpha) ||
+ get_user(clipcount, &kp->clipcount) ||
+ put_user(clipcount, &up->clipcount))
return -EFAULT;
- return 0;
-}
+ if (!clipcount)
+ return 0;
-static inline int put_v4l2_meta_format(struct v4l2_meta_format *kp, struct v4l2_meta_format __user *up)
-{
- if (copy_to_user(up, kp, sizeof(struct v4l2_meta_format)))
+ if (get_user(p, &up->clips))
return -EFAULT;
+ uclips = compat_ptr(p);
+ while (clipcount--) {
+ if (copy_in_user(&uclips->c, &kclips->c, sizeof(uclips->c)))
+ return -EFAULT;
+ uclips++;
+ kclips++;
+ }
return 0;
}
@@ -209,101 +159,164 @@ struct v4l2_create_buffers32 {
__u32 reserved[8];
};
-static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int __bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size)
{
- if (get_user(kp->type, &up->type))
+ u32 type;
+
+ if (get_user(type, &up->type))
return -EFAULT;
- switch (kp->type) {
+ switch (type) {
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: {
+ u32 clipcount;
+
+ if (get_user(clipcount, &up->fmt.win.clipcount))
+ return -EFAULT;
+ if (clipcount > 2048)
+ return -EINVAL;
+ *size = clipcount * sizeof(struct v4l2_clip);
+ return 0;
+ }
+ default:
+ *size = 0;
+ return 0;
+ }
+}
+
+static int bufsize_v4l2_format(struct v4l2_format32 __user *up, u32 *size)
+{
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)))
+ return -EFAULT;
+ return __bufsize_v4l2_format(up, size);
+}
+
+static int __get_v4l2_format32(struct v4l2_format __user *kp,
+ struct v4l2_format32 __user *up,
+ void __user *aux_buf, u32 aux_space)
+{
+ u32 type;
+
+ if (get_user(type, &up->type) || put_user(type, &kp->type))
+ return -EFAULT;
+
+ switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
+ return copy_in_user(&kp->fmt.pix, &up->fmt.pix,
+ sizeof(kp->fmt.pix)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- return get_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
- &up->fmt.pix_mp);
+ return copy_in_user(&kp->fmt.pix_mp, &up->fmt.pix_mp,
+ sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
+ return get_v4l2_window32(&kp->fmt.win, &up->fmt.win,
+ aux_buf, aux_space);
case V4L2_BUF_TYPE_VBI_CAPTURE:
case V4L2_BUF_TYPE_VBI_OUTPUT:
- return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
+ return copy_in_user(&kp->fmt.vbi, &up->fmt.vbi,
+ sizeof(kp->fmt.vbi)) ? -EFAULT : 0;
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);
+ return copy_in_user(&kp->fmt.sliced, &up->fmt.sliced,
+ sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_SDR_CAPTURE:
case V4L2_BUF_TYPE_SDR_OUTPUT:
- return get_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
+ return copy_in_user(&kp->fmt.sdr, &up->fmt.sdr,
+ sizeof(kp->fmt.sdr)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_META_CAPTURE:
- return get_v4l2_meta_format(&kp->fmt.meta, &up->fmt.meta);
+ return copy_in_user(&kp->fmt.meta, &up->fmt.meta,
+ sizeof(kp->fmt.meta)) ? -EFAULT : 0;
default:
- pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
- kp->type);
return -EINVAL;
}
}
-static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int get_v4l2_format32(struct v4l2_format __user *kp,
+ struct v4l2_format32 __user *up,
+ void __user *aux_buf, u32 aux_space)
+{
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)))
+ return -EFAULT;
+ return __get_v4l2_format32(kp, up, aux_buf, aux_space);
+}
+
+static int bufsize_v4l2_create(struct v4l2_create_buffers32 __user *up,
+ u32 *size)
{
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)))
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)))
return -EFAULT;
- return __get_v4l2_format32(kp, up);
+ return __bufsize_v4l2_format(&up->format, size);
}
-static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+static int get_v4l2_create32(struct v4l2_create_buffers __user *kp,
+ struct v4l2_create_buffers32 __user *up,
+ void __user *aux_buf, u32 aux_space)
{
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
- copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format)))
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+ copy_in_user(kp, up,
+ offsetof(struct v4l2_create_buffers32, format)))
return -EFAULT;
- return __get_v4l2_format32(&kp->format, &up->format);
+ return __get_v4l2_format32(&kp->format, &up->format,
+ aux_buf, aux_space);
}
-static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int __put_v4l2_format32(struct v4l2_format __user *kp,
+ struct v4l2_format32 __user *up)
{
- if (put_user(kp->type, &up->type))
+ u32 type;
+
+ if (get_user(type, &kp->type))
return -EFAULT;
- switch (kp->type) {
+ switch (type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
+ return copy_in_user(&up->fmt.pix, &kp->fmt.pix,
+ sizeof(kp->fmt.pix)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- return put_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
- &up->fmt.pix_mp);
+ return copy_in_user(&up->fmt.pix_mp, &kp->fmt.pix_mp,
+ sizeof(kp->fmt.pix_mp)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
case V4L2_BUF_TYPE_VBI_CAPTURE:
case V4L2_BUF_TYPE_VBI_OUTPUT:
- return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi);
+ return copy_in_user(&up->fmt.vbi, &kp->fmt.vbi,
+ sizeof(kp->fmt.vbi)) ? -EFAULT : 0;
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);
+ return copy_in_user(&up->fmt.sliced, &kp->fmt.sliced,
+ sizeof(kp->fmt.sliced)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_SDR_CAPTURE:
case V4L2_BUF_TYPE_SDR_OUTPUT:
- return put_v4l2_sdr_format(&kp->fmt.sdr, &up->fmt.sdr);
+ return copy_in_user(&up->fmt.sdr, &kp->fmt.sdr,
+ sizeof(kp->fmt.sdr)) ? -EFAULT : 0;
case V4L2_BUF_TYPE_META_CAPTURE:
- return put_v4l2_meta_format(&kp->fmt.meta, &up->fmt.meta);
+ return copy_in_user(&up->fmt.meta, &kp->fmt.meta,
+ sizeof(kp->fmt.meta)) ? -EFAULT : 0;
default:
- pr_info("compat_ioctl32: unexpected VIDIOC_FMT type %d\n",
- kp->type);
return -EINVAL;
}
}
-static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
+static int put_v4l2_format32(struct v4l2_format __user *kp,
+ struct v4l2_format32 __user *up)
{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)))
+ if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
return -EFAULT;
return __put_v4l2_format32(kp, up);
}
-static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+static int put_v4l2_create32(struct v4l2_create_buffers __user *kp,
+ struct v4l2_create_buffers32 __user *up)
{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
- copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format)) ||
- copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
+ if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+ copy_in_user(up, kp,
+ offsetof(struct v4l2_create_buffers32, format)) ||
+ copy_in_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
return -EFAULT;
return __put_v4l2_format32(&kp->format, &up->format);
}
@@ -317,25 +330,28 @@ struct v4l2_standard32 {
__u32 reserved[4];
};
-static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
+static int get_v4l2_standard32(struct v4l2_standard __user *kp,
+ struct v4l2_standard32 __user *up)
{
/* other fields are not set by the user, nor used by the driver */
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard32)) ||
- get_user(kp->index, &up->index))
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+ assign_in_user(&kp->index, &up->index))
return -EFAULT;
return 0;
}
-static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up)
+static int put_v4l2_standard32(struct v4l2_standard __user *kp,
+ struct v4l2_standard32 __user *up)
{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard32)) ||
- put_user(kp->index, &up->index) ||
- put_user(kp->id, &up->id) ||
- copy_to_user(up->name, kp->name, 24) ||
- copy_to_user(&up->frameperiod, &kp->frameperiod, sizeof(kp->frameperiod)) ||
- put_user(kp->framelines, &up->framelines) ||
- copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)))
- return -EFAULT;
+ if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+ assign_in_user(&up->index, &kp->index) ||
+ assign_in_user(&up->id, &kp->id) ||
+ copy_in_user(up->name, kp->name, sizeof(up->name)) ||
+ copy_in_user(&up->frameperiod, &kp->frameperiod,
+ sizeof(up->frameperiod)) ||
+ assign_in_user(&up->framelines, &kp->framelines) ||
+ copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+ return -EFAULT;
return 0;
}
@@ -374,136 +390,186 @@ struct v4l2_buffer32 {
__u32 reserved;
};
-static int get_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
- enum v4l2_memory memory)
+static int get_v4l2_plane32(struct v4l2_plane __user *up,
+ struct v4l2_plane32 __user *up32,
+ enum v4l2_memory memory)
{
- void __user *up_pln;
- compat_long_t p;
+ compat_ulong_t p;
if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
- copy_in_user(&up->data_offset, &up32->data_offset,
- sizeof(__u32)))
+ copy_in_user(&up->data_offset, &up32->data_offset,
+ sizeof(up->data_offset)))
return -EFAULT;
- if (memory == V4L2_MEMORY_USERPTR) {
- if (get_user(p, &up32->m.userptr))
- return -EFAULT;
- up_pln = compat_ptr(p);
- if (put_user((unsigned long)up_pln, &up->m.userptr))
+ switch (memory) {
+ case V4L2_MEMORY_MMAP:
+ case V4L2_MEMORY_OVERLAY:
+ if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
+ sizeof(up32->m.mem_offset)))
return -EFAULT;
- } else if (memory == V4L2_MEMORY_DMABUF) {
- if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int)))
+ break;
+ case V4L2_MEMORY_USERPTR:
+ if (get_user(p, &up32->m.userptr) ||
+ put_user((unsigned long)compat_ptr(p), &up->m.userptr))
return -EFAULT;
- } else {
- if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
- sizeof(__u32)))
+ break;
+ case V4L2_MEMORY_DMABUF:
+ if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(up32->m.fd)))
return -EFAULT;
+ break;
}
return 0;
}
-static int put_v4l2_plane32(struct v4l2_plane __user *up, struct v4l2_plane32 __user *up32,
- enum v4l2_memory memory)
+static int put_v4l2_plane32(struct v4l2_plane __user *up,
+ struct v4l2_plane32 __user *up32,
+ enum v4l2_memory memory)
{
+ unsigned long p;
+
if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
- copy_in_user(&up32->data_offset, &up->data_offset,
- sizeof(__u32)))
+ copy_in_user(&up32->data_offset, &up->data_offset,
+ sizeof(up->data_offset)))
return -EFAULT;
- /* For MMAP, driver might've set up the offset, so copy it back.
- * USERPTR stays the same (was userspace-provided), so no copying. */
- if (memory == V4L2_MEMORY_MMAP)
+ switch (memory) {
+ case V4L2_MEMORY_MMAP:
+ case V4L2_MEMORY_OVERLAY:
if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
- sizeof(__u32)))
+ sizeof(up->m.mem_offset)))
return -EFAULT;
- /* For DMABUF, driver might've set up the fd, so copy it back. */
- if (memory == V4L2_MEMORY_DMABUF)
- if (copy_in_user(&up32->m.fd, &up->m.fd,
- sizeof(int)))
+ break;
+ case V4L2_MEMORY_USERPTR:
+ if (get_user(p, &up->m.userptr) ||
+ put_user((compat_ulong_t)ptr_to_compat((__force void *)p),
+ &up32->m.userptr))
return -EFAULT;
+ break;
+ case V4L2_MEMORY_DMABUF:
+ if (copy_in_user(&up32->m.fd, &up->m.fd, sizeof(up->m.fd)))
+ return -EFAULT;
+ break;
+ }
+
+ return 0;
+}
+
+static int bufsize_v4l2_buffer(struct v4l2_buffer32 __user *up, u32 *size)
+{
+ u32 type;
+ u32 length;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+ get_user(type, &up->type) ||
+ get_user(length, &up->length))
+ return -EFAULT;
+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ if (length > VIDEO_MAX_PLANES)
+ return -EINVAL;
+
+ /*
+ * We don't really care if userspace decides to kill itself
+ * by passing a very big length value
+ */
+ *size = length * sizeof(struct v4l2_plane);
+ } else {
+ *size = 0;
+ }
return 0;
}
-static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
+static int get_v4l2_buffer32(struct v4l2_buffer __user *kp,
+ struct v4l2_buffer32 __user *up,
+ void __user *aux_buf, u32 aux_space)
{
+ u32 type;
+ u32 length;
+ enum v4l2_memory memory;
struct v4l2_plane32 __user *uplane32;
struct v4l2_plane __user *uplane;
compat_caddr_t p;
int ret;
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
- get_user(kp->index, &up->index) ||
- get_user(kp->type, &up->type) ||
- get_user(kp->flags, &up->flags) ||
- get_user(kp->memory, &up->memory) ||
- get_user(kp->length, &up->length))
- return -EFAULT;
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+ assign_in_user(&kp->index, &up->index) ||
+ get_user(type, &up->type) ||
+ put_user(type, &kp->type) ||
+ assign_in_user(&kp->flags, &up->flags) ||
+ get_user(memory, &up->memory) ||
+ put_user(memory, &kp->memory) ||
+ get_user(length, &up->length) ||
+ put_user(length, &kp->length))
+ return -EFAULT;
- if (V4L2_TYPE_IS_OUTPUT(kp->type))
- if (get_user(kp->bytesused, &up->bytesused) ||
- get_user(kp->field, &up->field) ||
- get_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
- get_user(kp->timestamp.tv_usec,
- &up->timestamp.tv_usec))
+ if (V4L2_TYPE_IS_OUTPUT(type))
+ if (assign_in_user(&kp->bytesused, &up->bytesused) ||
+ assign_in_user(&kp->field, &up->field) ||
+ assign_in_user(&kp->timestamp.tv_sec,
+ &up->timestamp.tv_sec) ||
+ assign_in_user(&kp->timestamp.tv_usec,
+ &up->timestamp.tv_usec))
return -EFAULT;
- if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
- unsigned int num_planes;
+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ u32 num_planes = length;
- if (kp->length == 0) {
- kp->m.planes = NULL;
- /* num_planes == 0 is legal, e.g. when userspace doesn't
- * need planes array on DQBUF*/
- return 0;
- } else if (kp->length > VIDEO_MAX_PLANES) {
- return -EINVAL;
+ if (num_planes == 0) {
+ /*
+ * num_planes == 0 is legal, e.g. when userspace doesn't
+ * need planes array on DQBUF
+ */
+ return put_user(NULL, &kp->m.planes);
}
+ if (num_planes > VIDEO_MAX_PLANES)
+ return -EINVAL;
if (get_user(p, &up->m.planes))
return -EFAULT;
uplane32 = compat_ptr(p);
if (!access_ok(VERIFY_READ, uplane32,
- kp->length * sizeof(struct v4l2_plane32)))
+ num_planes * sizeof(*uplane32)))
return -EFAULT;
- /* We don't really care if userspace decides to kill itself
- * by passing a very big num_planes value */
- uplane = compat_alloc_user_space(kp->length *
- sizeof(struct v4l2_plane));
- kp->m.planes = (__force struct v4l2_plane *)uplane;
+ /*
+ * We don't really care if userspace decides to kill itself
+ * by passing a very big num_planes value
+ */
+ if (aux_space < num_planes * sizeof(*uplane))
+ return -EFAULT;
- for (num_planes = 0; num_planes < kp->length; num_planes++) {
- ret = get_v4l2_plane32(uplane, uplane32, kp->memory);
+ uplane = aux_buf;
+ if (put_user((__force struct v4l2_plane *)uplane,
+ &kp->m.planes))
+ return -EFAULT;
+
+ while (num_planes--) {
+ ret = get_v4l2_plane32(uplane, uplane32, memory);
if (ret)
return ret;
- ++uplane;
- ++uplane32;
+ uplane++;
+ uplane32++;
}
} else {
- switch (kp->memory) {
+ switch (memory) {
case V4L2_MEMORY_MMAP:
- if (get_user(kp->m.offset, &up->m.offset))
+ case V4L2_MEMORY_OVERLAY:
+ if (assign_in_user(&kp->m.offset, &up->m.offset))
return -EFAULT;
break;
- case V4L2_MEMORY_USERPTR:
- {
- compat_long_t tmp;
+ case V4L2_MEMORY_USERPTR: {
+ compat_ulong_t userptr;
- if (get_user(tmp, &up->m.userptr))
- return -EFAULT;
-
- kp->m.userptr = (unsigned long)compat_ptr(tmp);
- }
- break;
- case V4L2_MEMORY_OVERLAY:
- if (get_user(kp->m.offset, &up->m.offset))
+ if (get_user(userptr, &up->m.userptr) ||
+ put_user((unsigned long)compat_ptr(userptr),
+ &kp->m.userptr))
return -EFAULT;
break;
+ }
case V4L2_MEMORY_DMABUF:
- if (get_user(kp->m.fd, &up->m.fd))
+ if (assign_in_user(&kp->m.fd, &up->m.fd))
return -EFAULT;
break;
}
@@ -512,65 +578,70 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
return 0;
}
-static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
+static int put_v4l2_buffer32(struct v4l2_buffer __user *kp,
+ struct v4l2_buffer32 __user *up)
{
+ u32 type;
+ u32 length;
+ enum v4l2_memory memory;
struct v4l2_plane32 __user *uplane32;
struct v4l2_plane __user *uplane;
compat_caddr_t p;
- int num_planes;
int ret;
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
- put_user(kp->index, &up->index) ||
- put_user(kp->type, &up->type) ||
- put_user(kp->flags, &up->flags) ||
- put_user(kp->memory, &up->memory))
- return -EFAULT;
+ if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+ assign_in_user(&up->index, &kp->index) ||
+ get_user(type, &kp->type) ||
+ put_user(type, &up->type) ||
+ assign_in_user(&up->flags, &kp->flags) ||
+ get_user(memory, &kp->memory) ||
+ put_user(memory, &up->memory))
+ return -EFAULT;
- if (put_user(kp->bytesused, &up->bytesused) ||
- put_user(kp->field, &up->field) ||
- put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
- put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) ||
- copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
- put_user(kp->sequence, &up->sequence) ||
- put_user(kp->reserved2, &up->reserved2) ||
- put_user(kp->reserved, &up->reserved) ||
- put_user(kp->length, &up->length))
- return -EFAULT;
+ if (assign_in_user(&up->bytesused, &kp->bytesused) ||
+ assign_in_user(&up->field, &kp->field) ||
+ assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
+ assign_in_user(&up->timestamp.tv_usec, &kp->timestamp.tv_usec) ||
+ copy_in_user(&up->timecode, &kp->timecode, sizeof(kp->timecode)) ||
+ assign_in_user(&up->sequence, &kp->sequence) ||
+ assign_in_user(&up->reserved2, &kp->reserved2) ||
+ assign_in_user(&up->reserved, &kp->reserved) ||
+ get_user(length, &kp->length) ||
+ put_user(length, &up->length))
+ return -EFAULT;
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
+ u32 num_planes = length;
- if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
- num_planes = kp->length;
if (num_planes == 0)
return 0;
- uplane = (__force struct v4l2_plane __user *)kp->m.planes;
+ if (get_user(uplane, ((__force struct v4l2_plane __user **)&kp->m.planes)))
+ return -EFAULT;
if (get_user(p, &up->m.planes))
return -EFAULT;
uplane32 = compat_ptr(p);
- while (--num_planes >= 0) {
- ret = put_v4l2_plane32(uplane, uplane32, kp->memory);
+ while (num_planes--) {
+ ret = put_v4l2_plane32(uplane, uplane32, memory);
if (ret)
return ret;
++uplane;
++uplane32;
}
} else {
- switch (kp->memory) {
+ switch (memory) {
case V4L2_MEMORY_MMAP:
- if (put_user(kp->m.offset, &up->m.offset))
+ case V4L2_MEMORY_OVERLAY:
+ if (assign_in_user(&up->m.offset, &kp->m.offset))
return -EFAULT;
break;
case V4L2_MEMORY_USERPTR:
- if (put_user(kp->m.userptr, &up->m.userptr))
- return -EFAULT;
- break;
- case V4L2_MEMORY_OVERLAY:
- if (put_user(kp->m.offset, &up->m.offset))
+ if (assign_in_user(&up->m.userptr, &kp->m.userptr))
return -EFAULT;
break;
case V4L2_MEMORY_DMABUF:
- if (put_user(kp->m.fd, &up->m.fd))
+ if (assign_in_user(&up->m.fd, &kp->m.fd))
return -EFAULT;
break;
}
@@ -582,7 +653,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
struct v4l2_framebuffer32 {
__u32 capability;
__u32 flags;
- compat_caddr_t base;
+ compat_caddr_t base;
struct {
__u32 width;
__u32 height;
@@ -595,30 +666,33 @@ struct v4l2_framebuffer32 {
} fmt;
};
-static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
+static int get_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
+ struct v4l2_framebuffer32 __user *up)
{
- u32 tmp;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_framebuffer32)) ||
- get_user(tmp, &up->base) ||
- get_user(kp->capability, &up->capability) ||
- get_user(kp->flags, &up->flags) ||
- copy_from_user(&kp->fmt, &up->fmt, sizeof(up->fmt)))
- return -EFAULT;
- kp->base = (__force void *)compat_ptr(tmp);
+ compat_caddr_t tmp;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+ get_user(tmp, &up->base) ||
+ put_user((__force void *)compat_ptr(tmp), &kp->base) ||
+ assign_in_user(&kp->capability, &up->capability) ||
+ assign_in_user(&kp->flags, &up->flags) ||
+ copy_in_user(&kp->fmt, &up->fmt, sizeof(kp->fmt)))
+ return -EFAULT;
return 0;
}
-static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up)
+static int put_v4l2_framebuffer32(struct v4l2_framebuffer __user *kp,
+ struct v4l2_framebuffer32 __user *up)
{
- u32 tmp = (u32)((unsigned long)kp->base);
-
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_framebuffer32)) ||
- put_user(tmp, &up->base) ||
- put_user(kp->capability, &up->capability) ||
- put_user(kp->flags, &up->flags) ||
- copy_to_user(&up->fmt, &kp->fmt, sizeof(up->fmt)))
- return -EFAULT;
+ void *base;
+
+ if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+ get_user(base, &kp->base) ||
+ put_user(ptr_to_compat(base), &up->base) ||
+ assign_in_user(&up->capability, &kp->capability) ||
+ assign_in_user(&up->flags, &kp->flags) ||
+ copy_in_user(&up->fmt, &kp->fmt, sizeof(kp->fmt)))
+ return -EFAULT;
return 0;
}
@@ -634,18 +708,22 @@ struct v4l2_input32 {
__u32 reserved[3];
};
-/* The 64-bit v4l2_input struct has extra padding at the end of the struct.
- Otherwise it is identical to the 32-bit version. */
-static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
+/*
+ * The 64-bit v4l2_input struct has extra padding at the end of the struct.
+ * Otherwise it is identical to the 32-bit version.
+ */
+static inline int get_v4l2_input32(struct v4l2_input __user *kp,
+ struct v4l2_input32 __user *up)
{
- if (copy_from_user(kp, up, sizeof(struct v4l2_input32)))
+ if (copy_in_user(kp, up, sizeof(*up)))
return -EFAULT;
return 0;
}
-static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
+static inline int put_v4l2_input32(struct v4l2_input __user *kp,
+ struct v4l2_input32 __user *up)
{
- if (copy_to_user(up, kp, sizeof(struct v4l2_input32)))
+ if (copy_in_user(up, kp, sizeof(*up)))
return -EFAULT;
return 0;
}
@@ -669,60 +747,95 @@ struct v4l2_ext_control32 {
};
} __attribute__ ((packed));
-/* The following function really belong in v4l2-common, but that causes
- a circular dependency between modules. We need to think about this, but
- for now this will do. */
-
-/* Return non-zero if this control is a pointer type. Currently only
- type STRING is a pointer type. */
-static inline int ctrl_is_pointer(u32 id)
+/* Return true if this control is a pointer type. */
+static inline bool ctrl_is_pointer(struct file *file, u32 id)
{
- switch (id) {
- case V4L2_CID_RDS_TX_PS_NAME:
- case V4L2_CID_RDS_TX_RADIO_TEXT:
- return 1;
- default:
- return 0;
+ struct video_device *vdev = video_devdata(file);
+ struct v4l2_fh *fh = NULL;
+ struct v4l2_ctrl_handler *hdl = NULL;
+ struct v4l2_query_ext_ctrl qec = { id };
+ const struct v4l2_ioctl_ops *ops = vdev->ioctl_ops;
+
+ if (test_bit(V4L2_FL_USES_V4L2_FH, &vdev->flags))
+ fh = file->private_data;
+
+ if (fh && fh->ctrl_handler)
+ hdl = fh->ctrl_handler;
+ else if (vdev->ctrl_handler)
+ hdl = vdev->ctrl_handler;
+
+ if (hdl) {
+ struct v4l2_ctrl *ctrl = v4l2_ctrl_find(hdl, id);
+
+ return ctrl && ctrl->is_ptr;
}
+
+ if (!ops || !ops->vidioc_query_ext_ctrl)
+ return false;
+
+ return !ops->vidioc_query_ext_ctrl(file, fh, &qec) &&
+ (qec.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD);
+}
+
+static int bufsize_v4l2_ext_controls(struct v4l2_ext_controls32 __user *up,
+ u32 *size)
+{
+ u32 count;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+ get_user(count, &up->count))
+ return -EFAULT;
+ if (count > V4L2_CID_MAX_CTRLS)
+ return -EINVAL;
+ *size = count * sizeof(struct v4l2_ext_control);
+ return 0;
}
-static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
+static int get_v4l2_ext_controls32(struct file *file,
+ struct v4l2_ext_controls __user *kp,
+ struct v4l2_ext_controls32 __user *up,
+ void __user *aux_buf, u32 aux_space)
{
struct v4l2_ext_control32 __user *ucontrols;
struct v4l2_ext_control __user *kcontrols;
- unsigned int n;
+ u32 count;
+ u32 n;
compat_caddr_t p;
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_ext_controls32)) ||
- get_user(kp->which, &up->which) ||
- get_user(kp->count, &up->count) ||
- get_user(kp->error_idx, &up->error_idx) ||
- copy_from_user(kp->reserved, up->reserved,
- sizeof(kp->reserved)))
- return -EFAULT;
- if (kp->count == 0) {
- kp->controls = NULL;
- return 0;
- } else if (kp->count > V4L2_CID_MAX_CTRLS) {
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+ assign_in_user(&kp->which, &up->which) ||
+ get_user(count, &up->count) ||
+ put_user(count, &kp->count) ||
+ assign_in_user(&kp->error_idx, &up->error_idx) ||
+ copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+ return -EFAULT;
+
+ if (count == 0)
+ return put_user(NULL, &kp->controls);
+ if (count > V4L2_CID_MAX_CTRLS)
return -EINVAL;
- }
if (get_user(p, &up->controls))
return -EFAULT;
ucontrols = compat_ptr(p);
- if (!access_ok(VERIFY_READ, ucontrols,
- kp->count * sizeof(struct v4l2_ext_control32)))
+ if (!access_ok(VERIFY_READ, ucontrols, count * sizeof(*ucontrols)))
return -EFAULT;
- kcontrols = compat_alloc_user_space(kp->count *
- sizeof(struct v4l2_ext_control));
- kp->controls = (__force struct v4l2_ext_control *)kcontrols;
- for (n = 0; n < kp->count; n++) {
+ if (aux_space < count * sizeof(*kcontrols))
+ return -EFAULT;
+ kcontrols = aux_buf;
+ if (put_user((__force struct v4l2_ext_control *)kcontrols,
+ &kp->controls))
+ return -EFAULT;
+
+ for (n = 0; n < count; n++) {
u32 id;
if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
return -EFAULT;
+
if (get_user(id, &kcontrols->id))
return -EFAULT;
- if (ctrl_is_pointer(id)) {
+
+ if (ctrl_is_pointer(file, id)) {
void __user *s;
if (get_user(p, &ucontrols->string))
@@ -737,43 +850,55 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
return 0;
}
-static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext_controls32 __user *up)
+static int put_v4l2_ext_controls32(struct file *file,
+ struct v4l2_ext_controls __user *kp,
+ struct v4l2_ext_controls32 __user *up)
{
struct v4l2_ext_control32 __user *ucontrols;
- struct v4l2_ext_control __user *kcontrols =
- (__force struct v4l2_ext_control __user *)kp->controls;
- int n = kp->count;
+ struct v4l2_ext_control __user *kcontrols;
+ u32 count;
+ u32 n;
compat_caddr_t p;
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_ext_controls32)) ||
- put_user(kp->which, &up->which) ||
- put_user(kp->count, &up->count) ||
- put_user(kp->error_idx, &up->error_idx) ||
- copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
- return -EFAULT;
- if (!kp->count)
- return 0;
+ if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+ assign_in_user(&up->which, &kp->which) ||
+ get_user(count, &kp->count) ||
+ put_user(count, &up->count) ||
+ assign_in_user(&up->error_idx, &kp->error_idx) ||
+ copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)) ||
+ get_user(kcontrols, &kp->controls))
+ return -EFAULT;
+ if (!count)
+ return 0;
if (get_user(p, &up->controls))
return -EFAULT;
ucontrols = compat_ptr(p);
- if (!access_ok(VERIFY_WRITE, ucontrols,
- n * sizeof(struct v4l2_ext_control32)))
+ if (!access_ok(VERIFY_WRITE, ucontrols, count * sizeof(*ucontrols)))
return -EFAULT;
- while (--n >= 0) {
- unsigned size = sizeof(*ucontrols);
+ for (n = 0; n < count; n++) {
+ unsigned int size = sizeof(*ucontrols);
u32 id;
- if (get_user(id, &kcontrols->id))
+ if (get_user(id, &kcontrols->id) ||
+ put_user(id, &ucontrols->id) ||
+ assign_in_user(&ucontrols->size, &kcontrols->size) ||
+ copy_in_user(&ucontrols->reserved2, &kcontrols->reserved2,
+ sizeof(ucontrols->reserved2)))
return -EFAULT;
- /* Do not modify the pointer when copying a pointer control.
- The contents of the pointer was changed, not the pointer
- itself. */
- if (ctrl_is_pointer(id))
+
+ /*
+ * Do not modify the pointer when copying a pointer control.
+ * The contents of the pointer was changed, not the pointer
+ * itself.
+ */
+ if (ctrl_is_pointer(file, id))
size -= sizeof(ucontrols->value64);
+
if (copy_in_user(ucontrols, kcontrols, size))
return -EFAULT;
+
ucontrols++;
kcontrols++;
}
@@ -793,18 +918,19 @@ struct v4l2_event32 {
__u32 reserved[8];
};
-static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *up)
+static int put_v4l2_event32(struct v4l2_event __user *kp,
+ struct v4l2_event32 __user *up)
{
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_event32)) ||
- put_user(kp->type, &up->type) ||
- copy_to_user(&up->u, &kp->u, sizeof(kp->u)) ||
- put_user(kp->pending, &up->pending) ||
- put_user(kp->sequence, &up->sequence) ||
- put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
- put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) ||
- put_user(kp->id, &up->id) ||
- copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32)))
- return -EFAULT;
+ if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+ assign_in_user(&up->type, &kp->type) ||
+ copy_in_user(&up->u, &kp->u, sizeof(kp->u)) ||
+ assign_in_user(&up->pending, &kp->pending) ||
+ assign_in_user(&up->sequence, &kp->sequence) ||
+ assign_in_user(&up->timestamp.tv_sec, &kp->timestamp.tv_sec) ||
+ assign_in_user(&up->timestamp.tv_nsec, &kp->timestamp.tv_nsec) ||
+ assign_in_user(&up->id, &kp->id) ||
+ copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+ return -EFAULT;
return 0;
}
@@ -816,32 +942,35 @@ struct v4l2_edid32 {
compat_caddr_t edid;
};
-static int get_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
+static int get_v4l2_edid32(struct v4l2_edid __user *kp,
+ struct v4l2_edid32 __user *up)
{
- u32 tmp;
-
- if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_edid32)) ||
- get_user(kp->pad, &up->pad) ||
- get_user(kp->start_block, &up->start_block) ||
- get_user(kp->blocks, &up->blocks) ||
- get_user(tmp, &up->edid) ||
- copy_from_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
- return -EFAULT;
- kp->edid = (__force u8 *)compat_ptr(tmp);
+ compat_uptr_t tmp;
+
+ if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
+ assign_in_user(&kp->pad, &up->pad) ||
+ assign_in_user(&kp->start_block, &up->start_block) ||
+ assign_in_user(&kp->blocks, &up->blocks) ||
+ get_user(tmp, &up->edid) ||
+ put_user(compat_ptr(tmp), &kp->edid) ||
+ copy_in_user(kp->reserved, up->reserved, sizeof(kp->reserved)))
+ return -EFAULT;
return 0;
}
-static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
+static int put_v4l2_edid32(struct v4l2_edid __user *kp,
+ struct v4l2_edid32 __user *up)
{
- u32 tmp = (u32)((unsigned long)kp->edid);
-
- if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_edid32)) ||
- put_user(kp->pad, &up->pad) ||
- put_user(kp->start_block, &up->start_block) ||
- put_user(kp->blocks, &up->blocks) ||
- put_user(tmp, &up->edid) ||
- copy_to_user(up->reserved, kp->reserved, sizeof(up->reserved)))
- return -EFAULT;
+ void *edid;
+
+ if (!access_ok(VERIFY_WRITE, up, sizeof(*up)) ||
+ assign_in_user(&up->pad, &kp->pad) ||
+ assign_in_user(&up->start_block, &kp->start_block) ||
+ assign_in_user(&up->blocks, &kp->blocks) ||
+ get_user(edid, &kp->edid) ||
+ put_user(ptr_to_compat(edid), &up->edid) ||
+ copy_in_user(up->reserved, kp->reserved, sizeof(up->reserved)))
+ return -EFAULT;
return 0;
}
@@ -857,7 +986,7 @@ static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
#define VIDIOC_ENUMINPUT32 _IOWR('V', 26, struct v4l2_input32)
#define VIDIOC_G_EDID32 _IOWR('V', 40, struct v4l2_edid32)
#define VIDIOC_S_EDID32 _IOWR('V', 41, struct v4l2_edid32)
-#define VIDIOC_TRY_FMT32 _IOWR('V', 64, struct v4l2_format32)
+#define VIDIOC_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)
#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
@@ -873,22 +1002,23 @@ static int put_v4l2_edid32(struct v4l2_edid *kp, struct v4l2_edid32 __user *up)
#define VIDIOC_G_OUTPUT32 _IOR ('V', 46, s32)
#define VIDIOC_S_OUTPUT32 _IOWR('V', 47, s32)
+static int alloc_userspace(unsigned int size, u32 aux_space,
+ void __user **up_native)
+{
+ *up_native = compat_alloc_user_space(size + aux_space);
+ if (!*up_native)
+ return -ENOMEM;
+ if (clear_user(*up_native, size))
+ return -EFAULT;
+ return 0;
+}
+
static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- union {
- struct v4l2_format v2f;
- struct v4l2_buffer v2b;
- struct v4l2_framebuffer v2fb;
- struct v4l2_input v2i;
- struct v4l2_standard v2s;
- struct v4l2_ext_controls v2ecs;
- struct v4l2_event v2ev;
- struct v4l2_create_buffers v2crt;
- struct v4l2_edid v2edid;
- unsigned long vx;
- int vi;
- } karg;
void __user *up = compat_ptr(arg);
+ void __user *up_native = NULL;
+ void __user *aux_buf;
+ u32 aux_space;
int compatible_arg = 1;
long err = 0;
@@ -927,30 +1057,52 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
case VIDIOC_STREAMOFF:
case VIDIOC_S_INPUT:
case VIDIOC_S_OUTPUT:
- err = get_user(karg.vi, (s32 __user *)up);
+ err = alloc_userspace(sizeof(unsigned int), 0, &up_native);
+ if (!err && assign_in_user((unsigned int __user *)up_native,
+ (compat_uint_t __user *)up))
+ err = -EFAULT;
compatible_arg = 0;
break;
case VIDIOC_G_INPUT:
case VIDIOC_G_OUTPUT:
+ err = alloc_userspace(sizeof(unsigned int), 0, &up_native);
compatible_arg = 0;
break;
case VIDIOC_G_EDID:
case VIDIOC_S_EDID:
- err = get_v4l2_edid32(&karg.v2edid, up);
+ err = alloc_userspace(sizeof(struct v4l2_edid), 0, &up_native);
+ if (!err)
+ err = get_v4l2_edid32(up_native, up);
compatible_arg = 0;
break;
case VIDIOC_G_FMT:
case VIDIOC_S_FMT:
case VIDIOC_TRY_FMT:
- err = get_v4l2_format32(&karg.v2f, up);
+ err = bufsize_v4l2_format(up, &aux_space);
+ if (!err)
+ err = alloc_userspace(sizeof(struct v4l2_format),
+ aux_space, &up_native);
+ if (!err) {
+ aux_buf = up_native + sizeof(struct v4l2_format);
+ err = get_v4l2_format32(up_native, up,
+ aux_buf, aux_space);
+ }
compatible_arg = 0;
break;
case VIDIOC_CREATE_BUFS:
- err = get_v4l2_create32(&karg.v2crt, up);
+ err = bufsize_v4l2_create(up, &aux_space);
+ if (!err)
+ err = alloc_userspace(sizeof(struct v4l2_create_buffers),
+ aux_space, &up_native);
+ if (!err) {
+ aux_buf = up_native + sizeof(struct v4l2_create_buffers);
+ err = get_v4l2_create32(up_native, up,
+ aux_buf, aux_space);
+ }
compatible_arg = 0;
break;
@@ -958,36 +1110,63 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
case VIDIOC_QUERYBUF:
case VIDIOC_QBUF:
case VIDIOC_DQBUF:
- err = get_v4l2_buffer32(&karg.v2b, up);
+ err = bufsize_v4l2_buffer(up, &aux_space);
+ if (!err)
+ err = alloc_userspace(sizeof(struct v4l2_buffer),
+ aux_space, &up_native);
+ if (!err) {
+ aux_buf = up_native + sizeof(struct v4l2_buffer);
+ err = get_v4l2_buffer32(up_native, up,
+ aux_buf, aux_space);
+ }
compatible_arg = 0;
break;
case VIDIOC_S_FBUF:
- err = get_v4l2_framebuffer32(&karg.v2fb, up);
+ err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
+ &up_native);
+ if (!err)
+ err = get_v4l2_framebuffer32(up_native, up);
compatible_arg = 0;
break;
case VIDIOC_G_FBUF:
+ err = alloc_userspace(sizeof(struct v4l2_framebuffer), 0,
+ &up_native);
compatible_arg = 0;
break;
case VIDIOC_ENUMSTD:
- err = get_v4l2_standard32(&karg.v2s, up);
+ err = alloc_userspace(sizeof(struct v4l2_standard), 0,
+ &up_native);
+ if (!err)
+ err = get_v4l2_standard32(up_native, up);
compatible_arg = 0;
break;
case VIDIOC_ENUMINPUT:
- err = get_v4l2_input32(&karg.v2i, up);
+ err = alloc_userspace(sizeof(struct v4l2_input), 0, &up_native);
+ if (!err)
+ err = get_v4l2_input32(up_native, up);
compatible_arg = 0;
break;
case VIDIOC_G_EXT_CTRLS:
case VIDIOC_S_EXT_CTRLS:
case VIDIOC_TRY_EXT_CTRLS:
- err = get_v4l2_ext_controls32(&karg.v2ecs, up);
+ err = bufsize_v4l2_ext_controls(up, &aux_space);
+ if (!err)
+ err = alloc_userspace(sizeof(struct v4l2_ext_controls),
+ aux_space, &up_native);
+ if (!err) {
+ aux_buf = up_native + sizeof(struct v4l2_ext_controls);
+ err = get_v4l2_ext_controls32(file, up_native, up,
+ aux_buf, aux_space);
+ }
compatible_arg = 0;
break;
case VIDIOC_DQEVENT:
+ err = alloc_userspace(sizeof(struct v4l2_event), 0, &up_native);
compatible_arg = 0;
break;
}
@@ -996,26 +1175,26 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
if (compatible_arg)
err = native_ioctl(file, cmd, (unsigned long)up);
- else {
- mm_segment_t old_fs = get_fs();
+ else
+ err = native_ioctl(file, cmd, (unsigned long)up_native);
- set_fs(KERNEL_DS);
- err = native_ioctl(file, cmd, (unsigned long)&karg);
- set_fs(old_fs);
- }
+ if (err == -ENOTTY)
+ return err;
- /* Special case: even after an error we need to put the
- results back for these ioctls since the error_idx will
- contain information on which control failed. */
+ /*
+ * Special case: even after an error we need to put the
+ * results back for these ioctls since the error_idx will
+ * contain information on which control failed.
+ */
switch (cmd) {
case VIDIOC_G_EXT_CTRLS:
case VIDIOC_S_EXT_CTRLS:
case VIDIOC_TRY_EXT_CTRLS:
- if (put_v4l2_ext_controls32(&karg.v2ecs, up))
+ if (put_v4l2_ext_controls32(file, up_native, up))
err = -EFAULT;
break;
case VIDIOC_S_EDID:
- if (put_v4l2_edid32(&karg.v2edid, up))
+ if (put_v4l2_edid32(up_native, up))
err = -EFAULT;
break;
}
@@ -1027,43 +1206,46 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
case VIDIOC_S_OUTPUT:
case VIDIOC_G_INPUT:
case VIDIOC_G_OUTPUT:
- err = put_user(((s32)karg.vi), (s32 __user *)up);
+ if (assign_in_user((compat_uint_t __user *)up,
+ ((unsigned int __user *)up_native)))
+ err = -EFAULT;
break;
case VIDIOC_G_FBUF:
- err = put_v4l2_framebuffer32(&karg.v2fb, up);
+ err = put_v4l2_framebuffer32(up_native, up);
break;
case VIDIOC_DQEVENT:
- err = put_v4l2_event32(&karg.v2ev, up);
+ err = put_v4l2_event32(up_native, up);
break;
case VIDIOC_G_EDID:
- err = put_v4l2_edid32(&karg.v2edid, up);
+ err = put_v4l2_edid32(up_native, up);
break;
case VIDIOC_G_FMT:
case VIDIOC_S_FMT:
case VIDIOC_TRY_FMT:
- err = put_v4l2_format32(&karg.v2f, up);
+ err = put_v4l2_format32(up_native, up);
break;
case VIDIOC_CREATE_BUFS:
- err = put_v4l2_create32(&karg.v2crt, up);
+ err = put_v4l2_create32(up_native, up);
break;
+ case VIDIOC_PREPARE_BUF:
case VIDIOC_QUERYBUF:
case VIDIOC_QBUF:
case VIDIOC_DQBUF:
- err = put_v4l2_buffer32(&karg.v2b, up);
+ err = put_v4l2_buffer32(up_native, up);
break;
case VIDIOC_ENUMSTD:
- err = put_v4l2_standard32(&karg.v2s, up);
+ err = put_v4l2_standard32(up_native, up);
break;
case VIDIOC_ENUMINPUT:
- err = put_v4l2_input32(&karg.v2i, up);
+ err = put_v4l2_input32(up_native, up);
break;
}
return err;
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 8ad8c1627768..cd8127d3f863 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -102,7 +102,7 @@ static DECLARE_BITMAP(devnode_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES);
#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
/* Return the bitmap corresponding to vfl_type. */
-static inline unsigned long *devnode_bits(int vfl_type)
+static inline unsigned long *devnode_bits(enum vfl_devnode_type vfl_type)
{
/* Any types not assigned to fixed minor ranges must be mapped to
one single bitmap for the purposes of finding a free node number
@@ -113,7 +113,7 @@ static inline unsigned long *devnode_bits(int vfl_type)
}
#else
/* Return the bitmap corresponding to vfl_type. */
-static inline unsigned long *devnode_bits(int vfl_type)
+static inline unsigned long *devnode_bits(enum vfl_devnode_type vfl_type)
{
return devnode_nums[vfl_type];
}
@@ -821,8 +821,10 @@ static int video_register_media_controller(struct video_device *vdev, int type)
return 0;
}
-int __video_register_device(struct video_device *vdev, int type, int nr,
- int warn_if_nr_in_use, struct module *owner)
+int __video_register_device(struct video_device *vdev,
+ enum vfl_devnode_type type,
+ int nr, int warn_if_nr_in_use,
+ struct module *owner)
{
int i = 0;
int ret;
diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c
index 930f9c53a64e..e2ee5f00c445 100644
--- a/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ b/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -249,7 +249,7 @@ EXPORT_SYMBOL_GPL(v4l2_find_dv_timings_cea861_vic);
* @t2: with this struct.
* @pclock_delta: the allowed pixelclock deviation.
* @match_reduced_fps: if true, then fail if V4L2_DV_FL_REDUCED_FPS does not
- * match.
+ * match.
*
* Compare t1 with t2 with a given margin of error for the pixelclock.
*/
diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c
index fb72c7ac04d4..d630640642ee 100644
--- a/drivers/media/v4l2-core/v4l2-fwnode.c
+++ b/drivers/media/v4l2-core/v4l2-fwnode.c
@@ -359,9 +359,9 @@ static int v4l2_async_notifier_fwnode_parse_endpoint(
return -ENOMEM;
asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
- asd->match.fwnode.fwnode =
+ asd->match.fwnode =
fwnode_graph_get_remote_port_parent(endpoint);
- if (!asd->match.fwnode.fwnode) {
+ if (!asd->match.fwnode) {
dev_warn(dev, "bad remote port parent\n");
ret = -EINVAL;
goto out_err;
@@ -393,7 +393,7 @@ static int v4l2_async_notifier_fwnode_parse_endpoint(
return 0;
out_err:
- fwnode_handle_put(asd->match.fwnode.fwnode);
+ fwnode_handle_put(asd->match.fwnode);
kfree(asd);
return ret == -ENOTCONN ? 0 : ret;
@@ -566,7 +566,7 @@ static int v4l2_fwnode_reference_parse(
}
notifier->subdevs[notifier->num_subdevs] = asd;
- asd->match.fwnode.fwnode = args.fwnode;
+ asd->match.fwnode = args.fwnode;
asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
notifier->num_subdevs++;
}
@@ -853,7 +853,7 @@ static int v4l2_fwnode_reference_parse_int_props(
}
notifier->subdevs[notifier->num_subdevs] = asd;
- asd->match.fwnode.fwnode = fwnode;
+ asd->match.fwnode = fwnode;
asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
notifier->num_subdevs++;
}
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 79614992ee21..260288ca4f55 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -46,37 +46,37 @@ struct std_descr {
};
static const struct std_descr standards[] = {
- { V4L2_STD_NTSC, "NTSC" },
- { V4L2_STD_NTSC_M, "NTSC-M" },
- { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
+ { V4L2_STD_NTSC, "NTSC" },
+ { V4L2_STD_NTSC_M, "NTSC-M" },
+ { V4L2_STD_NTSC_M_JP, "NTSC-M-JP" },
{ V4L2_STD_NTSC_M_KR, "NTSC-M-KR" },
- { V4L2_STD_NTSC_443, "NTSC-443" },
- { V4L2_STD_PAL, "PAL" },
- { V4L2_STD_PAL_BG, "PAL-BG" },
- { V4L2_STD_PAL_B, "PAL-B" },
- { V4L2_STD_PAL_B1, "PAL-B1" },
- { V4L2_STD_PAL_G, "PAL-G" },
- { V4L2_STD_PAL_H, "PAL-H" },
- { V4L2_STD_PAL_I, "PAL-I" },
- { V4L2_STD_PAL_DK, "PAL-DK" },
- { V4L2_STD_PAL_D, "PAL-D" },
- { V4L2_STD_PAL_D1, "PAL-D1" },
- { V4L2_STD_PAL_K, "PAL-K" },
- { V4L2_STD_PAL_M, "PAL-M" },
- { V4L2_STD_PAL_N, "PAL-N" },
- { V4L2_STD_PAL_Nc, "PAL-Nc" },
- { V4L2_STD_PAL_60, "PAL-60" },
- { V4L2_STD_SECAM, "SECAM" },
- { V4L2_STD_SECAM_B, "SECAM-B" },
- { V4L2_STD_SECAM_G, "SECAM-G" },
- { V4L2_STD_SECAM_H, "SECAM-H" },
- { V4L2_STD_SECAM_DK, "SECAM-DK" },
- { V4L2_STD_SECAM_D, "SECAM-D" },
- { V4L2_STD_SECAM_K, "SECAM-K" },
- { V4L2_STD_SECAM_K1, "SECAM-K1" },
- { V4L2_STD_SECAM_L, "SECAM-L" },
- { V4L2_STD_SECAM_LC, "SECAM-Lc" },
- { 0, "Unknown" }
+ { V4L2_STD_NTSC_443, "NTSC-443" },
+ { V4L2_STD_PAL, "PAL" },
+ { V4L2_STD_PAL_BG, "PAL-BG" },
+ { V4L2_STD_PAL_B, "PAL-B" },
+ { V4L2_STD_PAL_B1, "PAL-B1" },
+ { V4L2_STD_PAL_G, "PAL-G" },
+ { V4L2_STD_PAL_H, "PAL-H" },
+ { V4L2_STD_PAL_I, "PAL-I" },
+ { V4L2_STD_PAL_DK, "PAL-DK" },
+ { V4L2_STD_PAL_D, "PAL-D" },
+ { V4L2_STD_PAL_D1, "PAL-D1" },
+ { V4L2_STD_PAL_K, "PAL-K" },
+ { V4L2_STD_PAL_M, "PAL-M" },
+ { V4L2_STD_PAL_N, "PAL-N" },
+ { V4L2_STD_PAL_Nc, "PAL-Nc" },
+ { V4L2_STD_PAL_60, "PAL-60" },
+ { V4L2_STD_SECAM, "SECAM" },
+ { V4L2_STD_SECAM_B, "SECAM-B" },
+ { V4L2_STD_SECAM_G, "SECAM-G" },
+ { V4L2_STD_SECAM_H, "SECAM-H" },
+ { V4L2_STD_SECAM_DK, "SECAM-DK" },
+ { V4L2_STD_SECAM_D, "SECAM-D" },
+ { V4L2_STD_SECAM_K, "SECAM-K" },
+ { V4L2_STD_SECAM_K1, "SECAM-K1" },
+ { V4L2_STD_SECAM_L, "SECAM-L" },
+ { V4L2_STD_SECAM_LC, "SECAM-Lc" },
+ { 0, "Unknown" }
};
/* video4linux standard ID conversion to standard name
@@ -1202,6 +1202,10 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break;
case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break;
case V4L2_PIX_FMT_SRGGB10P: descr = "10-bit Bayer RGRG/GBGB Packed"; break;
+ case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break;
+ case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break;
+ case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break;
+ case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break;
case V4L2_PIX_FMT_SBGGR10ALAW8: descr = "8-bit Bayer BGBG/GRGR (A-law)"; break;
case V4L2_PIX_FMT_SGBRG10ALAW8: descr = "8-bit Bayer GBGB/RGRG (A-law)"; break;
case V4L2_PIX_FMT_SGRBG10ALAW8: descr = "8-bit Bayer GRGR/BGBG (A-law)"; break;
@@ -1246,6 +1250,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_TCH_FMT_TU08: descr = "8-bit unsigned touch data"; break;
case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break;
case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break;
+ case V4L2_META_FMT_UVC: descr = "UVC payload header metadata"; break;
default:
/* Compressed formats */
@@ -1311,52 +1316,50 @@ 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_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
- bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
- bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
- bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
- bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
- int ret = -EINVAL;
+ int ret = check_fmt(file, p->type);
+
+ if (ret)
+ return ret;
+ ret = -EINVAL;
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_enum_fmt_vid_cap))
+ if (unlikely(!ops->vidioc_enum_fmt_vid_cap))
break;
ret = ops->vidioc_enum_fmt_vid_cap(file, fh, arg);
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_cap_mplane))
+ if (unlikely(!ops->vidioc_enum_fmt_vid_cap_mplane))
break;
ret = ops->vidioc_enum_fmt_vid_cap_mplane(file, fh, arg);
break;
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_vid_overlay))
+ if (unlikely(!ops->vidioc_enum_fmt_vid_overlay))
break;
ret = ops->vidioc_enum_fmt_vid_overlay(file, fh, arg);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out))
+ if (unlikely(!ops->vidioc_enum_fmt_vid_out))
break;
ret = ops->vidioc_enum_fmt_vid_out(file, fh, arg);
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!is_tx || !is_vid || !ops->vidioc_enum_fmt_vid_out_mplane))
+ if (unlikely(!ops->vidioc_enum_fmt_vid_out_mplane))
break;
ret = ops->vidioc_enum_fmt_vid_out_mplane(file, fh, arg);
break;
case V4L2_BUF_TYPE_SDR_CAPTURE:
- if (unlikely(!is_rx || !is_sdr || !ops->vidioc_enum_fmt_sdr_cap))
+ if (unlikely(!ops->vidioc_enum_fmt_sdr_cap))
break;
ret = ops->vidioc_enum_fmt_sdr_cap(file, fh, arg);
break;
case V4L2_BUF_TYPE_SDR_OUTPUT:
- if (unlikely(!is_tx || !is_sdr || !ops->vidioc_enum_fmt_sdr_out))
+ if (unlikely(!ops->vidioc_enum_fmt_sdr_out))
break;
ret = ops->vidioc_enum_fmt_sdr_out(file, fh, arg);
break;
case V4L2_BUF_TYPE_META_CAPTURE:
- if (unlikely(!is_rx || !is_vid || !ops->vidioc_enum_fmt_meta_cap))
+ if (unlikely(!ops->vidioc_enum_fmt_meta_cap))
break;
ret = ops->vidioc_enum_fmt_meta_cap(file, fh, arg);
break;
@@ -1370,13 +1373,10 @@ 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_sdr = vfd->vfl_type == VFL_TYPE_SDR;
- bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
- bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
- bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
- int ret;
+ int ret = check_fmt(file, p->type);
+
+ if (ret)
+ return ret;
/*
* fmt can't be cleared for these overlay types due to the 'clips'
@@ -1404,7 +1404,7 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_g_fmt_vid_cap))
+ if (unlikely(!ops->vidioc_g_fmt_vid_cap))
break;
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
ret = ops->vidioc_g_fmt_vid_cap(file, fh, arg);
@@ -1412,23 +1412,15 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
return ret;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_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(!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(!is_tx || !is_vid || !ops->vidioc_g_fmt_vid_out))
+ if (unlikely(!ops->vidioc_g_fmt_vid_out))
break;
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
ret = ops->vidioc_g_fmt_vid_out(file, fh, arg);
@@ -1436,32 +1428,18 @@ static int v4l_g_fmt(const struct v4l2_ioctl_ops *ops,
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
return ret;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_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(!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_OUTPUT:
- 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_OUTPUT:
- if (unlikely(!is_tx || is_vid || !ops->vidioc_g_fmt_sliced_vbi_out))
- break;
return ops->vidioc_g_fmt_sliced_vbi_out(file, fh, arg);
case V4L2_BUF_TYPE_SDR_CAPTURE:
- if (unlikely(!is_rx || !is_sdr || !ops->vidioc_g_fmt_sdr_cap))
- break;
return ops->vidioc_g_fmt_sdr_cap(file, fh, arg);
case V4L2_BUF_TYPE_SDR_OUTPUT:
- if (unlikely(!is_tx || !is_sdr || !ops->vidioc_g_fmt_sdr_out))
- break;
return ops->vidioc_g_fmt_sdr_out(file, fh, arg);
case V4L2_BUF_TYPE_META_CAPTURE:
- if (unlikely(!is_rx || !is_vid || !ops->vidioc_g_fmt_meta_cap))
- break;
return ops->vidioc_g_fmt_meta_cap(file, fh, arg);
}
return -EINVAL;
@@ -1487,12 +1465,10 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
{
struct v4l2_format *p = arg;
struct video_device *vfd = video_devdata(file);
- bool is_vid = vfd->vfl_type == VFL_TYPE_GRABBER;
- bool is_sdr = vfd->vfl_type == VFL_TYPE_SDR;
- bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
- bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
- bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
- int ret;
+ int ret = check_fmt(file, p->type);
+
+ if (ret)
+ return ret;
ret = v4l_enable_media_source(vfd);
if (ret)
@@ -1501,37 +1477,37 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_s_fmt_vid_cap))
+ if (unlikely(!ops->vidioc_s_fmt_vid_cap))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
ret = ops->vidioc_s_fmt_vid_cap(file, fh, arg);
/* just in case the driver zeroed it again */
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
- if (is_tch)
+ if (vfd->vfl_type == VFL_TYPE_TOUCH)
v4l_pix_format_touch(&p->fmt.pix);
return ret;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_cap_mplane))
+ if (unlikely(!ops->vidioc_s_fmt_vid_cap_mplane))
break;
CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
return ops->vidioc_s_fmt_vid_cap_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_vid_overlay))
+ if (unlikely(!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))
+ 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_SLICED_VBI_CAPTURE:
- if (unlikely(!is_rx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_cap))
+ 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_VIDEO_OUTPUT:
- if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out))
+ if (unlikely(!ops->vidioc_s_fmt_vid_out))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
ret = ops->vidioc_s_fmt_vid_out(file, fh, arg);
@@ -1539,37 +1515,37 @@ static int v4l_s_fmt(const struct v4l2_ioctl_ops *ops,
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
return ret;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_mplane))
+ if (unlikely(!ops->vidioc_s_fmt_vid_out_mplane))
break;
CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
return ops->vidioc_s_fmt_vid_out_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (unlikely(!is_tx || !is_vid || !ops->vidioc_s_fmt_vid_out_overlay))
+ if (unlikely(!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_OUTPUT:
- if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_vbi_out))
+ if (unlikely(!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_OUTPUT:
- if (unlikely(!is_tx || is_vid || !ops->vidioc_s_fmt_sliced_vbi_out))
+ if (unlikely(!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_SDR_CAPTURE:
- if (unlikely(!is_rx || !is_sdr || !ops->vidioc_s_fmt_sdr_cap))
+ if (unlikely(!ops->vidioc_s_fmt_sdr_cap))
break;
CLEAR_AFTER_FIELD(p, fmt.sdr);
return ops->vidioc_s_fmt_sdr_cap(file, fh, arg);
case V4L2_BUF_TYPE_SDR_OUTPUT:
- if (unlikely(!is_tx || !is_sdr || !ops->vidioc_s_fmt_sdr_out))
+ if (unlikely(!ops->vidioc_s_fmt_sdr_out))
break;
CLEAR_AFTER_FIELD(p, fmt.sdr);
return ops->vidioc_s_fmt_sdr_out(file, fh, arg);
case V4L2_BUF_TYPE_META_CAPTURE:
- if (unlikely(!is_rx || !is_vid || !ops->vidioc_s_fmt_meta_cap))
+ if (unlikely(!ops->vidioc_s_fmt_meta_cap))
break;
CLEAR_AFTER_FIELD(p, fmt.meta);
return ops->vidioc_s_fmt_meta_cap(file, fh, arg);
@@ -1581,19 +1557,16 @@ 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_sdr = vfd->vfl_type == VFL_TYPE_SDR;
- bool is_tch = vfd->vfl_type == VFL_TYPE_TOUCH;
- bool is_rx = vfd->vfl_dir != VFL_DIR_TX;
- bool is_tx = vfd->vfl_dir != VFL_DIR_RX;
- int ret;
+ int ret = check_fmt(file, p->type);
+
+ if (ret)
+ return ret;
v4l_sanitize_format(p);
switch (p->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (unlikely(!is_rx || (!is_vid && !is_tch) || !ops->vidioc_try_fmt_vid_cap))
+ if (unlikely(!ops->vidioc_try_fmt_vid_cap))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
ret = ops->vidioc_try_fmt_vid_cap(file, fh, arg);
@@ -1601,27 +1574,27 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
return ret;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_cap_mplane))
+ if (unlikely(!ops->vidioc_try_fmt_vid_cap_mplane))
break;
CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
return ops->vidioc_try_fmt_vid_cap_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_vid_overlay))
+ if (unlikely(!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))
+ 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_SLICED_VBI_CAPTURE:
- if (unlikely(!is_rx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_cap))
+ 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_VIDEO_OUTPUT:
- if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out))
+ if (unlikely(!ops->vidioc_try_fmt_vid_out))
break;
CLEAR_AFTER_FIELD(p, fmt.pix);
ret = ops->vidioc_try_fmt_vid_out(file, fh, arg);
@@ -1629,37 +1602,37 @@ static int v4l_try_fmt(const struct v4l2_ioctl_ops *ops,
p->fmt.pix.priv = V4L2_PIX_FMT_PRIV_MAGIC;
return ret;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_mplane))
+ if (unlikely(!ops->vidioc_try_fmt_vid_out_mplane))
break;
CLEAR_AFTER_FIELD(p, fmt.pix_mp.xfer_func);
return ops->vidioc_try_fmt_vid_out_mplane(file, fh, arg);
case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
- if (unlikely(!is_tx || !is_vid || !ops->vidioc_try_fmt_vid_out_overlay))
+ if (unlikely(!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_OUTPUT:
- if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_vbi_out))
+ if (unlikely(!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_OUTPUT:
- if (unlikely(!is_tx || is_vid || !ops->vidioc_try_fmt_sliced_vbi_out))
+ if (unlikely(!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_SDR_CAPTURE:
- if (unlikely(!is_rx || !is_sdr || !ops->vidioc_try_fmt_sdr_cap))
+ if (unlikely(!ops->vidioc_try_fmt_sdr_cap))
break;
CLEAR_AFTER_FIELD(p, fmt.sdr);
return ops->vidioc_try_fmt_sdr_cap(file, fh, arg);
case V4L2_BUF_TYPE_SDR_OUTPUT:
- if (unlikely(!is_tx || !is_sdr || !ops->vidioc_try_fmt_sdr_out))
+ if (unlikely(!ops->vidioc_try_fmt_sdr_out))
break;
CLEAR_AFTER_FIELD(p, fmt.sdr);
return ops->vidioc_try_fmt_sdr_out(file, fh, arg);
case V4L2_BUF_TYPE_META_CAPTURE:
- if (unlikely(!is_rx || !is_vid || !ops->vidioc_try_fmt_meta_cap))
+ if (unlikely(!ops->vidioc_try_fmt_meta_cap))
break;
CLEAR_AFTER_FIELD(p, fmt.meta);
return ops->vidioc_try_fmt_meta_cap(file, fh, arg);
@@ -2539,7 +2512,7 @@ struct v4l2_ioctl_info {
#define INFO_FL_CLEAR(v4l2_struct, field) \
((offsetof(struct v4l2_struct, field) + \
sizeof(((struct v4l2_struct *)0)->field)) << 16)
-#define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16)
+#define INFO_FL_CLEAR_MASK (_IOC_SIZEMASK << 16)
#define IOCTL_INFO_STD(_ioctl, _vidioc, _debug, _flags) \
[_IOC_NR(_ioctl)] = { \
@@ -2927,8 +2900,11 @@ video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
/* Handles IOCTL */
err = func(file, cmd, parg);
- if (err == -ENOIOCTLCMD)
+ if (err == -ENOTTY || err == -ENOIOCTLCMD) {
err = -ENOTTY;
+ goto out;
+ }
+
if (err == 0) {
if (cmd == VIDIOC_DQBUF)
trace_v4l2_dqbuf(video_devdata(file)->minor, parg);
diff --git a/drivers/media/v4l2-core/v4l2-mc.c b/drivers/media/v4l2-core/v4l2-mc.c
index 303980b71aae..1d550afeda13 100644
--- a/drivers/media/v4l2-core/v4l2-mc.c
+++ b/drivers/media/v4l2-core/v4l2-mc.c
@@ -25,8 +25,6 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-mc.h>
#include <media/v4l2-subdev.h>
-#include <media/media-device.h>
-#include <media/v4l2-mc.h>
#include <media/videobuf2-core.h>
int v4l2_mc_create_media_graph(struct media_device *mdev)
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index 1afa27de7191..fcb3a92ae85f 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -1258,20 +1258,6 @@ static struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = {
},
};
-#define DEFINE_SHOW_ATTRIBUTE(__name) \
-static int __name ## _open(struct inode *inode, struct file *file) \
-{ \
- return single_open(file, __name ## _show, inode->i_private); \
-} \
- \
-static const struct file_operations __name ## _fops = { \
- .owner = THIS_MODULE, \
- .open = __name ## _open, \
- .read = seq_read, \
- .llseek = seq_lseek, \
- .release = single_release, \
-} \
-
static irqreturn_t ab8500_debug_handler(int irq, void *data)
{
char buf[16];
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 67bd3344dd03..0eae619419d9 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -605,7 +605,7 @@ config MMC_SDHI
config MMC_SDHI_SYS_DMAC
tristate "DMA for SDHI SD/SDIO controllers using SYS-DMAC"
- depends on MMC_SDHI
+ depends on MMC_SDHI && HAS_DMA
default MMC_SDHI if (SUPERH || ARM)
help
This provides DMA support for SDHI SD/SDIO controllers
@@ -615,7 +615,7 @@ config MMC_SDHI_SYS_DMAC
config MMC_SDHI_INTERNAL_DMAC
tristate "DMA for SDHI SD/SDIO controllers using on-chip bus mastering"
depends on ARM64 || COMPILE_TEST
- depends on MMC_SDHI
+ depends on MMC_SDHI && HAS_DMA
default MMC_SDHI if ARM64
help
This provides DMA support for SDHI SD/SDIO controllers
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index 32a6a228cd12..22438ebfe4e6 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -37,6 +37,7 @@
#include <linux/regulator/consumer.h>
#include <linux/interrupt.h>
#include <linux/bitfield.h>
+#include <linux/pinctrl/consumer.h>
#define DRIVER_NAME "meson-gx-mmc"
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 070aff9c108f..2020e57ffa7e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -21,6 +21,7 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/scatterlist.h>
+#include <linux/sizes.h>
#include <linux/swiotlb.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
@@ -502,8 +503,35 @@ static int sdhci_pre_dma_transfer(struct sdhci_host *host,
if (data->host_cookie == COOKIE_PRE_MAPPED)
return data->sg_count;
- sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
- mmc_get_dma_dir(data));
+ /* Bounce write requests to the bounce buffer */
+ if (host->bounce_buffer) {
+ unsigned int length = data->blksz * data->blocks;
+
+ if (length > host->bounce_buffer_size) {
+ pr_err("%s: asked for transfer of %u bytes exceeds bounce buffer %u bytes\n",
+ mmc_hostname(host->mmc), length,
+ host->bounce_buffer_size);
+ return -EIO;
+ }
+ if (mmc_get_dma_dir(data) == DMA_TO_DEVICE) {
+ /* Copy the data to the bounce buffer */
+ sg_copy_to_buffer(data->sg, data->sg_len,
+ host->bounce_buffer,
+ length);
+ }
+ /* Switch ownership to the DMA */
+ dma_sync_single_for_device(host->mmc->parent,
+ host->bounce_addr,
+ host->bounce_buffer_size,
+ mmc_get_dma_dir(data));
+ /* Just a dummy value */
+ sg_count = 1;
+ } else {
+ /* Just access the data directly from memory */
+ sg_count = dma_map_sg(mmc_dev(host->mmc),
+ data->sg, data->sg_len,
+ mmc_get_dma_dir(data));
+ }
if (sg_count == 0)
return -ENOSPC;
@@ -673,6 +701,14 @@ static void sdhci_adma_table_post(struct sdhci_host *host,
}
}
+static u32 sdhci_sdma_address(struct sdhci_host *host)
+{
+ if (host->bounce_buffer)
+ return host->bounce_addr;
+ else
+ return sg_dma_address(host->data->sg);
+}
+
static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
{
u8 count;
@@ -858,8 +894,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
SDHCI_ADMA_ADDRESS_HI);
} else {
WARN_ON(sg_cnt != 1);
- sdhci_writel(host, sg_dma_address(data->sg),
- SDHCI_DMA_ADDRESS);
+ sdhci_writel(host, sdhci_sdma_address(host),
+ SDHCI_DMA_ADDRESS);
}
}
@@ -2255,7 +2291,12 @@ static void sdhci_pre_req(struct mmc_host *mmc, struct mmc_request *mrq)
mrq->data->host_cookie = COOKIE_UNMAPPED;
- if (host->flags & SDHCI_REQ_USE_DMA)
+ /*
+ * No pre-mapping in the pre hook if we're using the bounce buffer,
+ * for that we would need two bounce buffers since one buffer is
+ * in flight when this is getting called.
+ */
+ if (host->flags & SDHCI_REQ_USE_DMA && !host->bounce_buffer)
sdhci_pre_dma_transfer(host, mrq->data, COOKIE_PRE_MAPPED);
}
@@ -2359,8 +2400,45 @@ static bool sdhci_request_done(struct sdhci_host *host)
struct mmc_data *data = mrq->data;
if (data && data->host_cookie == COOKIE_MAPPED) {
- dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
- mmc_get_dma_dir(data));
+ if (host->bounce_buffer) {
+ /*
+ * On reads, copy the bounced data into the
+ * sglist
+ */
+ if (mmc_get_dma_dir(data) == DMA_FROM_DEVICE) {
+ unsigned int length = data->bytes_xfered;
+
+ if (length > host->bounce_buffer_size) {
+ pr_err("%s: bounce buffer is %u bytes but DMA claims to have transferred %u bytes\n",
+ mmc_hostname(host->mmc),
+ host->bounce_buffer_size,
+ data->bytes_xfered);
+ /* Cap it down and continue */
+ length = host->bounce_buffer_size;
+ }
+ dma_sync_single_for_cpu(
+ host->mmc->parent,
+ host->bounce_addr,
+ host->bounce_buffer_size,
+ DMA_FROM_DEVICE);
+ sg_copy_from_buffer(data->sg,
+ data->sg_len,
+ host->bounce_buffer,
+ length);
+ } else {
+ /* No copying, just switch ownership */
+ dma_sync_single_for_cpu(
+ host->mmc->parent,
+ host->bounce_addr,
+ host->bounce_buffer_size,
+ mmc_get_dma_dir(data));
+ }
+ } else {
+ /* Unmap the raw data */
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len,
+ mmc_get_dma_dir(data));
+ }
data->host_cookie = COOKIE_UNMAPPED;
}
}
@@ -2643,7 +2721,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
*/
if (intmask & SDHCI_INT_DMA_END) {
u32 dmastart, dmanow;
- dmastart = sg_dma_address(host->data->sg);
+
+ dmastart = sdhci_sdma_address(host);
dmanow = dmastart + host->data->bytes_xfered;
/*
* Force update to the next DMA block boundary.
@@ -3234,6 +3313,68 @@ void __sdhci_read_caps(struct sdhci_host *host, u16 *ver, u32 *caps, u32 *caps1)
}
EXPORT_SYMBOL_GPL(__sdhci_read_caps);
+static int sdhci_allocate_bounce_buffer(struct sdhci_host *host)
+{
+ struct mmc_host *mmc = host->mmc;
+ unsigned int max_blocks;
+ unsigned int bounce_size;
+ int ret;
+
+ /*
+ * Cap the bounce buffer at 64KB. Using a bigger bounce buffer
+ * has diminishing returns, this is probably because SD/MMC
+ * cards are usually optimized to handle this size of requests.
+ */
+ bounce_size = SZ_64K;
+ /*
+ * Adjust downwards to maximum request size if this is less
+ * than our segment size, else hammer down the maximum
+ * request size to the maximum buffer size.
+ */
+ if (mmc->max_req_size < bounce_size)
+ bounce_size = mmc->max_req_size;
+ max_blocks = bounce_size / 512;
+
+ /*
+ * When we just support one segment, we can get significant
+ * speedups by the help of a bounce buffer to group scattered
+ * reads/writes together.
+ */
+ host->bounce_buffer = devm_kmalloc(mmc->parent,
+ bounce_size,
+ GFP_KERNEL);
+ if (!host->bounce_buffer) {
+ pr_err("%s: failed to allocate %u bytes for bounce buffer, falling back to single segments\n",
+ mmc_hostname(mmc),
+ bounce_size);
+ /*
+ * Exiting with zero here makes sure we proceed with
+ * mmc->max_segs == 1.
+ */
+ return 0;
+ }
+
+ host->bounce_addr = dma_map_single(mmc->parent,
+ host->bounce_buffer,
+ bounce_size,
+ DMA_BIDIRECTIONAL);
+ ret = dma_mapping_error(mmc->parent, host->bounce_addr);
+ if (ret)
+ /* Again fall back to max_segs == 1 */
+ return 0;
+ host->bounce_buffer_size = bounce_size;
+
+ /* Lie about this since we're bouncing */
+ mmc->max_segs = max_blocks;
+ mmc->max_seg_size = bounce_size;
+ mmc->max_req_size = bounce_size;
+
+ pr_info("%s bounce up to %u segments into one, max segment size %u bytes\n",
+ mmc_hostname(mmc), max_blocks, bounce_size);
+
+ return 0;
+}
+
int sdhci_setup_host(struct sdhci_host *host)
{
struct mmc_host *mmc;
@@ -3730,6 +3871,13 @@ int sdhci_setup_host(struct sdhci_host *host)
*/
mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535;
+ if (mmc->max_segs == 1) {
+ /* This may alter mmc->*_blk_* parameters */
+ ret = sdhci_allocate_bounce_buffer(host);
+ if (ret)
+ return ret;
+ }
+
return 0;
unreg:
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index afab26fd70e6..c95b0a4a7594 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -440,6 +440,9 @@ struct sdhci_host {
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
+ char *bounce_buffer; /* For packing SDMA reads/writes */
+ dma_addr_t bounce_addr;
+ unsigned int bounce_buffer_size;
const struct sdhci_ops *ops; /* Low level hw interface */
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index 7a3ebfd236f5..100adee778df 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -595,7 +595,7 @@ isr_done:
reissue_mask = 1 << 0;
if (!pdata->per_channel_irq)
- reissue_mask |= 0xffff < 4;
+ reissue_mask |= 0xffff << 4;
XP_IOWRITE(pdata, XP_INT_REISSUE_EN, reissue_mask);
}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 3591077a5f6b..ffa7959f6b31 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -812,7 +812,7 @@ static u8 bnx2x_vf_is_pcie_pending(struct bnx2x *bp, u8 abs_vfid)
if (!vf)
return false;
- dev = pci_get_bus_and_slot(vf->bus, vf->devfn);
+ dev = pci_get_domain_bus_and_slot(vf->domain, vf->bus, vf->devfn);
if (dev)
return bnx2x_is_pcie_pending(dev);
return false;
@@ -1041,6 +1041,13 @@ void bnx2x_iov_init_dmae(struct bnx2x *bp)
REG_WR(bp, DMAE_REG_BACKWARD_COMP_EN, 0);
}
+static int bnx2x_vf_domain(struct bnx2x *bp, int vfid)
+{
+ struct pci_dev *dev = bp->pdev;
+
+ return pci_domain_nr(dev->bus);
+}
+
static int bnx2x_vf_bus(struct bnx2x *bp, int vfid)
{
struct pci_dev *dev = bp->pdev;
@@ -1606,6 +1613,7 @@ int bnx2x_iov_nic_init(struct bnx2x *bp)
struct bnx2x_virtf *vf = BP_VF(bp, vfid);
/* fill in the BDF and bars */
+ vf->domain = bnx2x_vf_domain(bp, vfid);
vf->bus = bnx2x_vf_bus(bp, vfid);
vf->devfn = bnx2x_vf_devfn(bp, vfid);
bnx2x_vf_set_bars(bp, vf);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index 53466f6cebab..eb814c65152f 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -182,6 +182,7 @@ struct bnx2x_virtf {
u32 error; /* 0 means all's-well */
/* BDF */
+ unsigned int domain;
unsigned int bus;
unsigned int devfn;
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 8984c4938881..382891f81e09 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -248,6 +248,7 @@ struct be_tx_stats {
u32 tx_spoof_check_err;
u32 tx_qinq_err;
u32 tx_internal_parity_err;
+ u32 tx_sge_err;
struct u64_stats_sync sync;
struct u64_stats_sync sync_compl;
};
@@ -944,8 +945,10 @@ static inline bool is_ipv6_ext_hdr(struct sk_buff *skb)
#define BE_ERROR_EEH 1
#define BE_ERROR_UE BIT(1)
#define BE_ERROR_FW BIT(2)
-#define BE_ERROR_HW (BE_ERROR_EEH | BE_ERROR_UE)
-#define BE_ERROR_ANY (BE_ERROR_EEH | BE_ERROR_UE | BE_ERROR_FW)
+#define BE_ERROR_TX BIT(3)
+#define BE_ERROR_HW (BE_ERROR_EEH | BE_ERROR_UE | BE_ERROR_TX)
+#define BE_ERROR_ANY (BE_ERROR_EEH | BE_ERROR_UE | BE_ERROR_FW | \
+ BE_ERROR_TX)
#define BE_CLEAR_ALL 0xFF
static inline u8 be_check_error(struct be_adapter *adapter, u32 err_type)
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 7d1819c9e8cc..7f7e206f95f8 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -189,6 +189,7 @@ static const struct be_ethtool_stat et_tx_stats[] = {
* packet data. This counter is applicable only for Lancer adapters.
*/
{DRVSTAT_TX_INFO(tx_internal_parity_err)},
+ {DRVSTAT_TX_INFO(tx_sge_err)},
{DRVSTAT_TX_INFO(tx_bytes)},
{DRVSTAT_TX_INFO(tx_pkts)},
{DRVSTAT_TX_INFO(tx_vxlan_offload_pkts)},
diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h
index c967f45705d9..db5f92fb87e0 100644
--- a/drivers/net/ethernet/emulex/benet/be_hw.h
+++ b/drivers/net/ethernet/emulex/benet/be_hw.h
@@ -261,6 +261,7 @@ struct be_eth_hdr_wrb {
#define LANCER_TX_COMP_HSW_DROP_MAC_ERR 0x3
#define LANCER_TX_COMP_HSW_DROP_VLAN_ERR 0x5
#define LANCER_TX_COMP_QINQ_ERR 0x7
+#define LANCER_TX_COMP_SGE_ERR 0x9
#define LANCER_TX_COMP_PARITY_ERR 0xb
#define LANCER_TX_COMP_DMA_ERR 0xd
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index d81e2d37bc3d..5774fb6f8aa0 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2583,7 +2583,48 @@ static void be_post_rx_frags(struct be_rx_obj *rxo, gfp_t gfp, u32 frags_needed)
}
}
-static struct be_tx_compl_info *be_tx_compl_get(struct be_tx_obj *txo)
+static inline void be_update_tx_err(struct be_tx_obj *txo, u8 status)
+{
+ switch (status) {
+ case BE_TX_COMP_HDR_PARSE_ERR:
+ tx_stats(txo)->tx_hdr_parse_err++;
+ break;
+ case BE_TX_COMP_NDMA_ERR:
+ tx_stats(txo)->tx_dma_err++;
+ break;
+ case BE_TX_COMP_ACL_ERR:
+ tx_stats(txo)->tx_spoof_check_err++;
+ break;
+ }
+}
+
+static inline void lancer_update_tx_err(struct be_tx_obj *txo, u8 status)
+{
+ switch (status) {
+ case LANCER_TX_COMP_LSO_ERR:
+ tx_stats(txo)->tx_tso_err++;
+ break;
+ case LANCER_TX_COMP_HSW_DROP_MAC_ERR:
+ case LANCER_TX_COMP_HSW_DROP_VLAN_ERR:
+ tx_stats(txo)->tx_spoof_check_err++;
+ break;
+ case LANCER_TX_COMP_QINQ_ERR:
+ tx_stats(txo)->tx_qinq_err++;
+ break;
+ case LANCER_TX_COMP_PARITY_ERR:
+ tx_stats(txo)->tx_internal_parity_err++;
+ break;
+ case LANCER_TX_COMP_DMA_ERR:
+ tx_stats(txo)->tx_dma_err++;
+ break;
+ case LANCER_TX_COMP_SGE_ERR:
+ tx_stats(txo)->tx_sge_err++;
+ break;
+ }
+}
+
+static struct be_tx_compl_info *be_tx_compl_get(struct be_adapter *adapter,
+ struct be_tx_obj *txo)
{
struct be_queue_info *tx_cq = &txo->cq;
struct be_tx_compl_info *txcp = &txo->txcp;
@@ -2599,6 +2640,24 @@ static struct be_tx_compl_info *be_tx_compl_get(struct be_tx_obj *txo)
txcp->status = GET_TX_COMPL_BITS(status, compl);
txcp->end_index = GET_TX_COMPL_BITS(wrb_index, compl);
+ if (txcp->status) {
+ if (lancer_chip(adapter)) {
+ lancer_update_tx_err(txo, txcp->status);
+ /* Reset the adapter incase of TSO,
+ * SGE or Parity error
+ */
+ if (txcp->status == LANCER_TX_COMP_LSO_ERR ||
+ txcp->status == LANCER_TX_COMP_PARITY_ERR ||
+ txcp->status == LANCER_TX_COMP_SGE_ERR)
+ be_set_error(adapter, BE_ERROR_TX);
+ } else {
+ be_update_tx_err(txo, txcp->status);
+ }
+ }
+
+ if (be_check_error(adapter, BE_ERROR_TX))
+ return NULL;
+
compl->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] = 0;
queue_tail_inc(tx_cq);
return txcp;
@@ -2741,7 +2800,7 @@ static void be_tx_compl_clean(struct be_adapter *adapter)
cmpl = 0;
num_wrbs = 0;
txq = &txo->q;
- while ((txcp = be_tx_compl_get(txo))) {
+ while ((txcp = be_tx_compl_get(adapter, txo))) {
num_wrbs +=
be_tx_compl_process(adapter, txo,
txcp->end_index);
@@ -3120,42 +3179,6 @@ loop_continue:
return work_done;
}
-static inline void be_update_tx_err(struct be_tx_obj *txo, u8 status)
-{
- switch (status) {
- case BE_TX_COMP_HDR_PARSE_ERR:
- tx_stats(txo)->tx_hdr_parse_err++;
- break;
- case BE_TX_COMP_NDMA_ERR:
- tx_stats(txo)->tx_dma_err++;
- break;
- case BE_TX_COMP_ACL_ERR:
- tx_stats(txo)->tx_spoof_check_err++;
- break;
- }
-}
-
-static inline void lancer_update_tx_err(struct be_tx_obj *txo, u8 status)
-{
- switch (status) {
- case LANCER_TX_COMP_LSO_ERR:
- tx_stats(txo)->tx_tso_err++;
- break;
- case LANCER_TX_COMP_HSW_DROP_MAC_ERR:
- case LANCER_TX_COMP_HSW_DROP_VLAN_ERR:
- tx_stats(txo)->tx_spoof_check_err++;
- break;
- case LANCER_TX_COMP_QINQ_ERR:
- tx_stats(txo)->tx_qinq_err++;
- break;
- case LANCER_TX_COMP_PARITY_ERR:
- tx_stats(txo)->tx_internal_parity_err++;
- break;
- case LANCER_TX_COMP_DMA_ERR:
- tx_stats(txo)->tx_dma_err++;
- break;
- }
-}
static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
int idx)
@@ -3163,16 +3186,9 @@ static void be_process_tx(struct be_adapter *adapter, struct be_tx_obj *txo,
int num_wrbs = 0, work_done = 0;
struct be_tx_compl_info *txcp;
- while ((txcp = be_tx_compl_get(txo))) {
+ while ((txcp = be_tx_compl_get(adapter, txo))) {
num_wrbs += be_tx_compl_process(adapter, txo, txcp->end_index);
work_done++;
-
- if (txcp->status) {
- if (lancer_chip(adapter))
- lancer_update_tx_err(txo, txcp->status);
- else
- be_update_tx_err(txo, txcp->status);
- }
}
if (work_done) {
@@ -5104,9 +5120,12 @@ static netdev_features_t be_features_check(struct sk_buff *skb,
features &= ~NETIF_F_TSO6;
/* Lancer cannot handle the packet with MSS less than 256.
+ * Also it can't handle a TSO packet with a single segment
* Disable the GSO support in such cases
*/
- if (lancer_chip(adapter) && skb_shinfo(skb)->gso_size < 256)
+ if (lancer_chip(adapter) &&
+ (skb_shinfo(skb)->gso_size < 256 ||
+ skb_shinfo(skb)->gso_segs == 1))
features &= ~NETIF_F_GSO_MASK;
}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
index 7d95f0866fb0..28a81ac97af5 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.c
@@ -143,7 +143,7 @@ int hinic_alloc_cmdq_buf(struct hinic_cmdqs *cmdqs,
struct hinic_hwif *hwif = cmdqs->hwif;
struct pci_dev *pdev = hwif->pdev;
- cmdq_buf->buf = pci_pool_alloc(cmdqs->cmdq_buf_pool, GFP_KERNEL,
+ cmdq_buf->buf = dma_pool_alloc(cmdqs->cmdq_buf_pool, GFP_KERNEL,
&cmdq_buf->dma_addr);
if (!cmdq_buf->buf) {
dev_err(&pdev->dev, "Failed to allocate cmd from the pool\n");
@@ -161,7 +161,7 @@ int hinic_alloc_cmdq_buf(struct hinic_cmdqs *cmdqs,
void hinic_free_cmdq_buf(struct hinic_cmdqs *cmdqs,
struct hinic_cmdq_buf *cmdq_buf)
{
- pci_pool_free(cmdqs->cmdq_buf_pool, cmdq_buf->buf, cmdq_buf->dma_addr);
+ dma_pool_free(cmdqs->cmdq_buf_pool, cmdq_buf->buf, cmdq_buf->dma_addr);
}
static unsigned int cmdq_wqe_size_from_bdlen(enum bufdesc_len len)
@@ -875,7 +875,7 @@ int hinic_init_cmdqs(struct hinic_cmdqs *cmdqs, struct hinic_hwif *hwif,
int err;
cmdqs->hwif = hwif;
- cmdqs->cmdq_buf_pool = pci_pool_create("hinic_cmdq", pdev,
+ cmdqs->cmdq_buf_pool = dma_pool_create("hinic_cmdq", &pdev->dev,
HINIC_CMDQ_BUF_SIZE,
HINIC_CMDQ_BUF_SIZE, 0);
if (!cmdqs->cmdq_buf_pool)
@@ -916,7 +916,7 @@ err_cmdq_wqs:
devm_kfree(&pdev->dev, cmdqs->saved_wqs);
err_saved_wqs:
- pci_pool_destroy(cmdqs->cmdq_buf_pool);
+ dma_pool_destroy(cmdqs->cmdq_buf_pool);
return err;
}
@@ -942,5 +942,5 @@ void hinic_free_cmdqs(struct hinic_cmdqs *cmdqs)
devm_kfree(&pdev->dev, cmdqs->saved_wqs);
- pci_pool_destroy(cmdqs->cmdq_buf_pool);
+ dma_pool_destroy(cmdqs->cmdq_buf_pool);
}
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
index b35583400cb6..23f8d39eab68 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_cmdq.h
@@ -157,7 +157,7 @@ struct hinic_cmdq {
struct hinic_cmdqs {
struct hinic_hwif *hwif;
- struct pci_pool *cmdq_buf_pool;
+ struct dma_pool *cmdq_buf_pool;
struct hinic_wq *saved_wqs;
diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
index 5caaa9033841..afaf29b201dc 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -3286,7 +3286,7 @@ static void handle_vpd_rsp(union ibmvnic_crq *crq,
struct ibmvnic_adapter *adapter)
{
struct device *dev = &adapter->vdev->dev;
- unsigned char *substr = NULL, *ptr = NULL;
+ unsigned char *substr = NULL;
u8 fw_level_len = 0;
memset(adapter->fw_version, 0, 32);
@@ -3306,10 +3306,6 @@ static void handle_vpd_rsp(union ibmvnic_crq *crq,
substr = strnstr(adapter->vpd->buff, "RM", adapter->vpd->len);
if (!substr) {
dev_info(dev, "Warning - No FW level has been provided in the VPD buffer by the VIOS Server\n");
- ptr = strncpy((char *)adapter->fw_version, "N/A",
- 3 * sizeof(char));
- if (!ptr)
- dev_err(dev, "Failed to inform that firmware version is unavailable to the adapter\n");
goto complete;
}
@@ -3324,16 +3320,14 @@ static void handle_vpd_rsp(union ibmvnic_crq *crq,
/* copy firmware version string from vpd into adapter */
if ((substr + 3 + fw_level_len) <
(adapter->vpd->buff + adapter->vpd->len)) {
- ptr = strncpy((char *)adapter->fw_version,
- substr + 3, fw_level_len);
-
- if (!ptr)
- dev_err(dev, "Failed to isolate FW level string\n");
+ strncpy((char *)adapter->fw_version, substr + 3, fw_level_len);
} else {
dev_info(dev, "FW substr extrapolated VPD buff\n");
}
complete:
+ if (adapter->fw_version[0] == '\0')
+ strncpy((char *)adapter->fw_version, "N/A", 3 * sizeof(char));
complete(&adapter->fw_done);
}
diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c
index 44b3937f7e81..29486478836e 100644
--- a/drivers/net/ethernet/intel/e100.c
+++ b/drivers/net/ethernet/intel/e100.c
@@ -607,7 +607,7 @@ struct nic {
struct mem *mem;
dma_addr_t dma_addr;
- struct pci_pool *cbs_pool;
+ struct dma_pool *cbs_pool;
dma_addr_t cbs_dma_addr;
u8 adaptive_ifs;
u8 tx_threshold;
@@ -1892,7 +1892,7 @@ static void e100_clean_cbs(struct nic *nic)
nic->cb_to_clean = nic->cb_to_clean->next;
nic->cbs_avail++;
}
- pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr);
+ dma_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr);
nic->cbs = NULL;
nic->cbs_avail = 0;
}
@@ -1910,7 +1910,7 @@ static int e100_alloc_cbs(struct nic *nic)
nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL;
nic->cbs_avail = 0;
- nic->cbs = pci_pool_zalloc(nic->cbs_pool, GFP_KERNEL,
+ nic->cbs = dma_pool_zalloc(nic->cbs_pool, GFP_KERNEL,
&nic->cbs_dma_addr);
if (!nic->cbs)
return -ENOMEM;
@@ -2960,8 +2960,8 @@ static int e100_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
netif_err(nic, probe, nic->netdev, "Cannot register net device, aborting\n");
goto err_out_free;
}
- nic->cbs_pool = pci_pool_create(netdev->name,
- nic->pdev,
+ nic->cbs_pool = dma_pool_create(netdev->name,
+ &nic->pdev->dev,
nic->params.cbs.max * sizeof(struct cb),
sizeof(u32),
0);
@@ -3001,7 +3001,7 @@ static void e100_remove(struct pci_dev *pdev)
unregister_netdev(netdev);
e100_free(nic);
pci_iounmap(pdev, nic->csr);
- pci_pool_destroy(nic->cbs_pool);
+ dma_pool_destroy(nic->cbs_pool);
free_netdev(netdev);
pci_release_regions(pdev);
pci_disable_device(pdev);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 29826dd15204..e0b72bf428f7 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -23,6 +23,7 @@
#include <linux/reset.h>
#include <linux/tcp.h>
#include <linux/interrupt.h>
+#include <linux/pinctrl/devinfo.h>
#include "mtk_eth_soc.h"
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index 05c1157bc9f2..25106e996a96 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -51,7 +51,7 @@ enum {
enum {
MLX5_NUM_SPARE_EQE = 0x80,
- MLX5_NUM_ASYNC_EQE = 0x100,
+ MLX5_NUM_ASYNC_EQE = 0x1000,
MLX5_NUM_CMD_EQE = 32,
MLX5_NUM_PF_DRAIN = 64,
};
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h
index 424fe8338105..054df3dc0698 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.h
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h
@@ -112,22 +112,22 @@ enum pkt_vec {
* @map_elems_in_use: number of elements allocated to offloaded maps
*
* @adjust_head: adjust head capability
- * @flags: extra flags for adjust head
- * @off_min: minimal packet offset within buffer required
- * @off_max: maximum packet offset within buffer required
- * @guaranteed_sub: amount of negative adjustment guaranteed possible
- * @guaranteed_add: amount of positive adjustment guaranteed possible
+ * @adjust_head.flags: extra flags for adjust head
+ * @adjust_head.off_min: minimal packet offset within buffer required
+ * @adjust_head.off_max: maximum packet offset within buffer required
+ * @adjust_head.guaranteed_sub: negative adjustment guaranteed possible
+ * @adjust_head.guaranteed_add: positive adjustment guaranteed possible
*
* @maps: map capability
- * @types: supported map types
- * @max_maps: max number of maps supported
- * @max_elems: max number of entries in each map
- * @max_key_sz: max size of map key
- * @max_val_sz: max size of map value
- * @max_elem_sz: max size of map entry (key + value)
+ * @maps.types: supported map types
+ * @maps.max_maps: max number of maps supported
+ * @maps.max_elems: max number of entries in each map
+ * @maps.max_key_sz: max size of map key
+ * @maps.max_val_sz: max size of map value
+ * @maps.max_elem_sz: max size of map entry (key + value)
*
* @helpers: helper addressess for various calls
- * @map_lookup: map lookup helper address
+ * @helpers.map_lookup: map lookup helper address
*/
struct nfp_app_bpf {
struct nfp_app *app;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
index b03f22f29612..ec524d97869d 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
@@ -50,9 +50,9 @@
* @seq: sequence number of the message
* @count: number of tunnels report in message
* @flags: options part of the request
- * @ipv4: dest IPv4 address of active route
- * @egress_port: port the encapsulated packet egressed
- * @extra: reserved for future use
+ * @tun_info.ipv4: dest IPv4 address of active route
+ * @tun_info.egress_port: port the encapsulated packet egressed
+ * @tun_info.extra: reserved for future use
* @tun_info: tunnels that have sent traffic in reported period
*/
struct nfp_tun_active_tuns {
@@ -132,8 +132,8 @@ struct nfp_ipv4_addr_entry {
* struct nfp_tun_mac_addr - configure MAC address of tunnel EP on NFP
* @reserved: reserved for future use
* @count: number of MAC addresses in the message
- * @index: index of MAC address in the lookup table
- * @addr: interface MAC address
+ * @addresses.index: index of MAC address in the lookup table
+ * @addresses.addr: interface MAC address
* @addresses: series of MACs to offload
*/
struct nfp_tun_mac_addr {
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net.h b/drivers/net/ethernet/netronome/nfp/nfp_net.h
index d88eda9707e6..787df47ec430 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net.h
@@ -193,7 +193,8 @@ struct nfp_net_tx_desc {
/**
* struct nfp_net_tx_buf - software TX buffer descriptor
- * @skb: sk_buff associated with this buffer
+ * @skb: normal ring, sk_buff associated with this buffer
+ * @frag: XDP ring, page frag associated with this buffer
* @dma_addr: DMA mapping address of the buffer
* @fidx: Fragment index (-1 for the head and [0..nr_frags-1] for frags)
* @pkt_cnt: Number of packets to be produced out of the skb associated
@@ -377,6 +378,9 @@ struct nfp_net_rx_ring {
* struct nfp_net_r_vector - Per ring interrupt vector configuration
* @nfp_net: Backpointer to nfp_net structure
* @napi: NAPI structure for this ring vec
+ * @tasklet: ctrl vNIC, tasklet for servicing the r_vec
+ * @queue: ctrl vNIC, send queue
+ * @lock: ctrl vNIC, r_vec lock protects @queue
* @tx_ring: Pointer to TX ring
* @rx_ring: Pointer to RX ring
* @xdp_ring: Pointer to an extra TX ring for XDP
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
index e983c9d7f86c..f23d9e06f097 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h
@@ -98,28 +98,29 @@ enum nfp_eth_fec {
* @max_index: max of @index fields of all @ports
* @ports: table of ports
*
- * @eth_index: port index according to legacy ethX numbering
- * @index: chip-wide first channel index
- * @nbi: NBI index
- * @base: first channel index (within NBI)
- * @lanes: number of channels
- * @speed: interface speed (in Mbps)
- * @interface: interface (module) plugged in
- * @media: media type of the @interface
- * @fec: forward error correction mode
- * @aneg: auto negotiation mode
- * @mac_addr: interface MAC address
- * @label_port: port id
- * @label_subport: id of interface within port (for split ports)
- * @enabled: is enabled?
- * @tx_enabled: is TX enabled?
- * @rx_enabled: is RX enabled?
- * @override_changed: is media reconfig pending?
+ * @ports.eth_index: port index according to legacy ethX numbering
+ * @ports.index: chip-wide first channel index
+ * @ports.nbi: NBI index
+ * @ports.base: first channel index (within NBI)
+ * @ports.lanes: number of channels
+ * @ports.speed: interface speed (in Mbps)
+ * @ports.interface: interface (module) plugged in
+ * @ports.media: media type of the @interface
+ * @ports.fec: forward error correction mode
+ * @ports.aneg: auto negotiation mode
+ * @ports.mac_addr: interface MAC address
+ * @ports.label_port: port id
+ * @ports.label_subport: id of interface within port (for split ports)
+ * @ports.enabled: is enabled?
+ * @ports.tx_enabled: is TX enabled?
+ * @ports.rx_enabled: is RX enabled?
+ * @ports.override_changed: is media reconfig pending?
*
- * @port_type: one of %PORT_* defines for ethtool
- * @port_lanes: total number of lanes on the port (sum of lanes of all subports)
- * @is_split: is interface part of a split port
- * @fec_modes_supported: bitmap of FEC modes supported
+ * @ports.port_type: one of %PORT_* defines for ethtool
+ * @ports.port_lanes: total number of lanes on the port (sum of lanes of all
+ * subports)
+ * @ports.is_split: is interface part of a split port
+ * @ports.fec_modes_supported: bitmap of FEC modes supported
*/
struct nfp_eth_table {
unsigned int count;
diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
index b1dd13ff282b..7e14725055c7 100644
--- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
+++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c
@@ -56,16 +56,17 @@
/**
* struct nfp_resource_entry - Resource table entry
- * @owner: NFP CPP Lock, interface owner
- * @key: NFP CPP Lock, posix_crc32(name, 8)
- * @region: Memory region descriptor
- * @name: ASCII, zero padded name
- * @reserved
- * @cpp_action: CPP Action
- * @cpp_token: CPP Token
- * @cpp_target: CPP Target ID
- * @page_offset: 256-byte page offset into target's CPP address
- * @page_size: size, in 256-byte pages
+ * @mutex: NFP CPP Lock
+ * @mutex.owner: NFP CPP Lock, interface owner
+ * @mutex.key: NFP CPP Lock, posix_crc32(name, 8)
+ * @region: Memory region descriptor
+ * @region.name: ASCII, zero padded name
+ * @region.reserved: padding
+ * @region.cpp_action: CPP Action
+ * @region.cpp_token: CPP Token
+ * @region.cpp_target: CPP Target ID
+ * @region.page_offset: 256-byte page offset into target's CPP address
+ * @region.page_size: size, in 256-byte pages
*/
struct nfp_resource_entry {
struct nfp_resource_entry_mutex {
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 40e52ffb732f..7cd494611a74 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -2594,8 +2594,10 @@ static int pch_gbe_probe(struct pci_dev *pdev,
if (adapter->pdata && adapter->pdata->platform_init)
adapter->pdata->platform_init(pdev);
- adapter->ptp_pdev = pci_get_bus_and_slot(adapter->pdev->bus->number,
- PCI_DEVFN(12, 4));
+ adapter->ptp_pdev =
+ pci_get_domain_bus_and_slot(pci_domain_nr(adapter->pdev->bus),
+ adapter->pdev->bus->number,
+ PCI_DEVFN(12, 4));
netdev->netdev_ops = &pch_gbe_netdev_ops;
netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD;
diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c
index 0624b71ab5d4..edcd1e60b30d 100644
--- a/drivers/net/ethernet/tundra/tsi108_eth.c
+++ b/drivers/net/ethernet/tundra/tsi108_eth.c
@@ -152,6 +152,8 @@ struct tsi108_prv_data {
u32 msg_enable; /* debug message level */
struct mii_if_info mii_if;
unsigned int init_media;
+
+ struct platform_device *pdev;
};
/* Structure for a device driver */
@@ -703,17 +705,18 @@ static int tsi108_send_packet(struct sk_buff * skb, struct net_device *dev)
data->txskbs[tx] = skb;
if (i == 0) {
- data->txring[tx].buf0 = dma_map_single(NULL, skb->data,
- skb_headlen(skb), DMA_TO_DEVICE);
+ data->txring[tx].buf0 = dma_map_single(&data->pdev->dev,
+ skb->data, skb_headlen(skb),
+ DMA_TO_DEVICE);
data->txring[tx].len = skb_headlen(skb);
misc |= TSI108_TX_SOF;
} else {
const skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
- data->txring[tx].buf0 = skb_frag_dma_map(NULL, frag,
- 0,
- skb_frag_size(frag),
- DMA_TO_DEVICE);
+ data->txring[tx].buf0 =
+ skb_frag_dma_map(&data->pdev->dev, frag,
+ 0, skb_frag_size(frag),
+ DMA_TO_DEVICE);
data->txring[tx].len = skb_frag_size(frag);
}
@@ -808,9 +811,9 @@ static int tsi108_refill_rx(struct net_device *dev, int budget)
if (!skb)
break;
- data->rxring[rx].buf0 = dma_map_single(NULL, skb->data,
- TSI108_RX_SKB_SIZE,
- DMA_FROM_DEVICE);
+ data->rxring[rx].buf0 = dma_map_single(&data->pdev->dev,
+ skb->data, TSI108_RX_SKB_SIZE,
+ DMA_FROM_DEVICE);
/* Sometimes the hardware sets blen to zero after packet
* reception, even though the manual says that it's only ever
@@ -1308,15 +1311,15 @@ static int tsi108_open(struct net_device *dev)
data->id, dev->irq, dev->name);
}
- data->rxring = dma_zalloc_coherent(NULL, rxring_size, &data->rxdma,
- GFP_KERNEL);
+ data->rxring = dma_zalloc_coherent(&data->pdev->dev, rxring_size,
+ &data->rxdma, GFP_KERNEL);
if (!data->rxring)
return -ENOMEM;
- data->txring = dma_zalloc_coherent(NULL, txring_size, &data->txdma,
- GFP_KERNEL);
+ data->txring = dma_zalloc_coherent(&data->pdev->dev, txring_size,
+ &data->txdma, GFP_KERNEL);
if (!data->txring) {
- pci_free_consistent(NULL, rxring_size, data->rxring,
+ dma_free_coherent(&data->pdev->dev, rxring_size, data->rxring,
data->rxdma);
return -ENOMEM;
}
@@ -1428,10 +1431,10 @@ static int tsi108_close(struct net_device *dev)
dev_kfree_skb(skb);
}
- dma_free_coherent(0,
+ dma_free_coherent(&data->pdev->dev,
TSI108_RXRING_LEN * sizeof(rx_desc),
data->rxring, data->rxdma);
- dma_free_coherent(0,
+ dma_free_coherent(&data->pdev->dev,
TSI108_TXRING_LEN * sizeof(tx_desc),
data->txring, data->txdma);
@@ -1576,6 +1579,7 @@ tsi108_init_one(struct platform_device *pdev)
printk("tsi108_eth%d: probe...\n", pdev->id);
data = netdev_priv(dev);
data->dev = dev;
+ data->pdev = pdev;
pr_debug("tsi108_eth%d:regs:phyresgs:phy:irq_num=0x%x:0x%x:0x%x:0x%x\n",
pdev->id, einfo->regs, einfo->phyregs,
diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c
index de73c1ff0939..75c25306d234 100644
--- a/drivers/net/netdevsim/bpf.c
+++ b/drivers/net/netdevsim/bpf.c
@@ -480,8 +480,7 @@ static int
nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)
{
struct nsim_bpf_bound_map *nmap;
- unsigned int i;
- int err;
+ int i, err;
if (WARN_ON(offmap->map.map_type != BPF_MAP_TYPE_ARRAY &&
offmap->map.map_type != BPF_MAP_TYPE_HASH))
@@ -518,7 +517,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap)
return 0;
err_free:
- while (--i) {
+ while (--i >= 0) {
kfree(nmap->entry[i].key);
kfree(nmap->entry[i].value);
}
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 88272b3ac2e2..24b5511222c8 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -56,7 +56,8 @@ static int mdiobus_register_gpiod(struct mdio_device *mdiodev)
gpiod = fwnode_get_named_gpiod(&mdiodev->dev.of_node->fwnode,
"reset-gpios", 0, GPIOD_OUT_LOW,
"PHY reset");
- if (PTR_ERR(gpiod) == -ENOENT)
+ if (PTR_ERR(gpiod) == -ENOENT ||
+ PTR_ERR(gpiod) == -ENOSYS)
gpiod = NULL;
else if (IS_ERR(gpiod))
return PTR_ERR(gpiod);
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index c586bcdb5190..2ef544f10ec8 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -753,6 +753,7 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size,
return NULL;
arena->nd_btt = btt->nd_btt;
arena->sector_size = btt->sector_size;
+ mutex_init(&arena->err_lock);
if (!size)
return arena;
@@ -891,7 +892,6 @@ static int discover_arenas(struct btt *btt)
goto out;
}
- mutex_init(&arena->err_lock);
ret = btt_freelist_init(arena);
if (ret)
goto out;
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index 0a5e6cd758fe..78eabc3a1ab1 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -1142,9 +1142,6 @@ int __init nvdimm_bus_init(void)
{
int rc;
- BUILD_BUG_ON(sizeof(struct nd_smart_payload) != 128);
- BUILD_BUG_ON(sizeof(struct nd_smart_threshold_payload) != 8);
-
rc = bus_register(&nvdimm_bus_type);
if (rc)
return rc;
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index bb3ba8cf24d4..658ada497be0 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -2408,7 +2408,7 @@ static struct device **scan_labels(struct nd_region *nd_region)
static struct device **create_namespaces(struct nd_region *nd_region)
{
- struct nd_mapping *nd_mapping = &nd_region->mapping[0];
+ struct nd_mapping *nd_mapping;
struct device **devs;
int i;
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index e958f3724c41..8d6375ee0fda 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -368,15 +368,14 @@ unsigned int pmem_sector_size(struct nd_namespace_common *ndns);
void nvdimm_badblocks_populate(struct nd_region *nd_region,
struct badblocks *bb, const struct resource *res);
#if IS_ENABLED(CONFIG_ND_CLAIM)
-struct vmem_altmap *nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
- struct resource *res, struct vmem_altmap *altmap);
+int nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap);
int devm_nsio_enable(struct device *dev, struct nd_namespace_io *nsio);
void devm_nsio_disable(struct device *dev, struct nd_namespace_io *nsio);
#else
-static inline struct vmem_altmap *nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
- struct resource *res, struct vmem_altmap *altmap)
+static inline int nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
+ struct dev_pagemap *pgmap)
{
- return ERR_PTR(-ENXIO);
+ return -ENXIO;
}
static inline int devm_nsio_enable(struct device *dev,
struct nd_namespace_io *nsio)
diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
index 2adada1a5855..f5c4e8c6e29d 100644
--- a/drivers/nvdimm/pfn_devs.c
+++ b/drivers/nvdimm/pfn_devs.c
@@ -542,9 +542,10 @@ static unsigned long init_altmap_reserve(resource_size_t base)
return reserve;
}
-static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
- struct resource *res, struct vmem_altmap *altmap)
+static int __nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap)
{
+ struct resource *res = &pgmap->res;
+ struct vmem_altmap *altmap = &pgmap->altmap;
struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
u64 offset = le64_to_cpu(pfn_sb->dataoff);
u32 start_pad = __le32_to_cpu(pfn_sb->start_pad);
@@ -561,11 +562,13 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
res->start += start_pad;
res->end -= end_trunc;
+ pgmap->type = MEMORY_DEVICE_HOST;
+
if (nd_pfn->mode == PFN_MODE_RAM) {
if (offset < SZ_8K)
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
nd_pfn->npfns = le64_to_cpu(pfn_sb->npfns);
- altmap = NULL;
+ pgmap->altmap_valid = false;
} else if (nd_pfn->mode == PFN_MODE_PMEM) {
nd_pfn->npfns = PFN_SECTION_ALIGN_UP((resource_size(res)
- offset) / PAGE_SIZE);
@@ -577,10 +580,11 @@ static struct vmem_altmap *__nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
memcpy(altmap, &__altmap, sizeof(*altmap));
altmap->free = PHYS_PFN(offset - SZ_8K);
altmap->alloc = 0;
+ pgmap->altmap_valid = true;
} else
- return ERR_PTR(-ENXIO);
+ return -ENXIO;
- return altmap;
+ return 0;
}
static u64 phys_pmem_align_down(struct nd_pfn *nd_pfn, u64 phys)
@@ -708,19 +712,18 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
* Determine the effective resource range and vmem_altmap from an nd_pfn
* instance.
*/
-struct vmem_altmap *nvdimm_setup_pfn(struct nd_pfn *nd_pfn,
- struct resource *res, struct vmem_altmap *altmap)
+int nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap)
{
int rc;
if (!nd_pfn->uuid || !nd_pfn->ndns)
- return ERR_PTR(-ENODEV);
+ return -ENODEV;
rc = nd_pfn_init(nd_pfn);
if (rc)
- return ERR_PTR(rc);
+ return rc;
- /* we need a valid pfn_sb before we can init a vmem_altmap */
- return __nvdimm_setup_pfn(nd_pfn, res, altmap);
+ /* we need a valid pfn_sb before we can init a dev_pagemap */
+ return __nvdimm_setup_pfn(nd_pfn, pgmap);
}
EXPORT_SYMBOL_GPL(nvdimm_setup_pfn);
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 7fbc5c5dc8e1..10041ac4032c 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -35,6 +35,7 @@
#include "pmem.h"
#include "pfn.h"
#include "nd.h"
+#include "nd-core.h"
static struct device *to_dev(struct pmem_device *pmem)
{
@@ -298,34 +299,34 @@ static int pmem_attach_disk(struct device *dev,
{
struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev);
struct nd_region *nd_region = to_nd_region(dev->parent);
- struct vmem_altmap __altmap, *altmap = NULL;
int nid = dev_to_node(dev), fua, wbc;
struct resource *res = &nsio->res;
+ struct resource bb_res;
struct nd_pfn *nd_pfn = NULL;
struct dax_device *dax_dev;
struct nd_pfn_sb *pfn_sb;
struct pmem_device *pmem;
- struct resource pfn_res;
struct request_queue *q;
struct device *gendev;
struct gendisk *disk;
void *addr;
+ int rc;
+
+ pmem = devm_kzalloc(dev, sizeof(*pmem), GFP_KERNEL);
+ if (!pmem)
+ return -ENOMEM;
/* while nsio_rw_bytes is active, parse a pfn info block if present */
if (is_nd_pfn(dev)) {
nd_pfn = to_nd_pfn(dev);
- altmap = nvdimm_setup_pfn(nd_pfn, &pfn_res, &__altmap);
- if (IS_ERR(altmap))
- return PTR_ERR(altmap);
+ rc = nvdimm_setup_pfn(nd_pfn, &pmem->pgmap);
+ if (rc)
+ return rc;
}
/* we're attaching a block device, disable raw namespace access */
devm_nsio_disable(dev, nsio);
- pmem = devm_kzalloc(dev, sizeof(*pmem), GFP_KERNEL);
- if (!pmem)
- return -ENOMEM;
-
dev_set_drvdata(dev, pmem);
pmem->phys_addr = res->start;
pmem->size = resource_size(res);
@@ -334,7 +335,8 @@ static int pmem_attach_disk(struct device *dev,
dev_warn(dev, "unable to guarantee persistence of writes\n");
fua = 0;
}
- wbc = nvdimm_has_cache(nd_region);
+ wbc = nvdimm_has_cache(nd_region) &&
+ !test_bit(ND_REGION_PERSIST_CACHE, &nd_region->flags);
if (!devm_request_mem_region(dev, res->start, resource_size(res),
dev_name(&ndns->dev))) {
@@ -350,19 +352,22 @@ static int pmem_attach_disk(struct device *dev,
return -ENOMEM;
pmem->pfn_flags = PFN_DEV;
+ pmem->pgmap.ref = &q->q_usage_counter;
if (is_nd_pfn(dev)) {
- addr = devm_memremap_pages(dev, &pfn_res, &q->q_usage_counter,
- altmap);
+ addr = devm_memremap_pages(dev, &pmem->pgmap);
pfn_sb = nd_pfn->pfn_sb;
pmem->data_offset = le64_to_cpu(pfn_sb->dataoff);
- pmem->pfn_pad = resource_size(res) - resource_size(&pfn_res);
+ pmem->pfn_pad = resource_size(res) -
+ resource_size(&pmem->pgmap.res);
pmem->pfn_flags |= PFN_MAP;
- res = &pfn_res; /* for badblocks populate */
- res->start += pmem->data_offset;
+ memcpy(&bb_res, &pmem->pgmap.res, sizeof(bb_res));
+ bb_res.start += pmem->data_offset;
} else if (pmem_should_map_pages(dev)) {
- addr = devm_memremap_pages(dev, &nsio->res,
- &q->q_usage_counter, NULL);
+ memcpy(&pmem->pgmap.res, &nsio->res, sizeof(pmem->pgmap.res));
+ pmem->pgmap.altmap_valid = false;
+ addr = devm_memremap_pages(dev, &pmem->pgmap);
pmem->pfn_flags |= PFN_MAP;
+ memcpy(&bb_res, &pmem->pgmap.res, sizeof(bb_res));
} else
addr = devm_memremap(dev, pmem->phys_addr,
pmem->size, ARCH_MEMREMAP_PMEM);
@@ -401,7 +406,7 @@ static int pmem_attach_disk(struct device *dev,
/ 512);
if (devm_init_badblocks(dev, &pmem->bb))
return -ENOMEM;
- nvdimm_badblocks_populate(nd_region, &pmem->bb, res);
+ nvdimm_badblocks_populate(nd_region, &pmem->bb, &bb_res);
disk->bb = &pmem->bb;
dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops);
diff --git a/drivers/nvdimm/pmem.h b/drivers/nvdimm/pmem.h
index 6a3cd2a10db6..a64ebc78b5df 100644
--- a/drivers/nvdimm/pmem.h
+++ b/drivers/nvdimm/pmem.h
@@ -22,6 +22,7 @@ struct pmem_device {
struct badblocks bb;
struct dax_device *dax_dev;
struct gendisk *disk;
+ struct dev_pagemap pgmap;
};
long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff,
diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
index abaf38c61220..e6d01911e092 100644
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -528,6 +528,18 @@ static ssize_t resource_show(struct device *dev,
}
static DEVICE_ATTR_RO(resource);
+static ssize_t persistence_domain_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct nd_region *nd_region = to_nd_region(dev);
+ unsigned long flags = nd_region->flags;
+
+ return sprintf(buf, "%s%s\n",
+ flags & BIT(ND_REGION_PERSIST_CACHE) ? "cpu_cache " : "",
+ flags & BIT(ND_REGION_PERSIST_MEMCTRL) ? "memory_controller " : "");
+}
+static DEVICE_ATTR_RO(persistence_domain);
+
static struct attribute *nd_region_attributes[] = {
&dev_attr_size.attr,
&dev_attr_nstype.attr,
@@ -543,6 +555,7 @@ static struct attribute *nd_region_attributes[] = {
&dev_attr_init_namespaces.attr,
&dev_attr_badblocks.attr,
&dev_attr_resource.attr,
+ &dev_attr_persistence_domain.attr,
NULL,
};
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 06898039d11e..783e0870bd22 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -64,10 +64,6 @@ config OF_DYNAMIC
config OF_ADDRESS
def_bool y
depends on !SPARC && (HAS_IOMEM || UML)
- select OF_ADDRESS_PCI if PCI
-
-config OF_ADDRESS_PCI
- bool
config OF_IRQ
def_bool y
@@ -84,18 +80,6 @@ config OF_MDIO
help
OpenFirmware MDIO bus (Ethernet PHY) accessors
-config OF_PCI
- def_tristate PCI
- depends on PCI
- help
- OpenFirmware PCI bus accessors
-
-config OF_PCI_IRQ
- def_tristate PCI
- depends on OF_PCI && OF_IRQ
- help
- OpenFirmware PCI IRQ routing helpers
-
config OF_RESERVED_MEM
depends on OF_EARLY_FLATTREE
bool
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 63a4be62ce19..663a4af0cccd 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,8 +10,6 @@ obj-$(CONFIG_OF_IRQ) += irq.o
obj-$(CONFIG_OF_NET) += of_net.o
obj-$(CONFIG_OF_UNITTEST) += unittest.o
obj-$(CONFIG_OF_MDIO) += of_mdio.o
-obj-$(CONFIG_OF_PCI) += of_pci.o
-obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
obj-$(CONFIG_OF_RESOLVE) += resolver.o
obj-$(CONFIG_OF_OVERLAY) += overlay.o
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 6391604a6f8f..ce4d3d8b85de 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -96,7 +96,7 @@ static unsigned int of_bus_default_get_flags(const __be32 *addr)
return IORESOURCE_MEM;
}
-#ifdef CONFIG_OF_ADDRESS_PCI
+#ifdef CONFIG_PCI
/*
* PCI bus specific translator
*/
@@ -171,9 +171,7 @@ static int of_bus_pci_translate(__be32 *addr, u64 offset, int na)
{
return of_bus_default_translate(addr + 1, offset, na - 1);
}
-#endif /* CONFIG_OF_ADDRESS_PCI */
-#ifdef CONFIG_PCI
const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
unsigned int *flags)
{
@@ -361,6 +359,7 @@ invalid_range:
res->end = (resource_size_t)OF_BAD_ADDR;
return err;
}
+EXPORT_SYMBOL(of_pci_range_to_resource);
#endif /* CONFIG_PCI */
/*
@@ -426,7 +425,7 @@ static unsigned int of_bus_isa_get_flags(const __be32 *addr)
*/
static struct of_bus of_busses[] = {
-#ifdef CONFIG_OF_ADDRESS_PCI
+#ifdef CONFIG_PCI
/* PCI */
{
.name = "pci",
@@ -437,7 +436,7 @@ static struct of_bus of_busses[] = {
.translate = of_bus_pci_translate,
.get_flags = of_bus_pci_get_flags,
},
-#endif /* CONFIG_OF_ADDRESS_PCI */
+#endif /* CONFIG_PCI */
/* ISA */
{
.name = "isa",
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c
deleted file mode 100644
index a7b1cb6c2f65..000000000000
--- a/drivers/of/of_pci.c
+++ /dev/null
@@ -1,384 +0,0 @@
-#define pr_fmt(fmt) "OF: PCI: " fmt
-
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_device.h>
-#include <linux/of_pci.h>
-#include <linux/slab.h>
-
-static inline int __of_pci_pci_compare(struct device_node *node,
- unsigned int data)
-{
- int devfn;
-
- devfn = of_pci_get_devfn(node);
- if (devfn < 0)
- return 0;
-
- return devfn == data;
-}
-
-struct device_node *of_pci_find_child_device(struct device_node *parent,
- unsigned int devfn)
-{
- struct device_node *node, *node2;
-
- for_each_child_of_node(parent, node) {
- if (__of_pci_pci_compare(node, devfn))
- return node;
- /*
- * Some OFs create a parent node "multifunc-device" as
- * a fake root for all functions of a multi-function
- * device we go down them as well.
- */
- if (!strcmp(node->name, "multifunc-device")) {
- for_each_child_of_node(node, node2) {
- if (__of_pci_pci_compare(node2, devfn)) {
- of_node_put(node);
- return node2;
- }
- }
- }
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(of_pci_find_child_device);
-
-/**
- * of_pci_get_devfn() - Get device and function numbers for a device node
- * @np: device node
- *
- * Parses a standard 5-cell PCI resource and returns an 8-bit value that can
- * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device
- * and function numbers respectively. On error a negative error code is
- * returned.
- */
-int of_pci_get_devfn(struct device_node *np)
-{
- u32 reg[5];
- int error;
-
- error = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
- if (error)
- return error;
-
- return (reg[0] >> 8) & 0xff;
-}
-EXPORT_SYMBOL_GPL(of_pci_get_devfn);
-
-/**
- * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
- * @node: device node
- * @res: address to a struct resource to return the bus-range
- *
- * Returns 0 on success or a negative error-code on failure.
- */
-int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
-{
- u32 bus_range[2];
- int error;
-
- error = of_property_read_u32_array(node, "bus-range", bus_range,
- ARRAY_SIZE(bus_range));
- if (error)
- return error;
-
- res->name = node->name;
- res->start = bus_range[0];
- res->end = bus_range[1];
- res->flags = IORESOURCE_BUS;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
-
-/**
- * This function will try to obtain the host bridge domain number by
- * finding a property called "linux,pci-domain" of the given device node.
- *
- * @node: device tree node with the domain information
- *
- * Returns the associated domain number from DT in the range [0-0xffff], or
- * a negative value if the required property is not found.
- */
-int of_get_pci_domain_nr(struct device_node *node)
-{
- u32 domain;
- int error;
-
- error = of_property_read_u32(node, "linux,pci-domain", &domain);
- if (error)
- return error;
-
- return (u16)domain;
-}
-EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
-
-/**
- * This function will try to find the limitation of link speed by finding
- * a property called "max-link-speed" of the given device node.
- *
- * @node: device tree node with the max link speed information
- *
- * Returns the associated max link speed from DT, or a negative value if the
- * required property is not found or is invalid.
- */
-int of_pci_get_max_link_speed(struct device_node *node)
-{
- u32 max_link_speed;
-
- if (of_property_read_u32(node, "max-link-speed", &max_link_speed) ||
- max_link_speed > 4)
- return -EINVAL;
-
- return max_link_speed;
-}
-EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
-
-/**
- * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
- * is present and valid
- */
-void of_pci_check_probe_only(void)
-{
- u32 val;
- int ret;
-
- ret = of_property_read_u32(of_chosen, "linux,pci-probe-only", &val);
- if (ret) {
- if (ret == -ENODATA || ret == -EOVERFLOW)
- pr_warn("linux,pci-probe-only without valid value, ignoring\n");
- return;
- }
-
- if (val)
- pci_add_flags(PCI_PROBE_ONLY);
- else
- pci_clear_flags(PCI_PROBE_ONLY);
-
- pr_info("PROBE_ONLY %sabled\n", val ? "en" : "dis");
-}
-EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
-
-#if defined(CONFIG_OF_ADDRESS)
-/**
- * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
- * @dev: device node of the host bridge having the range property
- * @busno: bus number associated with the bridge root bus
- * @bus_max: maximum number of buses for this bridge
- * @resources: list where the range of resources will be added after DT parsing
- * @io_base: pointer to a variable that will contain on return the physical
- * address for the start of the I/O range. Can be NULL if the caller doesn't
- * expect IO ranges to be present in the device tree.
- *
- * It is the caller's job to free the @resources list.
- *
- * This function will parse the "ranges" property of a PCI host bridge device
- * node and setup the resource mapping based on its content. It is expected
- * that the property conforms with the Power ePAPR document.
- *
- * It returns zero if the range parsing has been successful or a standard error
- * value if it failed.
- */
-int of_pci_get_host_bridge_resources(struct device_node *dev,
- unsigned char busno, unsigned char bus_max,
- struct list_head *resources, resource_size_t *io_base)
-{
- struct resource_entry *window;
- struct resource *res;
- struct resource *bus_range;
- struct of_pci_range range;
- struct of_pci_range_parser parser;
- char range_type[4];
- int err;
-
- if (io_base)
- *io_base = (resource_size_t)OF_BAD_ADDR;
-
- bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
- if (!bus_range)
- return -ENOMEM;
-
- pr_info("host bridge %pOF ranges:\n", dev);
-
- err = of_pci_parse_bus_range(dev, bus_range);
- if (err) {
- bus_range->start = busno;
- bus_range->end = bus_max;
- bus_range->flags = IORESOURCE_BUS;
- pr_info(" No bus range found for %pOF, using %pR\n",
- dev, bus_range);
- } else {
- if (bus_range->end > bus_range->start + bus_max)
- bus_range->end = bus_range->start + bus_max;
- }
- pci_add_resource(resources, bus_range);
-
- /* Check for ranges property */
- err = of_pci_range_parser_init(&parser, dev);
- if (err)
- goto parse_failed;
-
- pr_debug("Parsing ranges property...\n");
- for_each_of_pci_range(&parser, &range) {
- /* Read next ranges element */
- if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
- snprintf(range_type, 4, " IO");
- else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
- snprintf(range_type, 4, "MEM");
- else
- snprintf(range_type, 4, "err");
- pr_info(" %s %#010llx..%#010llx -> %#010llx\n", range_type,
- range.cpu_addr, range.cpu_addr + range.size - 1,
- range.pci_addr);
-
- /*
- * If we failed translation or got a zero-sized region
- * then skip this range
- */
- if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
- continue;
-
- res = kzalloc(sizeof(struct resource), GFP_KERNEL);
- if (!res) {
- err = -ENOMEM;
- goto parse_failed;
- }
-
- err = of_pci_range_to_resource(&range, dev, res);
- if (err) {
- kfree(res);
- continue;
- }
-
- if (resource_type(res) == IORESOURCE_IO) {
- if (!io_base) {
- pr_err("I/O range found for %pOF. Please provide an io_base pointer to save CPU base address\n",
- dev);
- err = -EINVAL;
- goto conversion_failed;
- }
- if (*io_base != (resource_size_t)OF_BAD_ADDR)
- pr_warn("More than one I/O resource converted for %pOF. CPU base address for old range lost!\n",
- dev);
- *io_base = range.cpu_addr;
- }
-
- pci_add_resource_offset(resources, res, res->start - range.pci_addr);
- }
-
- return 0;
-
-conversion_failed:
- kfree(res);
-parse_failed:
- resource_list_for_each_entry(window, resources)
- kfree(window->res);
- pci_free_resource_list(resources);
- return err;
-}
-EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
-#endif /* CONFIG_OF_ADDRESS */
-
-/**
- * of_pci_map_rid - Translate a requester ID through a downstream mapping.
- * @np: root complex device node.
- * @rid: PCI requester ID to map.
- * @map_name: property name of the map to use.
- * @map_mask_name: optional property name of the mask to use.
- * @target: optional pointer to a target device node.
- * @id_out: optional pointer to receive the translated ID.
- *
- * Given a PCI requester ID, look up the appropriate implementation-defined
- * platform ID and/or the target device which receives transactions on that
- * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
- * @id_out may be NULL if only the other is required. If @target points to
- * a non-NULL device node pointer, only entries targeting that node will be
- * matched; if it points to a NULL value, it will receive the device node of
- * the first matching target phandle, with a reference held.
- *
- * Return: 0 on success or a standard error code on failure.
- */
-int of_pci_map_rid(struct device_node *np, u32 rid,
- const char *map_name, const char *map_mask_name,
- struct device_node **target, u32 *id_out)
-{
- u32 map_mask, masked_rid;
- int map_len;
- const __be32 *map = NULL;
-
- if (!np || !map_name || (!target && !id_out))
- return -EINVAL;
-
- map = of_get_property(np, map_name, &map_len);
- if (!map) {
- if (target)
- return -ENODEV;
- /* Otherwise, no map implies no translation */
- *id_out = rid;
- return 0;
- }
-
- if (!map_len || map_len % (4 * sizeof(*map))) {
- pr_err("%pOF: Error: Bad %s length: %d\n", np,
- map_name, map_len);
- return -EINVAL;
- }
-
- /* The default is to select all bits. */
- map_mask = 0xffffffff;
-
- /*
- * Can be overridden by "{iommu,msi}-map-mask" property.
- * If of_property_read_u32() fails, the default is used.
- */
- if (map_mask_name)
- of_property_read_u32(np, map_mask_name, &map_mask);
-
- masked_rid = map_mask & rid;
- for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
- struct device_node *phandle_node;
- u32 rid_base = be32_to_cpup(map + 0);
- u32 phandle = be32_to_cpup(map + 1);
- u32 out_base = be32_to_cpup(map + 2);
- u32 rid_len = be32_to_cpup(map + 3);
-
- if (rid_base & ~map_mask) {
- pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n",
- np, map_name, map_name,
- map_mask, rid_base);
- return -EFAULT;
- }
-
- if (masked_rid < rid_base || masked_rid >= rid_base + rid_len)
- continue;
-
- phandle_node = of_find_node_by_phandle(phandle);
- if (!phandle_node)
- return -ENODEV;
-
- if (target) {
- if (*target)
- of_node_put(phandle_node);
- else
- *target = phandle_node;
-
- if (*target != phandle_node)
- continue;
- }
-
- if (id_out)
- *id_out = masked_rid - rid_base + out_base;
-
- pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n",
- np, map_name, map_mask, rid_base, out_base,
- rid_len, rid, masked_rid - rid_base + out_base);
- return 0;
- }
-
- pr_err("%pOF: Invalid %s translation - no match for rid 0x%x on %pOF\n",
- np, map_name, rid, target && *target ? *target : NULL);
- return -EFAULT;
-}
diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c
deleted file mode 100644
index 3a05568f65df..000000000000
--- a/drivers/of/of_pci_irq.c
+++ /dev/null
@@ -1,131 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/of_pci.h>
-#include <linux/of_irq.h>
-#include <linux/export.h>
-
-/**
- * of_irq_parse_pci - Resolve the interrupt for a PCI device
- * @pdev: the device whose interrupt is to be resolved
- * @out_irq: structure of_irq filled by this function
- *
- * This function resolves the PCI interrupt for a given PCI device. If a
- * device-node exists for a given pci_dev, it will use normal OF tree
- * walking. If not, it will implement standard swizzling and walk up the
- * PCI tree until an device-node is found, at which point it will finish
- * resolving using the OF tree walking.
- */
-int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
-{
- struct device_node *dn, *ppnode;
- struct pci_dev *ppdev;
- __be32 laddr[3];
- u8 pin;
- int rc;
-
- /* Check if we have a device node, if yes, fallback to standard
- * device tree parsing
- */
- dn = pci_device_to_OF_node(pdev);
- if (dn) {
- rc = of_irq_parse_one(dn, 0, out_irq);
- if (!rc)
- return rc;
- }
-
- /* Ok, we don't, time to have fun. Let's start by building up an
- * interrupt spec. we assume #interrupt-cells is 1, which is standard
- * for PCI. If you do different, then don't use that routine.
- */
- rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
- if (rc != 0)
- goto err;
- /* No pin, exit with no error message. */
- if (pin == 0)
- return -ENODEV;
-
- /* Now we walk up the PCI tree */
- for (;;) {
- /* Get the pci_dev of our parent */
- ppdev = pdev->bus->self;
-
- /* Ouch, it's a host bridge... */
- if (ppdev == NULL) {
- ppnode = pci_bus_to_OF_node(pdev->bus);
-
- /* No node for host bridge ? give up */
- if (ppnode == NULL) {
- rc = -EINVAL;
- goto err;
- }
- } else {
- /* We found a P2P bridge, check if it has a node */
- ppnode = pci_device_to_OF_node(ppdev);
- }
-
- /* Ok, we have found a parent with a device-node, hand over to
- * the OF parsing code.
- * We build a unit address from the linux device to be used for
- * resolution. Note that we use the linux bus number which may
- * not match your firmware bus numbering.
- * Fortunately, in most cases, interrupt-map-mask doesn't
- * include the bus number as part of the matching.
- * You should still be careful about that though if you intend
- * to rely on this function (you ship a firmware that doesn't
- * create device nodes for all PCI devices).
- */
- if (ppnode)
- break;
-
- /* We can only get here if we hit a P2P bridge with no node,
- * let's do standard swizzling and try again
- */
- pin = pci_swizzle_interrupt_pin(pdev, pin);
- pdev = ppdev;
- }
-
- out_irq->np = ppnode;
- out_irq->args_count = 1;
- out_irq->args[0] = pin;
- laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
- laddr[1] = laddr[2] = cpu_to_be32(0);
- rc = of_irq_parse_raw(laddr, out_irq);
- if (rc)
- goto err;
- return 0;
-err:
- if (rc == -ENOENT) {
- dev_warn(&pdev->dev,
- "%s: no interrupt-map found, INTx interrupts not available\n",
- __func__);
- pr_warn_once("%s: possibly some PCI slots don't have level triggered interrupts capability\n",
- __func__);
- } else {
- dev_err(&pdev->dev, "%s: failed with rc=%d\n", __func__, rc);
- }
- return rc;
-}
-EXPORT_SYMBOL_GPL(of_irq_parse_pci);
-
-/**
- * of_irq_parse_and_map_pci() - Decode a PCI irq from the device tree and map to a virq
- * @dev: The pci device needing an irq
- * @slot: PCI slot number; passed when used as map_irq callback. Unused
- * @pin: PCI irq pin number; passed when used as map_irq callback. Unused
- *
- * @slot and @pin are unused, but included in the function so that this
- * function can be used directly as the map_irq callback to
- * pci_assign_irq() and struct pci_host_bridge.map_irq pointer
- */
-int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- struct of_phandle_args oirq;
- int ret;
-
- ret = of_irq_parse_pci(dev, &oirq);
- if (ret)
- return 0; /* Proper return code 0 == NO_IRQ */
-
- return irq_create_of_mapping(&oirq);
-}
-EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
-
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index bda151788f3f..34b56a8f8480 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# PCI configuration
#
@@ -125,6 +126,7 @@ config PCI_PASID
config PCI_LABEL
def_bool y if (DMI || ACPI)
+ depends on PCI
select NLS
config PCI_HYPERV
@@ -135,6 +137,7 @@ config PCI_HYPERV
PCI devices from a PCI backend to support PCI driver domains.
source "drivers/pci/hotplug/Kconfig"
+source "drivers/pci/cadence/Kconfig"
source "drivers/pci/dwc/Kconfig"
source "drivers/pci/host/Kconfig"
source "drivers/pci/endpoint/Kconfig"
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index c7819b973df7..941970936840 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -3,12 +3,15 @@
# Makefile for the PCI bus specific drivers.
#
-obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \
+obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o remove.o pci.o \
pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \
irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o
+ifdef CONFIG_PCI
obj-$(CONFIG_PROC_FS) += proc.o
obj-$(CONFIG_SYSFS) += slot.o
+obj-$(CONFIG_OF) += of.o
+endif
obj-$(CONFIG_PCI_QUIRKS) += quirks.o
@@ -44,10 +47,15 @@ obj-$(CONFIG_PCI_ECAM) += ecam.o
obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o
-obj-$(CONFIG_OF) += of.o
-
ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
# PCI host controller drivers
obj-y += host/
obj-y += switch/
+
+obj-$(CONFIG_PCI_ENDPOINT) += endpoint/
+
+# Endpoint library must be initialized before its users
+obj-$(CONFIG_PCIE_CADENCE) += cadence/
+# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW
+obj-y += dwc/
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 913d6722ece9..5e9a9822d9d4 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/module.h>
@@ -333,8 +334,7 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size)
(tag == PCI_VPD_LTIN_RW_DATA)) {
if (pci_read_vpd(dev, off+1, 2,
&header[1]) != 2) {
- dev_warn(&dev->dev,
- "invalid large VPD tag %02x size at offset %zu",
+ pci_warn(dev, "invalid large VPD tag %02x size at offset %zu",
tag, off + 1);
return 0;
}
@@ -354,8 +354,7 @@ static size_t pci_vpd_size(struct pci_dev *dev, size_t old_size)
if ((tag != PCI_VPD_LTIN_ID_STRING) &&
(tag != PCI_VPD_LTIN_RO_DATA) &&
(tag != PCI_VPD_LTIN_RW_DATA)) {
- dev_warn(&dev->dev,
- "invalid %s VPD tag %02x at offset %zu",
+ pci_warn(dev, "invalid %s VPD tag %02x at offset %zu",
(header[0] & PCI_VPD_LRDT) ? "large" : "short",
tag, off);
return 0;
@@ -402,7 +401,7 @@ static int pci_vpd_wait(struct pci_dev *dev)
max_sleep *= 2;
}
- dev_warn(&dev->dev, "VPD access failed. This is likely a firmware bug on this device. Contact the card vendor for a firmware update\n");
+ pci_warn(dev, "VPD access failed. This is likely a firmware bug on this device. Contact the card vendor for a firmware update\n");
return -ETIMEDOUT;
}
diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index ad8ddbbbf245..6ad80a1fd5a7 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/ats.c
*
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index bc56cf19afd3..737d1c52f002 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/bus.c
*
@@ -289,7 +290,7 @@ bool pci_bus_clip_resource(struct pci_dev *dev, int idx)
res->end = end;
res->flags &= ~IORESOURCE_UNSET;
orig_res.flags &= ~IORESOURCE_UNSET;
- dev_printk(KERN_DEBUG, &dev->dev, "%pR clipped to %pR\n",
+ pci_printk(KERN_DEBUG, dev, "%pR clipped to %pR\n",
&orig_res, res);
return true;
@@ -325,7 +326,7 @@ void pci_bus_add_device(struct pci_dev *dev)
dev->match_driver = true;
retval = device_attach(&dev->dev);
if (retval < 0 && retval != -EPROBE_DEFER) {
- dev_warn(&dev->dev, "device attach failed (%d)\n", retval);
+ pci_warn(dev, "device attach failed (%d)\n", retval);
pci_proc_detach_device(dev);
pci_remove_sysfs_dev_files(dev);
return;
diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig
new file mode 100644
index 000000000000..e6824cb56c16
--- /dev/null
+++ b/drivers/pci/cadence/Kconfig
@@ -0,0 +1,27 @@
+menu "Cadence PCIe controllers support"
+
+config PCIE_CADENCE
+ bool
+
+config PCIE_CADENCE_HOST
+ bool "Cadence PCIe host controller"
+ depends on OF
+ depends on PCI
+ select IRQ_DOMAIN
+ select PCIE_CADENCE
+ help
+ Say Y here if you want to support the Cadence PCIe controller in host
+ mode. This PCIe controller may be embedded into many different vendors
+ SoCs.
+
+config PCIE_CADENCE_EP
+ bool "Cadence PCIe endpoint controller"
+ depends on OF
+ depends on PCI_ENDPOINT
+ select PCIE_CADENCE
+ help
+ Say Y here if you want to support the Cadence PCIe controller in
+ endpoint mode. This PCIe controller may be embedded into many
+ different vendors SoCs.
+
+endmenu
diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile
new file mode 100644
index 000000000000..719392b97998
--- /dev/null
+++ b/drivers/pci/cadence/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o
+obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o
+obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o
diff --git a/drivers/pci/cadence/pcie-cadence-ep.c b/drivers/pci/cadence/pcie-cadence-ep.c
new file mode 100644
index 000000000000..3c3a97743453
--- /dev/null
+++ b/drivers/pci/cadence/pcie-cadence-ep.c
@@ -0,0 +1,542 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe endpoint controller driver.
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/pci-epc.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/sizes.h>
+
+#include "pcie-cadence.h"
+
+#define CDNS_PCIE_EP_MIN_APERTURE 128 /* 128 bytes */
+#define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE 0x1
+#define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY 0x3
+
+/**
+ * struct cdns_pcie_ep - private data for this PCIe endpoint controller driver
+ * @pcie: Cadence PCIe controller
+ * @max_regions: maximum number of regions supported by hardware
+ * @ob_region_map: bitmask of mapped outbound regions
+ * @ob_addr: base addresses in the AXI bus where the outbound regions start
+ * @irq_phys_addr: base address on the AXI bus where the MSI/legacy IRQ
+ * dedicated outbound regions is mapped.
+ * @irq_cpu_addr: base address in the CPU space where a write access triggers
+ * the sending of a memory write (MSI) / normal message (legacy
+ * IRQ) TLP through the PCIe bus.
+ * @irq_pci_addr: used to save the current mapping of the MSI/legacy IRQ
+ * dedicated outbound region.
+ * @irq_pci_fn: the latest PCI function that has updated the mapping of
+ * the MSI/legacy IRQ dedicated outbound region.
+ * @irq_pending: bitmask of asserted legacy IRQs.
+ */
+struct cdns_pcie_ep {
+ struct cdns_pcie pcie;
+ u32 max_regions;
+ unsigned long ob_region_map;
+ phys_addr_t *ob_addr;
+ phys_addr_t irq_phys_addr;
+ void __iomem *irq_cpu_addr;
+ u64 irq_pci_addr;
+ u8 irq_pci_fn;
+ u8 irq_pending;
+};
+
+static int cdns_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
+ struct pci_epf_header *hdr)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie *pcie = &ep->pcie;
+
+ cdns_pcie_ep_fn_writew(pcie, fn, PCI_DEVICE_ID, hdr->deviceid);
+ cdns_pcie_ep_fn_writeb(pcie, fn, PCI_REVISION_ID, hdr->revid);
+ cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CLASS_PROG, hdr->progif_code);
+ cdns_pcie_ep_fn_writew(pcie, fn, PCI_CLASS_DEVICE,
+ hdr->subclass_code | hdr->baseclass_code << 8);
+ cdns_pcie_ep_fn_writeb(pcie, fn, PCI_CACHE_LINE_SIZE,
+ hdr->cache_line_size);
+ cdns_pcie_ep_fn_writew(pcie, fn, PCI_SUBSYSTEM_ID, hdr->subsys_id);
+ cdns_pcie_ep_fn_writeb(pcie, fn, PCI_INTERRUPT_PIN, hdr->interrupt_pin);
+
+ /*
+ * Vendor ID can only be modified from function 0, all other functions
+ * use the same vendor ID as function 0.
+ */
+ if (fn == 0) {
+ /* Update the vendor IDs. */
+ u32 id = CDNS_PCIE_LM_ID_VENDOR(hdr->vendorid) |
+ CDNS_PCIE_LM_ID_SUBSYS(hdr->subsys_vendor_id);
+
+ cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, id);
+ }
+
+ return 0;
+}
+
+static int cdns_pcie_ep_set_bar(struct pci_epc *epc, u8 fn, enum pci_barno bar,
+ dma_addr_t bar_phys, size_t size, int flags)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie *pcie = &ep->pcie;
+ u32 addr0, addr1, reg, cfg, b, aperture, ctrl;
+ u64 sz;
+
+ /* BAR size is 2^(aperture + 7) */
+ sz = max_t(size_t, size, CDNS_PCIE_EP_MIN_APERTURE);
+ /*
+ * roundup_pow_of_two() returns an unsigned long, which is not suited
+ * for 64bit values.
+ */
+ sz = 1ULL << fls64(sz - 1);
+ aperture = ilog2(sz) - 7; /* 128B -> 0, 256B -> 1, 512B -> 2, ... */
+
+ if ((flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS;
+ } else {
+ bool is_prefetch = !!(flags & PCI_BASE_ADDRESS_MEM_PREFETCH);
+ bool is_64bits = sz > SZ_2G;
+
+ if (is_64bits && (bar & 1))
+ return -EINVAL;
+
+ if (is_64bits && is_prefetch)
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS;
+ else if (is_prefetch)
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS;
+ else if (is_64bits)
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS;
+ else
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS;
+ }
+
+ addr0 = lower_32_bits(bar_phys);
+ addr1 = upper_32_bits(bar_phys);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar),
+ addr0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar),
+ addr1);
+
+ if (bar < BAR_4) {
+ reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
+ b = bar;
+ } else {
+ reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
+ b = bar - BAR_4;
+ }
+
+ cfg = cdns_pcie_readl(pcie, reg);
+ cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+ CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+ cfg |= (CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, aperture) |
+ CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl));
+ cdns_pcie_writel(pcie, reg, cfg);
+
+ return 0;
+}
+
+static void cdns_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
+ enum pci_barno bar)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie *pcie = &ep->pcie;
+ u32 reg, cfg, b, ctrl;
+
+ if (bar < BAR_4) {
+ reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn);
+ b = bar;
+ } else {
+ reg = CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn);
+ b = bar - BAR_4;
+ }
+
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
+ cfg = cdns_pcie_readl(pcie, reg);
+ cfg &= ~(CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) |
+ CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b));
+ cfg |= CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, ctrl);
+ cdns_pcie_writel(pcie, reg, cfg);
+
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar), 0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar), 0);
+}
+
+static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr,
+ u64 pci_addr, size_t size)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie *pcie = &ep->pcie;
+ u32 r;
+
+ r = find_first_zero_bit(&ep->ob_region_map,
+ sizeof(ep->ob_region_map) * BITS_PER_LONG);
+ if (r >= ep->max_regions - 1) {
+ dev_err(&epc->dev, "no free outbound region\n");
+ return -EINVAL;
+ }
+
+ cdns_pcie_set_outbound_region(pcie, fn, r, false, addr, pci_addr, size);
+
+ set_bit(r, &ep->ob_region_map);
+ ep->ob_addr[r] = addr;
+
+ return 0;
+}
+
+static void cdns_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
+ phys_addr_t addr)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie *pcie = &ep->pcie;
+ u32 r;
+
+ for (r = 0; r < ep->max_regions - 1; r++)
+ if (ep->ob_addr[r] == addr)
+ break;
+
+ if (r == ep->max_regions - 1)
+ return;
+
+ cdns_pcie_reset_outbound_region(pcie, r);
+
+ ep->ob_addr[r] = 0;
+ clear_bit(r, &ep->ob_region_map);
+}
+
+static int cdns_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 mmc)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie *pcie = &ep->pcie;
+ u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+ u16 flags;
+
+ /*
+ * Set the Multiple Message Capable bitfield into the Message Control
+ * register.
+ */
+ flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+ flags = (flags & ~PCI_MSI_FLAGS_QMASK) | (mmc << 1);
+ flags |= PCI_MSI_FLAGS_64BIT;
+ flags &= ~PCI_MSI_FLAGS_MASKBIT;
+ cdns_pcie_ep_fn_writew(pcie, fn, cap + PCI_MSI_FLAGS, flags);
+
+ return 0;
+}
+
+static int cdns_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie *pcie = &ep->pcie;
+ u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+ u16 flags, mmc, mme;
+
+ /* Validate that the MSI feature is actually enabled. */
+ flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+ if (!(flags & PCI_MSI_FLAGS_ENABLE))
+ return -EINVAL;
+
+ /*
+ * Get the Multiple Message Enable bitfield from the Message Control
+ * register.
+ */
+ mmc = (flags & PCI_MSI_FLAGS_QMASK) >> 1;
+ mme = (flags & PCI_MSI_FLAGS_QSIZE) >> 4;
+
+ return mme;
+}
+
+static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
+ u8 intx, bool is_asserted)
+{
+ struct cdns_pcie *pcie = &ep->pcie;
+ u32 r = ep->max_regions - 1;
+ u32 offset;
+ u16 status;
+ u8 msg_code;
+
+ intx &= 3;
+
+ /* Set the outbound region if needed. */
+ if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY ||
+ ep->irq_pci_fn != fn)) {
+ /* Last region was reserved for IRQ writes. */
+ cdns_pcie_set_outbound_region_for_normal_msg(pcie, fn, r,
+ ep->irq_phys_addr);
+ ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY;
+ ep->irq_pci_fn = fn;
+ }
+
+ if (is_asserted) {
+ ep->irq_pending |= BIT(intx);
+ msg_code = MSG_CODE_ASSERT_INTA + intx;
+ } else {
+ ep->irq_pending &= ~BIT(intx);
+ msg_code = MSG_CODE_DEASSERT_INTA + intx;
+ }
+
+ status = cdns_pcie_ep_fn_readw(pcie, fn, PCI_STATUS);
+ if (((status & PCI_STATUS_INTERRUPT) != 0) ^ (ep->irq_pending != 0)) {
+ status ^= PCI_STATUS_INTERRUPT;
+ cdns_pcie_ep_fn_writew(pcie, fn, PCI_STATUS, status);
+ }
+
+ offset = CDNS_PCIE_NORMAL_MSG_ROUTING(MSG_ROUTING_LOCAL) |
+ CDNS_PCIE_NORMAL_MSG_CODE(msg_code) |
+ CDNS_PCIE_MSG_NO_DATA;
+ writel(0, ep->irq_cpu_addr + offset);
+}
+
+static int cdns_pcie_ep_send_legacy_irq(struct cdns_pcie_ep *ep, u8 fn, u8 intx)
+{
+ u16 cmd;
+
+ cmd = cdns_pcie_ep_fn_readw(&ep->pcie, fn, PCI_COMMAND);
+ if (cmd & PCI_COMMAND_INTX_DISABLE)
+ return -EINVAL;
+
+ cdns_pcie_ep_assert_intx(ep, fn, intx, true);
+ /*
+ * The mdelay() value was taken from dra7xx_pcie_raise_legacy_irq()
+ * from drivers/pci/dwc/pci-dra7xx.c
+ */
+ mdelay(1);
+ cdns_pcie_ep_assert_intx(ep, fn, intx, false);
+ return 0;
+}
+
+static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
+ u8 interrupt_num)
+{
+ struct cdns_pcie *pcie = &ep->pcie;
+ u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET;
+ u16 flags, mme, data, data_mask;
+ u8 msi_count;
+ u64 pci_addr, pci_addr_mask = 0xff;
+
+ /* Check whether the MSI feature has been enabled by the PCI host. */
+ flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS);
+ if (!(flags & PCI_MSI_FLAGS_ENABLE))
+ return -EINVAL;
+
+ /* Get the number of enabled MSIs */
+ mme = (flags & PCI_MSI_FLAGS_QSIZE) >> 4;
+ msi_count = 1 << mme;
+ if (!interrupt_num || interrupt_num > msi_count)
+ return -EINVAL;
+
+ /* Compute the data value to be written. */
+ data_mask = msi_count - 1;
+ data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64);
+ data = (data & ~data_mask) | ((interrupt_num - 1) & data_mask);
+
+ /* Get the PCI address where to write the data into. */
+ pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI);
+ pci_addr <<= 32;
+ pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO);
+ pci_addr &= GENMASK_ULL(63, 2);
+
+ /* Set the outbound region if needed. */
+ if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
+ ep->irq_pci_fn != fn)) {
+ /* Last region was reserved for IRQ writes. */
+ cdns_pcie_set_outbound_region(pcie, fn, ep->max_regions - 1,
+ false,
+ ep->irq_phys_addr,
+ pci_addr & ~pci_addr_mask,
+ pci_addr_mask + 1);
+ ep->irq_pci_addr = (pci_addr & ~pci_addr_mask);
+ ep->irq_pci_fn = fn;
+ }
+ writew(data, ep->irq_cpu_addr + (pci_addr & pci_addr_mask));
+
+ return 0;
+}
+
+static int cdns_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
+ enum pci_epc_irq_type type, u8 interrupt_num)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+
+ switch (type) {
+ case PCI_EPC_IRQ_LEGACY:
+ return cdns_pcie_ep_send_legacy_irq(ep, fn, 0);
+
+ case PCI_EPC_IRQ_MSI:
+ return cdns_pcie_ep_send_msi_irq(ep, fn, interrupt_num);
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int cdns_pcie_ep_start(struct pci_epc *epc)
+{
+ struct cdns_pcie_ep *ep = epc_get_drvdata(epc);
+ struct cdns_pcie *pcie = &ep->pcie;
+ struct pci_epf *epf;
+ u32 cfg;
+
+ /*
+ * BIT(0) is hardwired to 1, hence function 0 is always enabled
+ * and can't be disabled anyway.
+ */
+ cfg = BIT(0);
+ list_for_each_entry(epf, &epc->pci_epf, list)
+ cfg |= BIT(epf->func_no);
+ cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, cfg);
+
+ /*
+ * The PCIe links are automatically established by the controller
+ * once for all at powerup: the software can neither start nor stop
+ * those links later at runtime.
+ *
+ * Then we only have to notify the EP core that our links are already
+ * established. However we don't call directly pci_epc_linkup() because
+ * we've already locked the epc->lock.
+ */
+ list_for_each_entry(epf, &epc->pci_epf, list)
+ pci_epf_linkup(epf);
+
+ return 0;
+}
+
+static const struct pci_epc_ops cdns_pcie_epc_ops = {
+ .write_header = cdns_pcie_ep_write_header,
+ .set_bar = cdns_pcie_ep_set_bar,
+ .clear_bar = cdns_pcie_ep_clear_bar,
+ .map_addr = cdns_pcie_ep_map_addr,
+ .unmap_addr = cdns_pcie_ep_unmap_addr,
+ .set_msi = cdns_pcie_ep_set_msi,
+ .get_msi = cdns_pcie_ep_get_msi,
+ .raise_irq = cdns_pcie_ep_raise_irq,
+ .start = cdns_pcie_ep_start,
+};
+
+static const struct of_device_id cdns_pcie_ep_of_match[] = {
+ { .compatible = "cdns,cdns-pcie-ep" },
+
+ { },
+};
+
+static int cdns_pcie_ep_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct cdns_pcie_ep *ep;
+ struct cdns_pcie *pcie;
+ struct pci_epc *epc;
+ struct resource *res;
+ int ret;
+
+ ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
+ if (!ep)
+ return -ENOMEM;
+
+ pcie = &ep->pcie;
+ pcie->is_rc = false;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg");
+ pcie->reg_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(pcie->reg_base)) {
+ dev_err(dev, "missing \"reg\"\n");
+ return PTR_ERR(pcie->reg_base);
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem");
+ if (!res) {
+ dev_err(dev, "missing \"mem\"\n");
+ return -EINVAL;
+ }
+ pcie->mem_res = res;
+
+ ret = of_property_read_u32(np, "cdns,max-outbound-regions",
+ &ep->max_regions);
+ if (ret < 0) {
+ dev_err(dev, "missing \"cdns,max-outbound-regions\"\n");
+ return ret;
+ }
+ ep->ob_addr = devm_kzalloc(dev, ep->max_regions * sizeof(*ep->ob_addr),
+ GFP_KERNEL);
+ if (!ep->ob_addr)
+ return -ENOMEM;
+
+ pm_runtime_enable(dev);
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "pm_runtime_get_sync() failed\n");
+ goto err_get_sync;
+ }
+
+ /* Disable all but function 0 (anyway BIT(0) is hardwired to 1). */
+ cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, BIT(0));
+
+ epc = devm_pci_epc_create(dev, &cdns_pcie_epc_ops);
+ if (IS_ERR(epc)) {
+ dev_err(dev, "failed to create epc device\n");
+ ret = PTR_ERR(epc);
+ goto err_init;
+ }
+
+ epc_set_drvdata(epc, ep);
+
+ if (of_property_read_u8(np, "max-functions", &epc->max_functions) < 0)
+ epc->max_functions = 1;
+
+ ret = pci_epc_mem_init(epc, pcie->mem_res->start,
+ resource_size(pcie->mem_res));
+ if (ret < 0) {
+ dev_err(dev, "failed to initialize the memory space\n");
+ goto err_init;
+ }
+
+ ep->irq_cpu_addr = pci_epc_mem_alloc_addr(epc, &ep->irq_phys_addr,
+ SZ_128K);
+ if (!ep->irq_cpu_addr) {
+ dev_err(dev, "failed to reserve memory space for MSI\n");
+ ret = -ENOMEM;
+ goto free_epc_mem;
+ }
+ ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE;
+
+ return 0;
+
+ free_epc_mem:
+ pci_epc_mem_exit(epc);
+
+ err_init:
+ pm_runtime_put_sync(dev);
+
+ err_get_sync:
+ pm_runtime_disable(dev);
+
+ return ret;
+}
+
+static void cdns_pcie_ep_shutdown(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ ret = pm_runtime_put_sync(dev);
+ if (ret < 0)
+ dev_dbg(dev, "pm_runtime_put_sync failed\n");
+
+ pm_runtime_disable(dev);
+
+ /* The PCIe controller can't be disabled. */
+}
+
+static struct platform_driver cdns_pcie_ep_driver = {
+ .driver = {
+ .name = "cdns-pcie-ep",
+ .of_match_table = cdns_pcie_ep_of_match,
+ },
+ .probe = cdns_pcie_ep_probe,
+ .shutdown = cdns_pcie_ep_shutdown,
+};
+builtin_platform_driver(cdns_pcie_ep_driver);
diff --git a/drivers/pci/cadence/pcie-cadence-host.c b/drivers/pci/cadence/pcie-cadence-host.c
new file mode 100644
index 000000000000..a4ebbd37b553
--- /dev/null
+++ b/drivers/pci/cadence/pcie-cadence-host.c
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe host controller driver.
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "pcie-cadence.h"
+
+/**
+ * struct cdns_pcie_rc - private data for this PCIe Root Complex driver
+ * @pcie: Cadence PCIe controller
+ * @dev: pointer to PCIe device
+ * @cfg_res: start/end offsets in the physical system memory to map PCI
+ * configuration space accesses
+ * @bus_range: first/last buses behind the PCIe host controller
+ * @cfg_base: IO mapped window to access the PCI configuration space of a
+ * single function at a time
+ * @max_regions: maximum number of regions supported by the hardware
+ * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address
+ * translation (nbits sets into the "no BAR match" register)
+ * @vendor_id: PCI vendor ID
+ * @device_id: PCI device ID
+ */
+struct cdns_pcie_rc {
+ struct cdns_pcie pcie;
+ struct device *dev;
+ struct resource *cfg_res;
+ struct resource *bus_range;
+ void __iomem *cfg_base;
+ u32 max_regions;
+ u32 no_bar_nbits;
+ u16 vendor_id;
+ u16 device_id;
+};
+
+static void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where)
+{
+ struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
+ struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge);
+ struct cdns_pcie *pcie = &rc->pcie;
+ unsigned int busn = bus->number;
+ u32 addr0, desc0;
+
+ if (busn == rc->bus_range->start) {
+ /*
+ * Only the root port (devfn == 0) is connected to this bus.
+ * All other PCI devices are behind some bridge hence on another
+ * bus.
+ */
+ if (devfn)
+ return NULL;
+
+ return pcie->reg_base + (where & 0xfff);
+ }
+
+ /* Update Output registers for AXI region 0. */
+ addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(12) |
+ CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) |
+ CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(busn);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(0), addr0);
+
+ /* Configuration Type 0 or Type 1 access. */
+ desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
+ CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
+ /*
+ * The bus number was already set once for all in desc1 by
+ * cdns_pcie_host_init_address_translation().
+ */
+ if (busn == rc->bus_range->start + 1)
+ desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0;
+ else
+ desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1;
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(0), desc0);
+
+ return rc->cfg_base + (where & 0xfff);
+}
+
+static struct pci_ops cdns_pcie_host_ops = {
+ .map_bus = cdns_pci_map_bus,
+ .read = pci_generic_config_read,
+ .write = pci_generic_config_write,
+};
+
+static const struct of_device_id cdns_pcie_host_of_match[] = {
+ { .compatible = "cdns,cdns-pcie-host" },
+
+ { },
+};
+
+static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc)
+{
+ struct cdns_pcie *pcie = &rc->pcie;
+ u32 value, ctrl;
+
+ /*
+ * Set the root complex BAR configuration register:
+ * - disable both BAR0 and BAR1.
+ * - enable Prefetchable Memory Base and Limit registers in type 1
+ * config space (64 bits).
+ * - enable IO Base and Limit registers in type 1 config
+ * space (32 bits).
+ */
+ ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED;
+ value = CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(ctrl) |
+ CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(ctrl) |
+ CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE |
+ CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS |
+ CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE |
+ CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS;
+ cdns_pcie_writel(pcie, CDNS_PCIE_LM_RC_BAR_CFG, value);
+
+ /* Set root port configuration space */
+ if (rc->vendor_id != 0xffff)
+ cdns_pcie_rp_writew(pcie, PCI_VENDOR_ID, rc->vendor_id);
+ if (rc->device_id != 0xffff)
+ cdns_pcie_rp_writew(pcie, PCI_DEVICE_ID, rc->device_id);
+
+ cdns_pcie_rp_writeb(pcie, PCI_CLASS_REVISION, 0);
+ cdns_pcie_rp_writeb(pcie, PCI_CLASS_PROG, 0);
+ cdns_pcie_rp_writew(pcie, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_PCI);
+
+ return 0;
+}
+
+static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
+{
+ struct cdns_pcie *pcie = &rc->pcie;
+ struct resource *cfg_res = rc->cfg_res;
+ struct resource *mem_res = pcie->mem_res;
+ struct resource *bus_range = rc->bus_range;
+ struct device *dev = rc->dev;
+ struct device_node *np = dev->of_node;
+ struct of_pci_range_parser parser;
+ struct of_pci_range range;
+ u32 addr0, addr1, desc1;
+ u64 cpu_addr;
+ int r, err;
+
+ /*
+ * Reserve region 0 for PCI configure space accesses:
+ * OB_REGION_PCI_ADDR0 and OB_REGION_DESC0 are updated dynamically by
+ * cdns_pci_map_bus(), other region registers are set here once for all.
+ */
+ addr1 = 0; /* Should be programmed to zero. */
+ desc1 = CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus_range->start);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1);
+
+ cpu_addr = cfg_res->start - mem_res->start;
+ addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(12) |
+ (lower_32_bits(cpu_addr) & GENMASK(31, 8));
+ addr1 = upper_32_bits(cpu_addr);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(0), addr0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(0), addr1);
+
+ err = of_pci_range_parser_init(&parser, np);
+ if (err)
+ return err;
+
+ r = 1;
+ for_each_of_pci_range(&parser, &range) {
+ bool is_io;
+
+ if (r >= rc->max_regions)
+ break;
+
+ if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
+ is_io = false;
+ else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
+ is_io = true;
+ else
+ continue;
+
+ cdns_pcie_set_outbound_region(pcie, 0, r, is_io,
+ range.cpu_addr,
+ range.pci_addr,
+ range.size);
+ r++;
+ }
+
+ /*
+ * Set Root Port no BAR match Inbound Translation registers:
+ * needed for MSI and DMA.
+ * Root Port BAR0 and BAR1 are disabled, hence no need to set their
+ * inbound translation registers.
+ */
+ addr0 = CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(rc->no_bar_nbits);
+ addr1 = 0;
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_RP_BAR_ADDR0(RP_NO_BAR), addr0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_RP_BAR_ADDR1(RP_NO_BAR), addr1);
+
+ return 0;
+}
+
+static int cdns_pcie_host_init(struct device *dev,
+ struct list_head *resources,
+ struct cdns_pcie_rc *rc)
+{
+ struct resource *bus_range = NULL;
+ int err;
+
+ /* Parse our PCI ranges and request their resources */
+ err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
+ if (err)
+ return err;
+
+ rc->bus_range = bus_range;
+ rc->pcie.bus = bus_range->start;
+
+ err = cdns_pcie_host_init_root_port(rc);
+ if (err)
+ goto err_out;
+
+ err = cdns_pcie_host_init_address_translation(rc);
+ if (err)
+ goto err_out;
+
+ return 0;
+
+ err_out:
+ pci_free_resource_list(resources);
+ return err;
+}
+
+static int cdns_pcie_host_probe(struct platform_device *pdev)
+{
+ const char *type;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct pci_host_bridge *bridge;
+ struct list_head resources;
+ struct cdns_pcie_rc *rc;
+ struct cdns_pcie *pcie;
+ struct resource *res;
+ int ret;
+
+ bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+ if (!bridge)
+ return -ENOMEM;
+
+ rc = pci_host_bridge_priv(bridge);
+ rc->dev = dev;
+
+ pcie = &rc->pcie;
+ pcie->is_rc = true;
+
+ rc->max_regions = 32;
+ of_property_read_u32(np, "cdns,max-outbound-regions", &rc->max_regions);
+
+ rc->no_bar_nbits = 32;
+ of_property_read_u32(np, "cdns,no-bar-match-nbits", &rc->no_bar_nbits);
+
+ rc->vendor_id = 0xffff;
+ of_property_read_u16(np, "vendor-id", &rc->vendor_id);
+
+ rc->device_id = 0xffff;
+ of_property_read_u16(np, "device-id", &rc->device_id);
+
+ type = of_get_property(np, "device_type", NULL);
+ if (!type || strcmp(type, "pci")) {
+ dev_err(dev, "invalid \"device_type\" %s\n", type);
+ return -EINVAL;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg");
+ pcie->reg_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(pcie->reg_base)) {
+ dev_err(dev, "missing \"reg\"\n");
+ return PTR_ERR(pcie->reg_base);
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
+ rc->cfg_base = devm_pci_remap_cfg_resource(dev, res);
+ if (IS_ERR(rc->cfg_base)) {
+ dev_err(dev, "missing \"cfg\"\n");
+ return PTR_ERR(rc->cfg_base);
+ }
+ rc->cfg_res = res;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem");
+ if (!res) {
+ dev_err(dev, "missing \"mem\"\n");
+ return -EINVAL;
+ }
+ pcie->mem_res = res;
+
+ pm_runtime_enable(dev);
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ dev_err(dev, "pm_runtime_get_sync() failed\n");
+ goto err_get_sync;
+ }
+
+ ret = cdns_pcie_host_init(dev, &resources, rc);
+ if (ret)
+ goto err_init;
+
+ list_splice_init(&resources, &bridge->windows);
+ bridge->dev.parent = dev;
+ bridge->busnr = pcie->bus;
+ bridge->ops = &cdns_pcie_host_ops;
+ bridge->map_irq = of_irq_parse_and_map_pci;
+ bridge->swizzle_irq = pci_common_swizzle;
+
+ ret = pci_host_probe(bridge);
+ if (ret < 0)
+ goto err_host_probe;
+
+ return 0;
+
+ err_host_probe:
+ pci_free_resource_list(&resources);
+
+ err_init:
+ pm_runtime_put_sync(dev);
+
+ err_get_sync:
+ pm_runtime_disable(dev);
+
+ return ret;
+}
+
+static struct platform_driver cdns_pcie_host_driver = {
+ .driver = {
+ .name = "cdns-pcie-host",
+ .of_match_table = cdns_pcie_host_of_match,
+ },
+ .probe = cdns_pcie_host_probe,
+};
+builtin_platform_driver(cdns_pcie_host_driver);
diff --git a/drivers/pci/cadence/pcie-cadence.c b/drivers/pci/cadence/pcie-cadence.c
new file mode 100644
index 000000000000..138d113eb45d
--- /dev/null
+++ b/drivers/pci/cadence/pcie-cadence.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe controller driver.
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#include <linux/kernel.h>
+
+#include "pcie-cadence.h"
+
+void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn,
+ u32 r, bool is_io,
+ u64 cpu_addr, u64 pci_addr, size_t size)
+{
+ /*
+ * roundup_pow_of_two() returns an unsigned long, which is not suited
+ * for 64bit values.
+ */
+ u64 sz = 1ULL << fls64(size - 1);
+ int nbits = ilog2(sz);
+ u32 addr0, addr1, desc0, desc1;
+
+ if (nbits < 8)
+ nbits = 8;
+
+ /* Set the PCI address */
+ addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) |
+ (lower_32_bits(pci_addr) & GENMASK(31, 8));
+ addr1 = upper_32_bits(pci_addr);
+
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r), addr0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r), addr1);
+
+ /* Set the PCIe header descriptor */
+ if (is_io)
+ desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_IO;
+ else
+ desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MEM;
+ desc1 = 0;
+
+ /*
+ * Whatever Bit [23] is set or not inside DESC0 register of the outbound
+ * PCIe descriptor, the PCI function number must be set into
+ * Bits [26:24] of DESC0 anyway.
+ *
+ * In Root Complex mode, the function number is always 0 but in Endpoint
+ * mode, the PCIe controller may support more than one function. This
+ * function number needs to be set properly into the outbound PCIe
+ * descriptor.
+ *
+ * Besides, setting Bit [23] is mandatory when in Root Complex mode:
+ * then the driver must provide the bus, resp. device, number in
+ * Bits [7:0] of DESC1, resp. Bits[31:27] of DESC0. Like the function
+ * number, the device number is always 0 in Root Complex mode.
+ *
+ * However when in Endpoint mode, we can clear Bit [23] of DESC0, hence
+ * the PCIe controller will use the captured values for the bus and
+ * device numbers.
+ */
+ if (pcie->is_rc) {
+ /* The device and function numbers are always 0. */
+ desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
+ CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
+ desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(pcie->bus);
+ } else {
+ /*
+ * Use captured values for bus and device numbers but still
+ * need to set the function number.
+ */
+ desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(fn);
+ }
+
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(r), desc0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), desc1);
+
+ /* Set the CPU address */
+ cpu_addr -= pcie->mem_res->start;
+ addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) |
+ (lower_32_bits(cpu_addr) & GENMASK(31, 8));
+ addr1 = upper_32_bits(cpu_addr);
+
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), addr0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), addr1);
+}
+
+void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn,
+ u32 r, u64 cpu_addr)
+{
+ u32 addr0, addr1, desc0, desc1;
+
+ desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG;
+ desc1 = 0;
+
+ /* See cdns_pcie_set_outbound_region() comments above. */
+ if (pcie->is_rc) {
+ desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
+ CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
+ desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(pcie->bus);
+ } else {
+ desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(fn);
+ }
+
+ /* Set the CPU address */
+ cpu_addr -= pcie->mem_res->start;
+ addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(17) |
+ (lower_32_bits(cpu_addr) & GENMASK(31, 8));
+ addr1 = upper_32_bits(cpu_addr);
+
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r), 0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r), 0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(r), desc0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), desc1);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), addr0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), addr1);
+}
+
+void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r)
+{
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r), 0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r), 0);
+
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(r), 0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), 0);
+
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), 0);
+ cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), 0);
+}
diff --git a/drivers/pci/cadence/pcie-cadence.h b/drivers/pci/cadence/pcie-cadence.h
new file mode 100644
index 000000000000..4bb27333b05c
--- /dev/null
+++ b/drivers/pci/cadence/pcie-cadence.h
@@ -0,0 +1,311 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017 Cadence
+// Cadence PCIe controller driver.
+// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+
+#ifndef _PCIE_CADENCE_H
+#define _PCIE_CADENCE_H
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+
+/*
+ * Local Management Registers
+ */
+#define CDNS_PCIE_LM_BASE 0x00100000
+
+/* Vendor ID Register */
+#define CDNS_PCIE_LM_ID (CDNS_PCIE_LM_BASE + 0x0044)
+#define CDNS_PCIE_LM_ID_VENDOR_MASK GENMASK(15, 0)
+#define CDNS_PCIE_LM_ID_VENDOR_SHIFT 0
+#define CDNS_PCIE_LM_ID_VENDOR(vid) \
+ (((vid) << CDNS_PCIE_LM_ID_VENDOR_SHIFT) & CDNS_PCIE_LM_ID_VENDOR_MASK)
+#define CDNS_PCIE_LM_ID_SUBSYS_MASK GENMASK(31, 16)
+#define CDNS_PCIE_LM_ID_SUBSYS_SHIFT 16
+#define CDNS_PCIE_LM_ID_SUBSYS(sub) \
+ (((sub) << CDNS_PCIE_LM_ID_SUBSYS_SHIFT) & CDNS_PCIE_LM_ID_SUBSYS_MASK)
+
+/* Root Port Requestor ID Register */
+#define CDNS_PCIE_LM_RP_RID (CDNS_PCIE_LM_BASE + 0x0228)
+#define CDNS_PCIE_LM_RP_RID_MASK GENMASK(15, 0)
+#define CDNS_PCIE_LM_RP_RID_SHIFT 0
+#define CDNS_PCIE_LM_RP_RID_(rid) \
+ (((rid) << CDNS_PCIE_LM_RP_RID_SHIFT) & CDNS_PCIE_LM_RP_RID_MASK)
+
+/* Endpoint Bus and Device Number Register */
+#define CDNS_PCIE_LM_EP_ID (CDNS_PCIE_LM_BASE + 0x022c)
+#define CDNS_PCIE_LM_EP_ID_DEV_MASK GENMASK(4, 0)
+#define CDNS_PCIE_LM_EP_ID_DEV_SHIFT 0
+#define CDNS_PCIE_LM_EP_ID_BUS_MASK GENMASK(15, 8)
+#define CDNS_PCIE_LM_EP_ID_BUS_SHIFT 8
+
+/* Endpoint Function f BAR b Configuration Registers */
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG0(fn) \
+ (CDNS_PCIE_LM_BASE + 0x0240 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG1(fn) \
+ (CDNS_PCIE_LM_BASE + 0x0244 + (fn) * 0x0008)
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b) \
+ (GENMASK(4, 0) << ((b) * 8))
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE(b, a) \
+ (((a) << ((b) * 8)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_APERTURE_MASK(b))
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b) \
+ (GENMASK(7, 5) << ((b) * 8))
+#define CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL(b, c) \
+ (((c) << ((b) * 8 + 5)) & CDNS_PCIE_LM_EP_FUNC_BAR_CFG_BAR_CTRL_MASK(b))
+
+/* Endpoint Function Configuration Register */
+#define CDNS_PCIE_LM_EP_FUNC_CFG (CDNS_PCIE_LM_BASE + 0x02c0)
+
+/* Root Complex BAR Configuration Register */
+#define CDNS_PCIE_LM_RC_BAR_CFG (CDNS_PCIE_LM_BASE + 0x0300)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK GENMASK(5, 0)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE(a) \
+ (((a) << 0) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK GENMASK(8, 6)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(c) \
+ (((c) << 6) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK GENMASK(13, 9)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE(a) \
+ (((a) << 9) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK GENMASK(16, 14)
+#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(c) \
+ (((c) << 14) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK)
+#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE BIT(17)
+#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_32BITS 0
+#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS BIT(18)
+#define CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE BIT(19)
+#define CDNS_PCIE_LM_RC_BAR_CFG_IO_16BITS 0
+#define CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS BIT(20)
+#define CDNS_PCIE_LM_RC_BAR_CFG_CHECK_ENABLE BIT(31)
+
+/* BAR control values applicable to both Endpoint Function and Root Complex */
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED 0x0
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_IO_32BITS 0x1
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_32BITS 0x4
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_32BITS 0x5
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_MEM_64BITS 0x6
+#define CDNS_PCIE_LM_BAR_CFG_CTRL_PREFETCH_MEM_64BITS 0x7
+
+
+/*
+ * Endpoint Function Registers (PCI configuration space for endpoint functions)
+ */
+#define CDNS_PCIE_EP_FUNC_BASE(fn) (((fn) << 12) & GENMASK(19, 12))
+
+#define CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET 0x90
+
+/*
+ * Root Port Registers (PCI configuration space for the root port function)
+ */
+#define CDNS_PCIE_RP_BASE 0x00200000
+
+
+/*
+ * Address Translation Registers
+ */
+#define CDNS_PCIE_AT_BASE 0x00400000
+
+/* Region r Outbound AXI to PCIe Address Translation Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r) \
+ (CDNS_PCIE_AT_BASE + 0x0000 + ((r) & 0x1f) * 0x0020)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK GENMASK(5, 0)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) \
+ (((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS_MASK)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK GENMASK(19, 12)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) \
+ (((devfn) << 12) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN_MASK)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK GENMASK(27, 20)
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(bus) \
+ (((bus) << 20) & CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS_MASK)
+
+/* Region r Outbound AXI to PCIe Address Translation Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r) \
+ (CDNS_PCIE_AT_BASE + 0x0004 + ((r) & 0x1f) * 0x0020)
+
+/* Region r Outbound PCIe Descriptor Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_DESC0(r) \
+ (CDNS_PCIE_AT_BASE + 0x0008 + ((r) & 0x1f) * 0x0020)
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MASK GENMASK(3, 0)
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_MEM 0x2
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_IO 0x6
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0 0xa
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1 0xb
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_NORMAL_MSG 0xc
+#define CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_VENDOR_MSG 0xd
+/* Bit 23 MUST be set in RC mode. */
+#define CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID BIT(23)
+#define CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK GENMASK(31, 24)
+#define CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(devfn) \
+ (((devfn) << 24) & CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN_MASK)
+
+/* Region r Outbound PCIe Descriptor Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_DESC1(r) \
+ (CDNS_PCIE_AT_BASE + 0x000c + ((r) & 0x1f) * 0x0020)
+#define CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK GENMASK(7, 0)
+#define CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus) \
+ ((bus) & CDNS_PCIE_AT_OB_REGION_DESC1_BUS_MASK)
+
+/* Region r AXI Region Base Address Register 0 */
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r) \
+ (CDNS_PCIE_AT_BASE + 0x0018 + ((r) & 0x1f) * 0x0020)
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK GENMASK(5, 0)
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(nbits) \
+ (((nbits) - 1) & CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS_MASK)
+
+/* Region r AXI Region Base Address Register 1 */
+#define CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r) \
+ (CDNS_PCIE_AT_BASE + 0x001c + ((r) & 0x1f) * 0x0020)
+
+/* Root Port BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR0(bar) \
+ (CDNS_PCIE_AT_BASE + 0x0800 + (bar) * 0x0008)
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK GENMASK(5, 0)
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(nbits) \
+ (((nbits) - 1) & CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS_MASK)
+#define CDNS_PCIE_AT_IB_RP_BAR_ADDR1(bar) \
+ (CDNS_PCIE_AT_BASE + 0x0804 + (bar) * 0x0008)
+
+enum cdns_pcie_rp_bar {
+ RP_BAR0,
+ RP_BAR1,
+ RP_NO_BAR
+};
+
+/* Endpoint Function BAR Inbound PCIe to AXI Address Translation Register */
+#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \
+ (CDNS_PCIE_AT_BASE + 0x0840 + (fn) * 0x0040 + (bar) * 0x0008)
+#define CDNS_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \
+ (CDNS_PCIE_AT_BASE + 0x0844 + (fn) * 0x0040 + (bar) * 0x0008)
+
+/* Normal/Vendor specific message access: offset inside some outbound region */
+#define CDNS_PCIE_NORMAL_MSG_ROUTING_MASK GENMASK(7, 5)
+#define CDNS_PCIE_NORMAL_MSG_ROUTING(route) \
+ (((route) << 5) & CDNS_PCIE_NORMAL_MSG_ROUTING_MASK)
+#define CDNS_PCIE_NORMAL_MSG_CODE_MASK GENMASK(15, 8)
+#define CDNS_PCIE_NORMAL_MSG_CODE(code) \
+ (((code) << 8) & CDNS_PCIE_NORMAL_MSG_CODE_MASK)
+#define CDNS_PCIE_MSG_NO_DATA BIT(16)
+
+enum cdns_pcie_msg_code {
+ MSG_CODE_ASSERT_INTA = 0x20,
+ MSG_CODE_ASSERT_INTB = 0x21,
+ MSG_CODE_ASSERT_INTC = 0x22,
+ MSG_CODE_ASSERT_INTD = 0x23,
+ MSG_CODE_DEASSERT_INTA = 0x24,
+ MSG_CODE_DEASSERT_INTB = 0x25,
+ MSG_CODE_DEASSERT_INTC = 0x26,
+ MSG_CODE_DEASSERT_INTD = 0x27,
+};
+
+enum cdns_pcie_msg_routing {
+ /* Route to Root Complex */
+ MSG_ROUTING_TO_RC,
+
+ /* Use Address Routing */
+ MSG_ROUTING_BY_ADDR,
+
+ /* Use ID Routing */
+ MSG_ROUTING_BY_ID,
+
+ /* Route as Broadcast Message from Root Complex */
+ MSG_ROUTING_BCAST,
+
+ /* Local message; terminate at receiver (INTx messages) */
+ MSG_ROUTING_LOCAL,
+
+ /* Gather & route to Root Complex (PME_TO_Ack message) */
+ MSG_ROUTING_GATHER,
+};
+
+/**
+ * struct cdns_pcie - private data for Cadence PCIe controller drivers
+ * @reg_base: IO mapped register base
+ * @mem_res: start/end offsets in the physical system memory to map PCI accesses
+ * @is_rc: tell whether the PCIe controller mode is Root Complex or Endpoint.
+ * @bus: In Root Complex mode, the bus number
+ */
+struct cdns_pcie {
+ void __iomem *reg_base;
+ struct resource *mem_res;
+ bool is_rc;
+ u8 bus;
+};
+
+/* Register access */
+static inline void cdns_pcie_writeb(struct cdns_pcie *pcie, u32 reg, u8 value)
+{
+ writeb(value, pcie->reg_base + reg);
+}
+
+static inline void cdns_pcie_writew(struct cdns_pcie *pcie, u32 reg, u16 value)
+{
+ writew(value, pcie->reg_base + reg);
+}
+
+static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value)
+{
+ writel(value, pcie->reg_base + reg);
+}
+
+static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
+{
+ return readl(pcie->reg_base + reg);
+}
+
+/* Root Port register access */
+static inline void cdns_pcie_rp_writeb(struct cdns_pcie *pcie,
+ u32 reg, u8 value)
+{
+ writeb(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+}
+
+static inline void cdns_pcie_rp_writew(struct cdns_pcie *pcie,
+ u32 reg, u16 value)
+{
+ writew(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
+}
+
+/* Endpoint Function register access */
+static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn,
+ u32 reg, u8 value)
+{
+ writeb(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline void cdns_pcie_ep_fn_writew(struct cdns_pcie *pcie, u8 fn,
+ u32 reg, u16 value)
+{
+ writew(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline void cdns_pcie_ep_fn_writel(struct cdns_pcie *pcie, u8 fn,
+ u32 reg, u16 value)
+{
+ writel(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline u8 cdns_pcie_ep_fn_readb(struct cdns_pcie *pcie, u8 fn, u32 reg)
+{
+ return readb(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline u16 cdns_pcie_ep_fn_readw(struct cdns_pcie *pcie, u8 fn, u32 reg)
+{
+ return readw(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg)
+{
+ return readl(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
+}
+
+void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn,
+ u32 r, bool is_io,
+ u64 cpu_addr, u64 pci_addr, size_t size);
+
+void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn,
+ u32 r, u64 cpu_addr);
+
+void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r);
+
+#endif /* _PCIE_CADENCE_H */
diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
index 113e09440f85..0f666b1ce289 100644
--- a/drivers/pci/dwc/Kconfig
+++ b/drivers/pci/dwc/Kconfig
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
menu "DesignWare PCI Core Support"
config PCIE_DW
@@ -15,39 +17,38 @@ config PCIE_DW_EP
select PCIE_DW
config PCI_DRA7XX
- bool "TI DRA7xx PCIe controller"
- depends on SOC_DRA7XX || COMPILE_TEST
- depends on (PCI && PCI_MSI_IRQ_DOMAIN) || PCI_ENDPOINT
- depends on OF && HAS_IOMEM && TI_PIPE3
- help
- Enables support for the PCIe controller in the DRA7xx SoC. There
- are two instances of PCIe controller in DRA7xx. This controller can
- work either as EP or RC. In order to enable host-specific features
- PCI_DRA7XX_HOST must be selected and in order to enable device-
- specific features PCI_DRA7XX_EP must be selected. This uses
- the DesignWare core.
-
-if PCI_DRA7XX
+ bool
config PCI_DRA7XX_HOST
- bool "PCI DRA7xx Host Mode"
- depends on PCI
- depends on PCI_MSI_IRQ_DOMAIN
+ bool "TI DRA7xx PCIe controller Host Mode"
+ depends on SOC_DRA7XX || COMPILE_TEST
+ depends on PCI && PCI_MSI_IRQ_DOMAIN
+ depends on OF && HAS_IOMEM && TI_PIPE3
select PCIE_DW_HOST
+ select PCI_DRA7XX
default y
help
- Enables support for the PCIe controller in the DRA7xx SoC to work in
- host mode.
+ Enables support for the PCIe controller in the DRA7xx SoC to work in
+ host mode. There are two instances of PCIe controller in DRA7xx.
+ This controller can work either as EP or RC. In order to enable
+ host-specific features PCI_DRA7XX_HOST must be selected and in order
+ to enable device-specific features PCI_DRA7XX_EP must be selected.
+ This uses the DesignWare core.
config PCI_DRA7XX_EP
- bool "PCI DRA7xx Endpoint Mode"
+ bool "TI DRA7xx PCIe controller Endpoint Mode"
+ depends on SOC_DRA7XX || COMPILE_TEST
depends on PCI_ENDPOINT
+ depends on OF && HAS_IOMEM && TI_PIPE3
select PCIE_DW_EP
+ select PCI_DRA7XX
help
- Enables support for the PCIe controller in the DRA7xx SoC to work in
- endpoint mode.
-
-endif
+ Enables support for the PCIe controller in the DRA7xx SoC to work in
+ endpoint mode. There are two instances of PCIe controller in DRA7xx.
+ This controller can work either as EP or RC. In order to enable
+ host-specific features PCI_DRA7XX_HOST must be selected and in order
+ to enable device-specific features PCI_DRA7XX_EP must be selected.
+ This uses the DesignWare core.
config PCIE_DW_PLAT
bool "Platform bus based DesignWare PCIe Controller"
@@ -149,15 +150,28 @@ config PCIE_ARMADA_8K
DesignWare core functions to implement the driver.
config PCIE_ARTPEC6
- bool "Axis ARTPEC-6 PCIe controller"
- depends on PCI
+ bool
+
+config PCIE_ARTPEC6_HOST
+ bool "Axis ARTPEC-6 PCIe controller Host Mode"
depends on MACH_ARTPEC6
- depends on PCI_MSI_IRQ_DOMAIN
+ depends on PCI && PCI_MSI_IRQ_DOMAIN
select PCIEPORTBUS
select PCIE_DW_HOST
+ select PCIE_ARTPEC6
+ help
+ Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
+ host mode. This uses the DesignWare core.
+
+config PCIE_ARTPEC6_EP
+ bool "Axis ARTPEC-6 PCIe controller Endpoint Mode"
+ depends on MACH_ARTPEC6
+ depends on PCI_ENDPOINT
+ select PCIE_DW_EP
+ select PCIE_ARTPEC6
help
- Say Y here to enable PCIe controller support on Axis ARTPEC-6
- SoCs. This PCIe controller uses the DesignWare core.
+ Enables support for the PCIe controller in the ARTPEC-6 SoC to work in
+ endpoint mode. This uses the DesignWare core.
config PCIE_KIRIN
depends on OF && ARM64
diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
index 41ba499c96ee..5d2ce72c7a52 100644
--- a/drivers/pci/dwc/Makefile
+++ b/drivers/pci/dwc/Makefile
@@ -3,9 +3,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
-ifneq ($(filter y,$(CONFIG_PCI_DRA7XX_HOST) $(CONFIG_PCI_DRA7XX_EP)),)
- obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
-endif
+obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
@@ -27,4 +25,6 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
# ARM64 and use internal ifdefs to only build the pieces we need
# depending on whether ACPI, the DT driver, or both are enabled.
+ifdef CONFIG_PCI
obj-$(CONFIG_ARM64) += pcie-hisi.o
+endif
diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index e77a4ceed74c..ed8558d638e5 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* pcie-dra7xx - PCIe controller driver for TI DRA7xx SoCs
*
* Copyright (C) 2013-2014 Texas Instruments Incorporated - http://www.ti.com
*
* Authors: Kishon Vijay Abraham I <kishon@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>
@@ -110,7 +107,7 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
writel(value, pcie->base + offset);
}
-static u64 dra7xx_pcie_cpu_addr_fixup(u64 pci_addr)
+static u64 dra7xx_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
{
return pci_addr & DRA7XX_CPU_TO_BUS_ADDR;
}
@@ -226,6 +223,7 @@ static int dra7xx_pcie_intx_map(struct irq_domain *domain, unsigned int irq,
static const struct irq_domain_ops intx_domain_ops = {
.map = dra7xx_pcie_intx_map,
+ .xlate = pci_irqd_intx_xlate,
};
static int dra7xx_pcie_init_irq_domain(struct pcie_port *pp)
@@ -256,7 +254,8 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
struct dra7xx_pcie *dra7xx = arg;
struct dw_pcie *pci = dra7xx->pci;
struct pcie_port *pp = &pci->pp;
- u32 reg;
+ unsigned long reg;
+ u32 virq, bit;
reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI);
@@ -268,8 +267,11 @@ static irqreturn_t dra7xx_pcie_msi_irq_handler(int irq, void *arg)
case INTB:
case INTC:
case INTD:
- generic_handle_irq(irq_find_mapping(dra7xx->irq_domain,
- ffs(reg)));
+ for_each_set_bit(bit, &reg, PCI_NUM_INTX) {
+ virq = irq_find_mapping(dra7xx->irq_domain, bit);
+ if (virq)
+ generic_handle_irq(virq);
+ }
break;
}
@@ -337,15 +339,6 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
}
-static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
-{
- u32 reg;
-
- reg = PCI_BASE_ADDRESS_0 + (4 * bar);
- dw_pcie_writel_dbi2(pci, reg, 0x0);
- dw_pcie_writel_dbi(pci, reg, 0x0);
-}
-
static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep)
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -375,7 +368,7 @@ static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie *dra7xx,
dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_MSI_XMT, reg);
}
-static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep,
+static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
enum pci_epc_irq_type type, u8 interrupt_num)
{
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -470,6 +463,8 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
if (!pci->dbi_base)
return -ENOMEM;
+ pp->ops = &dra7xx_pcie_host_ops;
+
ret = dw_pcie_host_init(pp);
if (ret) {
dev_err(dev, "failed to initialize host\n");
@@ -599,7 +594,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
void __iomem *base;
struct resource *res;
struct dw_pcie *pci;
- struct pcie_port *pp;
struct dra7xx_pcie *dra7xx;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
@@ -627,9 +621,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
pci->dev = dev;
pci->ops = &dw_pcie_ops;
- pp = &pci->pp;
- pp->ops = &dra7xx_pcie_host_ops;
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(dev, "missing IRQ resource: %d\n", irq);
@@ -705,6 +696,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
switch (mode) {
case DW_PCIE_RC_TYPE:
+ if (!IS_ENABLED(CONFIG_PCI_DRA7XX_HOST)) {
+ ret = -ENODEV;
+ goto err_gpio;
+ }
+
dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
DEVICE_TYPE_RC);
ret = dra7xx_add_pcie_port(dra7xx, pdev);
@@ -712,6 +708,11 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
goto err_gpio;
break;
case DW_PCIE_EP_TYPE:
+ if (!IS_ENABLED(CONFIG_PCI_DRA7XX_EP)) {
+ ret = -ENODEV;
+ goto err_gpio;
+ }
+
dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
DEVICE_TYPE_EP);
@@ -810,7 +811,7 @@ static int dra7xx_pcie_resume_noirq(struct device *dev)
}
#endif
-void dra7xx_pcie_shutdown(struct platform_device *pdev)
+static void dra7xx_pcie_shutdown(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct dra7xx_pcie *dra7xx = dev_get_drvdata(dev);
diff --git a/drivers/pci/dwc/pci-exynos.c b/drivers/pci/dwc/pci-exynos.c
index 5596fdedbb94..ca6278113936 100644
--- a/drivers/pci/dwc/pci-exynos.c
+++ b/drivers/pci/dwc/pci-exynos.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for Samsung EXYNOS SoCs
*
@@ -5,10 +6,6 @@
* http://www.samsung.com
*
* Author: Jingoo Han <jg1.han@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/clk.h>
@@ -55,49 +52,8 @@
#define PCIE_ELBI_SLV_ARMISC 0x120
#define PCIE_ELBI_SLV_DBI_ENABLE BIT(21)
-/* PCIe Purple registers */
-#define PCIE_PHY_GLOBAL_RESET 0x000
-#define PCIE_PHY_COMMON_RESET 0x004
-#define PCIE_PHY_CMN_REG 0x008
-#define PCIE_PHY_MAC_RESET 0x00c
-#define PCIE_PHY_PLL_LOCKED 0x010
-#define PCIE_PHY_TRSVREG_RESET 0x020
-#define PCIE_PHY_TRSV_RESET 0x024
-
-/* PCIe PHY registers */
-#define PCIE_PHY_IMPEDANCE 0x004
-#define PCIE_PHY_PLL_DIV_0 0x008
-#define PCIE_PHY_PLL_BIAS 0x00c
-#define PCIE_PHY_DCC_FEEDBACK 0x014
-#define PCIE_PHY_PLL_DIV_1 0x05c
-#define PCIE_PHY_COMMON_POWER 0x064
-#define PCIE_PHY_COMMON_PD_CMN BIT(3)
-#define PCIE_PHY_TRSV0_EMP_LVL 0x084
-#define PCIE_PHY_TRSV0_DRV_LVL 0x088
-#define PCIE_PHY_TRSV0_RXCDR 0x0ac
-#define PCIE_PHY_TRSV0_POWER 0x0c4
-#define PCIE_PHY_TRSV0_PD_TSV BIT(7)
-#define PCIE_PHY_TRSV0_LVCC 0x0dc
-#define PCIE_PHY_TRSV1_EMP_LVL 0x144
-#define PCIE_PHY_TRSV1_RXCDR 0x16c
-#define PCIE_PHY_TRSV1_POWER 0x184
-#define PCIE_PHY_TRSV1_PD_TSV BIT(7)
-#define PCIE_PHY_TRSV1_LVCC 0x19c
-#define PCIE_PHY_TRSV2_EMP_LVL 0x204
-#define PCIE_PHY_TRSV2_RXCDR 0x22c
-#define PCIE_PHY_TRSV2_POWER 0x244
-#define PCIE_PHY_TRSV2_PD_TSV BIT(7)
-#define PCIE_PHY_TRSV2_LVCC 0x25c
-#define PCIE_PHY_TRSV3_EMP_LVL 0x2c4
-#define PCIE_PHY_TRSV3_RXCDR 0x2ec
-#define PCIE_PHY_TRSV3_POWER 0x304
-#define PCIE_PHY_TRSV3_PD_TSV BIT(7)
-#define PCIE_PHY_TRSV3_LVCC 0x31c
-
struct exynos_pcie_mem_res {
void __iomem *elbi_base; /* DT 0th resource: PCIe CTRL */
- void __iomem *phy_base; /* DT 1st resource: PHY CTRL */
- void __iomem *block_base; /* DT 2nd resource: PHY ADDITIONAL CTRL */
};
struct exynos_pcie_clk_res {
@@ -112,8 +68,6 @@ struct exynos_pcie {
const struct exynos_pcie_ops *ops;
int reset_gpio;
- /* For Generic PHY Framework */
- bool using_phy;
struct phy *phy;
};
@@ -141,20 +95,6 @@ static int exynos5440_pcie_get_mem_resources(struct platform_device *pdev,
if (IS_ERR(ep->mem_res->elbi_base))
return PTR_ERR(ep->mem_res->elbi_base);
- /* If using the PHY framework, doesn't need to get other resource */
- if (ep->using_phy)
- return 0;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- ep->mem_res->phy_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(ep->mem_res->phy_base))
- return PTR_ERR(ep->mem_res->phy_base);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
- ep->mem_res->block_base = devm_ioremap_resource(dev, res);
- if (IS_ERR(ep->mem_res->block_base))
- return PTR_ERR(ep->mem_res->block_base);
-
return 0;
}
@@ -279,111 +219,6 @@ static void exynos_pcie_deassert_core_reset(struct exynos_pcie *ep)
exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_NONSTICKY_RESET);
exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_APP_INIT_RESET);
exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_APP_INIT_RESET);
- exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_MAC_RESET);
-}
-
-static void exynos_pcie_assert_phy_reset(struct exynos_pcie *ep)
-{
- exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_MAC_RESET);
- exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_GLOBAL_RESET);
-}
-
-static void exynos_pcie_deassert_phy_reset(struct exynos_pcie *ep)
-{
- exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_GLOBAL_RESET);
- exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_PWR_RESET);
- exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_COMMON_RESET);
- exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_CMN_REG);
- exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_TRSVREG_RESET);
- exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_TRSV_RESET);
-}
-
-static void exynos_pcie_power_on_phy(struct exynos_pcie *ep)
-{
- u32 val;
-
- val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_COMMON_POWER);
- val &= ~PCIE_PHY_COMMON_PD_CMN;
- exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_COMMON_POWER);
-
- val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV0_POWER);
- val &= ~PCIE_PHY_TRSV0_PD_TSV;
- exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV0_POWER);
-
- val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV1_POWER);
- val &= ~PCIE_PHY_TRSV1_PD_TSV;
- exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV1_POWER);
-
- val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV2_POWER);
- val &= ~PCIE_PHY_TRSV2_PD_TSV;
- exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV2_POWER);
-
- val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV3_POWER);
- val &= ~PCIE_PHY_TRSV3_PD_TSV;
- exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV3_POWER);
-}
-
-static void exynos_pcie_power_off_phy(struct exynos_pcie *ep)
-{
- u32 val;
-
- val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_COMMON_POWER);
- val |= PCIE_PHY_COMMON_PD_CMN;
- exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_COMMON_POWER);
-
- val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV0_POWER);
- val |= PCIE_PHY_TRSV0_PD_TSV;
- exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV0_POWER);
-
- val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV1_POWER);
- val |= PCIE_PHY_TRSV1_PD_TSV;
- exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV1_POWER);
-
- val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV2_POWER);
- val |= PCIE_PHY_TRSV2_PD_TSV;
- exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV2_POWER);
-
- val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV3_POWER);
- val |= PCIE_PHY_TRSV3_PD_TSV;
- exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV3_POWER);
-}
-
-static void exynos_pcie_init_phy(struct exynos_pcie *ep)
-{
- /* DCC feedback control off */
- exynos_pcie_writel(ep->mem_res->phy_base, 0x29, PCIE_PHY_DCC_FEEDBACK);
-
- /* set TX/RX impedance */
- exynos_pcie_writel(ep->mem_res->phy_base, 0xd5, PCIE_PHY_IMPEDANCE);
-
- /* set 50Mhz PHY clock */
- exynos_pcie_writel(ep->mem_res->phy_base, 0x14, PCIE_PHY_PLL_DIV_0);
- exynos_pcie_writel(ep->mem_res->phy_base, 0x12, PCIE_PHY_PLL_DIV_1);
-
- /* set TX Differential output for lane 0 */
- exynos_pcie_writel(ep->mem_res->phy_base, 0x7f, PCIE_PHY_TRSV0_DRV_LVL);
-
- /* set TX Pre-emphasis Level Control for lane 0 to minimum */
- exynos_pcie_writel(ep->mem_res->phy_base, 0x0, PCIE_PHY_TRSV0_EMP_LVL);
-
- /* set RX clock and data recovery bandwidth */
- exynos_pcie_writel(ep->mem_res->phy_base, 0xe7, PCIE_PHY_PLL_BIAS);
- exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV0_RXCDR);
- exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV1_RXCDR);
- exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV2_RXCDR);
- exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV3_RXCDR);
-
- /* change TX Pre-emphasis Level Control for lanes */
- exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV0_EMP_LVL);
- exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV1_EMP_LVL);
- exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV2_EMP_LVL);
- exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV3_EMP_LVL);
-
- /* set LVCC */
- exynos_pcie_writel(ep->mem_res->phy_base, 0x20, PCIE_PHY_TRSV0_LVCC);
- exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV1_LVCC);
- exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV2_LVCC);
- exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV3_LVCC);
}
static void exynos_pcie_assert_reset(struct exynos_pcie *ep)
@@ -401,7 +236,6 @@ static int exynos_pcie_establish_link(struct exynos_pcie *ep)
struct dw_pcie *pci = ep->pci;
struct pcie_port *pp = &pci->pp;
struct device *dev = pci->dev;
- u32 val;
if (dw_pcie_link_up(pci)) {
dev_err(dev, "Link already up\n");
@@ -410,32 +244,13 @@ static int exynos_pcie_establish_link(struct exynos_pcie *ep)
exynos_pcie_assert_core_reset(ep);
- if (ep->using_phy) {
- phy_reset(ep->phy);
-
- exynos_pcie_writel(ep->mem_res->elbi_base, 1,
- PCIE_PWR_RESET);
-
- phy_power_on(ep->phy);
- phy_init(ep->phy);
- } else {
- exynos_pcie_assert_phy_reset(ep);
- exynos_pcie_deassert_phy_reset(ep);
- exynos_pcie_power_on_phy(ep);
- exynos_pcie_init_phy(ep);
-
- /* pulse for common reset */
- exynos_pcie_writel(ep->mem_res->block_base, 1,
- PCIE_PHY_COMMON_RESET);
- udelay(500);
- exynos_pcie_writel(ep->mem_res->block_base, 0,
- PCIE_PHY_COMMON_RESET);
- }
+ phy_reset(ep->phy);
- /* pulse for common reset */
- exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_COMMON_RESET);
- udelay(500);
- exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_COMMON_RESET);
+ exynos_pcie_writel(ep->mem_res->elbi_base, 1,
+ PCIE_PWR_RESET);
+
+ phy_power_on(ep->phy);
+ phy_init(ep->phy);
exynos_pcie_deassert_core_reset(ep);
dw_pcie_setup_rc(pp);
@@ -449,18 +264,7 @@ static int exynos_pcie_establish_link(struct exynos_pcie *ep)
if (!dw_pcie_wait_for_link(pci))
return 0;
- if (ep->using_phy) {
- phy_power_off(ep->phy);
- return -ETIMEDOUT;
- }
-
- while (exynos_pcie_readl(ep->mem_res->phy_base,
- PCIE_PHY_PLL_LOCKED) == 0) {
- val = exynos_pcie_readl(ep->mem_res->block_base,
- PCIE_PHY_PLL_LOCKED);
- dev_info(dev, "PLL Locked: 0x%x\n", val);
- }
- exynos_pcie_power_off_phy(ep);
+ phy_power_off(ep->phy);
return -ETIMEDOUT;
}
@@ -678,16 +482,13 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
ep->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
- /* Assume that controller doesn't use the PHY framework */
- ep->using_phy = false;
-
ep->phy = devm_of_phy_get(dev, np, NULL);
if (IS_ERR(ep->phy)) {
if (PTR_ERR(ep->phy) == -EPROBE_DEFER)
return PTR_ERR(ep->phy);
- dev_warn(dev, "Use the 'phy' property. Current DT of pci-exynos was deprecated!!\n");
- } else
- ep->using_phy = true;
+
+ ep->phy = NULL;
+ }
if (ep->ops && ep->ops->get_mem_resources) {
ret = ep->ops->get_mem_resources(pdev, ep);
@@ -695,7 +496,8 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
return ret;
}
- if (ep->ops && ep->ops->get_clk_resources) {
+ if (ep->ops && ep->ops->get_clk_resources &&
+ ep->ops->init_clk_resources) {
ret = ep->ops->get_clk_resources(ep);
if (ret)
return ret;
@@ -713,8 +515,7 @@ static int __init exynos_pcie_probe(struct platform_device *pdev)
return 0;
fail_probe:
- if (ep->using_phy)
- phy_exit(ep->phy);
+ phy_exit(ep->phy);
if (ep->ops && ep->ops->deinit_clk_resources)
ep->ops->deinit_clk_resources(ep);
diff --git a/drivers/pci/dwc/pci-imx6.c b/drivers/pci/dwc/pci-imx6.c
index b73483534a5b..4fddbd08b089 100644
--- a/drivers/pci/dwc/pci-imx6.c
+++ b/drivers/pci/dwc/pci-imx6.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for Freescale i.MX6 SoCs
*
@@ -5,10 +6,6 @@
* http://www.kosagi.com
*
* Author: Sean Cross <xobs@kosagi.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/clk.h>
diff --git a/drivers/pci/dwc/pci-keystone-dw.c b/drivers/pci/dwc/pci-keystone-dw.c
index 2fb20b887d2a..99a0e7076221 100644
--- a/drivers/pci/dwc/pci-keystone-dw.c
+++ b/drivers/pci/dwc/pci-keystone-dw.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* DesignWare application register space functions for Keystone PCI controller
*
@@ -5,11 +6,6 @@
* http://www.ti.com
*
* Author: Murali Karicheri <m-karicheri2@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/irq.h>
diff --git a/drivers/pci/dwc/pci-keystone.c b/drivers/pci/dwc/pci-keystone.c
index 5bee3af47588..d4f8ab90c018 100644
--- a/drivers/pci/dwc/pci-keystone.c
+++ b/drivers/pci/dwc/pci-keystone.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for Texas Instruments Keystone SoCs
*
@@ -6,10 +7,6 @@
*
* Author: Murali Karicheri <m-karicheri2@ti.com>
* Implementation based on pci-exynos.c and pcie-designware.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.
*/
#include <linux/irqchip/chained_irq.h>
@@ -178,7 +175,7 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
}
/* interrupt controller is in a child node */
- *np_temp = of_find_node_by_name(np_pcie, controller);
+ *np_temp = of_get_child_by_name(np_pcie, controller);
if (!(*np_temp)) {
dev_err(dev, "Node for %s is absent\n", controller);
return -EINVAL;
@@ -187,6 +184,7 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
temp = of_irq_count(*np_temp);
if (!temp) {
dev_err(dev, "No IRQ entries in %s\n", controller);
+ of_node_put(*np_temp);
return -EINVAL;
}
@@ -204,6 +202,8 @@ static int ks_pcie_get_irq_controller_info(struct keystone_pcie *ks_pcie,
break;
}
+ of_node_put(*np_temp);
+
if (temp) {
*num_irqs = temp;
return 0;
diff --git a/drivers/pci/dwc/pci-keystone.h b/drivers/pci/dwc/pci-keystone.h
index 30b7bc2ac380..1dd1f3ef98e7 100644
--- a/drivers/pci/dwc/pci-keystone.h
+++ b/drivers/pci/dwc/pci-keystone.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Keystone PCI Controller's common includes
*
@@ -5,11 +6,6 @@
* http://www.ti.com
*
* Author: Murali Karicheri <m-karicheri2@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.
*/
#define MAX_MSI_HOST_IRQS 8
diff --git a/drivers/pci/dwc/pci-layerscape.c b/drivers/pci/dwc/pci-layerscape.c
index 8f34c2fdc600..a7b4159631ae 100644
--- a/drivers/pci/dwc/pci-layerscape.c
+++ b/drivers/pci/dwc/pci-layerscape.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for Freescale Layerscape SoCs
*
* Copyright (C) 2014 Freescale Semiconductor.
*
* Author: Minghuan Lian <Minghuan.Lian@freescale.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>
diff --git a/drivers/pci/dwc/pcie-armada8k.c b/drivers/pci/dwc/pcie-armada8k.c
index 370d057c0046..b587352f8b9f 100644
--- a/drivers/pci/dwc/pcie-armada8k.c
+++ b/drivers/pci/dwc/pcie-armada8k.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for Marvell Armada-8K SoCs
*
@@ -7,10 +8,6 @@
*
* Author: Yehuda Yitshak <yehuday@marvell.com>
* Author: Shadi Ammouri <shadi@marvell.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#include <linux/clk.h>
diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c
index 6653619db6a1..93b3df9ed1b5 100644
--- a/drivers/pci/dwc/pcie-artpec6.c
+++ b/drivers/pci/dwc/pcie-artpec6.c
@@ -1,18 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for Axis ARTPEC-6 SoC
*
* Author: Niklas Cassel <niklas.cassel@axis.com>
*
* Based on work done by Phil Edworthy <phil@edworthys.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/delay.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/of_device.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/resource.h>
@@ -26,44 +24,72 @@
#define to_artpec6_pcie(x) dev_get_drvdata((x)->dev)
+enum artpec_pcie_variants {
+ ARTPEC6,
+ ARTPEC7,
+};
+
struct artpec6_pcie {
struct dw_pcie *pci;
struct regmap *regmap; /* DT axis,syscon-pcie */
void __iomem *phy_base; /* DT phy */
+ enum artpec_pcie_variants variant;
+ enum dw_pcie_device_mode mode;
};
+struct artpec_pcie_of_data {
+ enum artpec_pcie_variants variant;
+ enum dw_pcie_device_mode mode;
+};
+
+static const struct of_device_id artpec6_pcie_of_match[];
+
/* PCIe Port Logic registers (memory-mapped) */
#define PL_OFFSET 0x700
-#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
-#define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
-#define MISC_CONTROL_1_OFF (PL_OFFSET + 0x1bc)
-#define DBI_RO_WR_EN 1
+#define ACK_F_ASPM_CTRL_OFF (PL_OFFSET + 0xc)
+#define ACK_N_FTS_MASK GENMASK(15, 8)
+#define ACK_N_FTS(x) (((x) << 8) & ACK_N_FTS_MASK)
+
+#define FAST_TRAINING_SEQ_MASK GENMASK(7, 0)
+#define FAST_TRAINING_SEQ(x) (((x) << 0) & FAST_TRAINING_SEQ_MASK)
/* ARTPEC-6 specific registers */
#define PCIECFG 0x18
-#define PCIECFG_DBG_OEN (1 << 24)
-#define PCIECFG_CORE_RESET_REQ (1 << 21)
-#define PCIECFG_LTSSM_ENABLE (1 << 20)
-#define PCIECFG_CLKREQ_B (1 << 11)
-#define PCIECFG_REFCLK_ENABLE (1 << 10)
-#define PCIECFG_PLL_ENABLE (1 << 9)
-#define PCIECFG_PCLK_ENABLE (1 << 8)
-#define PCIECFG_RISRCREN (1 << 4)
-#define PCIECFG_MODE_TX_DRV_EN (1 << 3)
-#define PCIECFG_CISRREN (1 << 2)
-#define PCIECFG_MACRO_ENABLE (1 << 0)
+#define PCIECFG_DBG_OEN BIT(24)
+#define PCIECFG_CORE_RESET_REQ BIT(21)
+#define PCIECFG_LTSSM_ENABLE BIT(20)
+#define PCIECFG_DEVICE_TYPE_MASK GENMASK(19, 16)
+#define PCIECFG_CLKREQ_B BIT(11)
+#define PCIECFG_REFCLK_ENABLE BIT(10)
+#define PCIECFG_PLL_ENABLE BIT(9)
+#define PCIECFG_PCLK_ENABLE BIT(8)
+#define PCIECFG_RISRCREN BIT(4)
+#define PCIECFG_MODE_TX_DRV_EN BIT(3)
+#define PCIECFG_CISRREN BIT(2)
+#define PCIECFG_MACRO_ENABLE BIT(0)
+/* ARTPEC-7 specific fields */
+#define PCIECFG_REFCLKSEL BIT(23)
+#define PCIECFG_NOC_RESET BIT(3)
+
+#define PCIESTAT 0x1c
+/* ARTPEC-7 specific fields */
+#define PCIESTAT_EXTREFCLK BIT(3)
#define NOCCFG 0x40
-#define NOCCFG_ENABLE_CLK_PCIE (1 << 4)
-#define NOCCFG_POWER_PCIE_IDLEACK (1 << 3)
-#define NOCCFG_POWER_PCIE_IDLE (1 << 2)
-#define NOCCFG_POWER_PCIE_IDLEREQ (1 << 1)
+#define NOCCFG_ENABLE_CLK_PCIE BIT(4)
+#define NOCCFG_POWER_PCIE_IDLEACK BIT(3)
+#define NOCCFG_POWER_PCIE_IDLE BIT(2)
+#define NOCCFG_POWER_PCIE_IDLEREQ BIT(1)
#define PHY_STATUS 0x118
-#define PHY_COSPLLLOCK (1 << 0)
+#define PHY_COSPLLLOCK BIT(0)
+
+#define PHY_TX_ASIC_OUT 0x4040
+#define PHY_TX_ASIC_OUT_TX_ACK BIT(0)
-#define ARTPEC6_CPU_TO_BUS_ADDR 0x0fffffff
+#define PHY_RX_ASIC_OUT 0x405c
+#define PHY_RX_ASIC_OUT_ACK BIT(0)
static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset)
{
@@ -78,22 +104,123 @@ static void artpec6_pcie_writel(struct artpec6_pcie *artpec6_pcie, u32 offset, u
regmap_write(artpec6_pcie->regmap, offset, val);
}
-static u64 artpec6_pcie_cpu_addr_fixup(u64 pci_addr)
+static u64 artpec6_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
{
- return pci_addr & ARTPEC6_CPU_TO_BUS_ADDR;
+ struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
+ struct pcie_port *pp = &pci->pp;
+ struct dw_pcie_ep *ep = &pci->ep;
+
+ switch (artpec6_pcie->mode) {
+ case DW_PCIE_RC_TYPE:
+ return pci_addr - pp->cfg0_base;
+ case DW_PCIE_EP_TYPE:
+ return pci_addr - ep->phys_base;
+ default:
+ dev_err(pci->dev, "UNKNOWN device type\n");
+ }
+ return pci_addr;
}
-static int artpec6_pcie_establish_link(struct artpec6_pcie *artpec6_pcie)
+static int artpec6_pcie_establish_link(struct dw_pcie *pci)
{
- struct dw_pcie *pci = artpec6_pcie->pci;
- struct pcie_port *pp = &pci->pp;
+ struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
+ u32 val;
+
+ val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
+ val |= PCIECFG_LTSSM_ENABLE;
+ artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+
+ return 0;
+}
+
+static void artpec6_pcie_stop_link(struct dw_pcie *pci)
+{
+ struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
u32 val;
- unsigned int retries;
- /* Hold DW core in reset */
val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
- val |= PCIECFG_CORE_RESET_REQ;
+ val &= ~PCIECFG_LTSSM_ENABLE;
artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+}
+
+static const struct dw_pcie_ops dw_pcie_ops = {
+ .cpu_addr_fixup = artpec6_pcie_cpu_addr_fixup,
+ .start_link = artpec6_pcie_establish_link,
+ .stop_link = artpec6_pcie_stop_link,
+};
+
+static void artpec6_pcie_wait_for_phy_a6(struct artpec6_pcie *artpec6_pcie)
+{
+ struct dw_pcie *pci = artpec6_pcie->pci;
+ struct device *dev = pci->dev;
+ u32 val;
+ unsigned int retries;
+
+ retries = 50;
+ do {
+ usleep_range(1000, 2000);
+ val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
+ retries--;
+ } while (retries &&
+ (val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
+ if (!retries)
+ dev_err(dev, "PCIe clock manager did not leave idle state\n");
+
+ retries = 50;
+ do {
+ usleep_range(1000, 2000);
+ val = readl(artpec6_pcie->phy_base + PHY_STATUS);
+ retries--;
+ } while (retries && !(val & PHY_COSPLLLOCK));
+ if (!retries)
+ dev_err(dev, "PHY PLL did not lock\n");
+}
+
+static void artpec6_pcie_wait_for_phy_a7(struct artpec6_pcie *artpec6_pcie)
+{
+ struct dw_pcie *pci = artpec6_pcie->pci;
+ struct device *dev = pci->dev;
+ u32 val;
+ u16 phy_status_tx, phy_status_rx;
+ unsigned int retries;
+
+ retries = 50;
+ do {
+ usleep_range(1000, 2000);
+ val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
+ retries--;
+ } while (retries &&
+ (val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
+ if (!retries)
+ dev_err(dev, "PCIe clock manager did not leave idle state\n");
+
+ retries = 50;
+ do {
+ usleep_range(1000, 2000);
+ phy_status_tx = readw(artpec6_pcie->phy_base + PHY_TX_ASIC_OUT);
+ phy_status_rx = readw(artpec6_pcie->phy_base + PHY_RX_ASIC_OUT);
+ retries--;
+ } while (retries && ((phy_status_tx & PHY_TX_ASIC_OUT_TX_ACK) ||
+ (phy_status_rx & PHY_RX_ASIC_OUT_ACK)));
+ if (!retries)
+ dev_err(dev, "PHY did not enter Pn state\n");
+}
+
+static void artpec6_pcie_wait_for_phy(struct artpec6_pcie *artpec6_pcie)
+{
+ switch (artpec6_pcie->variant) {
+ case ARTPEC6:
+ artpec6_pcie_wait_for_phy_a6(artpec6_pcie);
+ break;
+ case ARTPEC7:
+ artpec6_pcie_wait_for_phy_a7(artpec6_pcie);
+ break;
+ }
+}
+
+static void artpec6_pcie_init_phy_a6(struct artpec6_pcie *artpec6_pcie)
+{
+ u32 val;
val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
val |= PCIECFG_RISRCREN | /* Receiver term. 50 Ohm */
@@ -119,45 +246,110 @@ static int artpec6_pcie_establish_link(struct artpec6_pcie *artpec6_pcie)
val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
val &= ~NOCCFG_POWER_PCIE_IDLEREQ;
artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
+}
- retries = 50;
- do {
- usleep_range(1000, 2000);
- val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
- retries--;
- } while (retries &&
- (val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
+static void artpec6_pcie_init_phy_a7(struct artpec6_pcie *artpec6_pcie)
+{
+ struct dw_pcie *pci = artpec6_pcie->pci;
+ u32 val;
+ bool extrefclk;
- retries = 50;
- do {
- usleep_range(1000, 2000);
- val = readl(artpec6_pcie->phy_base + PHY_STATUS);
- retries--;
- } while (retries && !(val & PHY_COSPLLLOCK));
+ /* Check if external reference clock is connected */
+ val = artpec6_pcie_readl(artpec6_pcie, PCIESTAT);
+ extrefclk = !!(val & PCIESTAT_EXTREFCLK);
+ dev_dbg(pci->dev, "Using reference clock: %s\n",
+ extrefclk ? "external" : "internal");
- /* Take DW core out of reset */
val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
- val &= ~PCIECFG_CORE_RESET_REQ;
+ val |= PCIECFG_RISRCREN | /* Receiver term. 50 Ohm */
+ PCIECFG_PCLK_ENABLE;
+ if (extrefclk)
+ val |= PCIECFG_REFCLKSEL;
+ else
+ val &= ~PCIECFG_REFCLKSEL;
artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
- usleep_range(100, 200);
+ usleep_range(10, 20);
- /* setup root complex */
- dw_pcie_setup_rc(pp);
+ val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
+ val |= NOCCFG_ENABLE_CLK_PCIE;
+ artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
+ usleep_range(20, 30);
+
+ val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
+ val &= ~NOCCFG_POWER_PCIE_IDLEREQ;
+ artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
+}
+
+static void artpec6_pcie_init_phy(struct artpec6_pcie *artpec6_pcie)
+{
+ switch (artpec6_pcie->variant) {
+ case ARTPEC6:
+ artpec6_pcie_init_phy_a6(artpec6_pcie);
+ break;
+ case ARTPEC7:
+ artpec6_pcie_init_phy_a7(artpec6_pcie);
+ break;
+ }
+}
+
+static void artpec6_pcie_set_nfts(struct artpec6_pcie *artpec6_pcie)
+{
+ struct dw_pcie *pci = artpec6_pcie->pci;
+ u32 val;
+
+ if (artpec6_pcie->variant != ARTPEC7)
+ return;
+
+ /*
+ * Increase the N_FTS (Number of Fast Training Sequences)
+ * to be transmitted when transitioning from L0s to L0.
+ */
+ val = dw_pcie_readl_dbi(pci, ACK_F_ASPM_CTRL_OFF);
+ val &= ~ACK_N_FTS_MASK;
+ val |= ACK_N_FTS(180);
+ dw_pcie_writel_dbi(pci, ACK_F_ASPM_CTRL_OFF, val);
+
+ /*
+ * Set the Number of Fast Training Sequences that the core
+ * advertises as its N_FTS during Gen2 or Gen3 link training.
+ */
+ val = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL);
+ val &= ~FAST_TRAINING_SEQ_MASK;
+ val |= FAST_TRAINING_SEQ(180);
+ dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, val);
+}
+
+static void artpec6_pcie_assert_core_reset(struct artpec6_pcie *artpec6_pcie)
+{
+ u32 val;
- /* assert LTSSM enable */
val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
- val |= PCIECFG_LTSSM_ENABLE;
+ switch (artpec6_pcie->variant) {
+ case ARTPEC6:
+ val |= PCIECFG_CORE_RESET_REQ;
+ break;
+ case ARTPEC7:
+ val &= ~PCIECFG_NOC_RESET;
+ break;
+ }
artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+}
- /* check if the link is up or not */
- if (!dw_pcie_wait_for_link(pci))
- return 0;
-
- dev_dbg(pci->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
- dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R0),
- dw_pcie_readl_dbi(pci, PCIE_PHY_DEBUG_R1));
+static void artpec6_pcie_deassert_core_reset(struct artpec6_pcie *artpec6_pcie)
+{
+ u32 val;
- return -ETIMEDOUT;
+ val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
+ switch (artpec6_pcie->variant) {
+ case ARTPEC6:
+ val &= ~PCIECFG_CORE_RESET_REQ;
+ break;
+ case ARTPEC7:
+ val |= PCIECFG_NOC_RESET;
+ break;
+ }
+ artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+ usleep_range(100, 200);
}
static void artpec6_pcie_enable_interrupts(struct artpec6_pcie *artpec6_pcie)
@@ -174,7 +366,14 @@ static int artpec6_pcie_host_init(struct pcie_port *pp)
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
- artpec6_pcie_establish_link(artpec6_pcie);
+ artpec6_pcie_assert_core_reset(artpec6_pcie);
+ artpec6_pcie_init_phy(artpec6_pcie);
+ artpec6_pcie_deassert_core_reset(artpec6_pcie);
+ artpec6_pcie_wait_for_phy(artpec6_pcie);
+ artpec6_pcie_set_nfts(artpec6_pcie);
+ dw_pcie_setup_rc(pp);
+ artpec6_pcie_establish_link(pci);
+ dw_pcie_wait_for_link(pci);
artpec6_pcie_enable_interrupts(artpec6_pcie);
return 0;
@@ -230,10 +429,78 @@ static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
return 0;
}
-static const struct dw_pcie_ops dw_pcie_ops = {
- .cpu_addr_fixup = artpec6_pcie_cpu_addr_fixup,
+static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
+ enum pci_barno bar;
+
+ artpec6_pcie_assert_core_reset(artpec6_pcie);
+ artpec6_pcie_init_phy(artpec6_pcie);
+ artpec6_pcie_deassert_core_reset(artpec6_pcie);
+ artpec6_pcie_wait_for_phy(artpec6_pcie);
+ artpec6_pcie_set_nfts(artpec6_pcie);
+
+ for (bar = BAR_0; bar <= BAR_5; bar++)
+ dw_pcie_ep_reset_bar(pci, bar);
+}
+
+static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
+ enum pci_epc_irq_type type, u8 interrupt_num)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+
+ switch (type) {
+ case PCI_EPC_IRQ_LEGACY:
+ dev_err(pci->dev, "EP cannot trigger legacy IRQs\n");
+ return -EINVAL;
+ case PCI_EPC_IRQ_MSI:
+ return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
+ default:
+ dev_err(pci->dev, "UNKNOWN IRQ type\n");
+ }
+
+ return 0;
+}
+
+static struct dw_pcie_ep_ops pcie_ep_ops = {
+ .ep_init = artpec6_pcie_ep_init,
+ .raise_irq = artpec6_pcie_raise_irq,
};
+static int artpec6_add_pcie_ep(struct artpec6_pcie *artpec6_pcie,
+ struct platform_device *pdev)
+{
+ int ret;
+ struct dw_pcie_ep *ep;
+ struct resource *res;
+ struct device *dev = &pdev->dev;
+ struct dw_pcie *pci = artpec6_pcie->pci;
+
+ ep = &pci->ep;
+ ep->ops = &pcie_ep_ops;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
+ pci->dbi_base2 = devm_ioremap(dev, res->start, resource_size(res));
+ if (!pci->dbi_base2)
+ return -ENOMEM;
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
+ if (!res)
+ return -EINVAL;
+
+ ep->phys_base = res->start;
+ ep->addr_size = resource_size(res);
+
+ ret = dw_pcie_ep_init(ep);
+ if (ret) {
+ dev_err(dev, "failed to initialize endpoint\n");
+ return ret;
+ }
+
+ return 0;
+}
+
static int artpec6_pcie_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -242,6 +509,18 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
struct resource *dbi_base;
struct resource *phy_base;
int ret;
+ const struct of_device_id *match;
+ const struct artpec_pcie_of_data *data;
+ enum artpec_pcie_variants variant;
+ enum dw_pcie_device_mode mode;
+
+ match = of_match_device(artpec6_pcie_of_match, dev);
+ if (!match)
+ return -EINVAL;
+
+ data = (struct artpec_pcie_of_data *)match->data;
+ variant = (enum artpec_pcie_variants)data->variant;
+ mode = (enum dw_pcie_device_mode)data->mode;
artpec6_pcie = devm_kzalloc(dev, sizeof(*artpec6_pcie), GFP_KERNEL);
if (!artpec6_pcie)
@@ -255,6 +534,8 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
pci->ops = &dw_pcie_ops;
artpec6_pcie->pci = pci;
+ artpec6_pcie->variant = variant;
+ artpec6_pcie->mode = mode;
dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
@@ -274,15 +555,73 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, artpec6_pcie);
- ret = artpec6_add_pcie_port(artpec6_pcie, pdev);
- if (ret < 0)
- return ret;
+ switch (artpec6_pcie->mode) {
+ case DW_PCIE_RC_TYPE:
+ if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST))
+ return -ENODEV;
+
+ ret = artpec6_add_pcie_port(artpec6_pcie, pdev);
+ if (ret < 0)
+ return ret;
+ break;
+ case DW_PCIE_EP_TYPE: {
+ u32 val;
+
+ if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP))
+ return -ENODEV;
+
+ val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
+ val &= ~PCIECFG_DEVICE_TYPE_MASK;
+ artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
+ ret = artpec6_add_pcie_ep(artpec6_pcie, pdev);
+ if (ret < 0)
+ return ret;
+ break;
+ }
+ default:
+ dev_err(dev, "INVALID device type %d\n", artpec6_pcie->mode);
+ }
return 0;
}
+static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data = {
+ .variant = ARTPEC6,
+ .mode = DW_PCIE_RC_TYPE,
+};
+
+static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data = {
+ .variant = ARTPEC6,
+ .mode = DW_PCIE_EP_TYPE,
+};
+
+static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data = {
+ .variant = ARTPEC7,
+ .mode = DW_PCIE_RC_TYPE,
+};
+
+static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data = {
+ .variant = ARTPEC7,
+ .mode = DW_PCIE_EP_TYPE,
+};
+
static const struct of_device_id artpec6_pcie_of_match[] = {
- { .compatible = "axis,artpec6-pcie", },
+ {
+ .compatible = "axis,artpec6-pcie",
+ .data = &artpec6_pcie_rc_of_data,
+ },
+ {
+ .compatible = "axis,artpec6-pcie-ep",
+ .data = &artpec6_pcie_ep_of_data,
+ },
+ {
+ .compatible = "axis,artpec7-pcie",
+ .data = &artpec7_pcie_rc_of_data,
+ },
+ {
+ .compatible = "axis,artpec7-pcie-ep",
+ .data = &artpec7_pcie_ep_of_data,
+ },
{},
};
diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c
index d53d5f168363..3a6feeff5f5b 100644
--- a/drivers/pci/dwc/pcie-designware-ep.c
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/**
* Synopsys DesignWare PCIe Endpoint controller driver
*
* Copyright (C) 2017 Texas Instruments
* Author: Kishon Vijay Abraham I <kishon@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/of.h>
@@ -30,21 +19,24 @@ void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
pci_epc_linkup(epc);
}
-static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
+void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
{
u32 reg;
reg = PCI_BASE_ADDRESS_0 + (4 * bar);
+ dw_pcie_dbi_ro_wr_en(pci);
dw_pcie_writel_dbi2(pci, reg, 0x0);
dw_pcie_writel_dbi(pci, reg, 0x0);
+ dw_pcie_dbi_ro_wr_dis(pci);
}
-static int dw_pcie_ep_write_header(struct pci_epc *epc,
+static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no,
struct pci_epf_header *hdr)
{
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ dw_pcie_dbi_ro_wr_en(pci);
dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, hdr->vendorid);
dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, hdr->deviceid);
dw_pcie_writeb_dbi(pci, PCI_REVISION_ID, hdr->revid);
@@ -58,6 +50,7 @@ static int dw_pcie_ep_write_header(struct pci_epc *epc,
dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_ID, hdr->subsys_id);
dw_pcie_writeb_dbi(pci, PCI_INTERRUPT_PIN,
hdr->interrupt_pin);
+ dw_pcie_dbi_ro_wr_dis(pci);
return 0;
}
@@ -70,8 +63,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
u32 free_win;
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
- free_win = find_first_zero_bit(&ep->ib_window_map,
- sizeof(ep->ib_window_map));
+ free_win = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows);
if (free_win >= ep->num_ib_windows) {
dev_err(pci->dev, "no free inbound window\n");
return -EINVAL;
@@ -85,7 +77,7 @@ static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
}
ep->bar_to_atu[bar] = free_win;
- set_bit(free_win, &ep->ib_window_map);
+ set_bit(free_win, ep->ib_window_map);
return 0;
}
@@ -96,8 +88,7 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
u32 free_win;
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
- free_win = find_first_zero_bit(&ep->ob_window_map,
- sizeof(ep->ob_window_map));
+ free_win = find_first_zero_bit(ep->ob_window_map, ep->num_ob_windows);
if (free_win >= ep->num_ob_windows) {
dev_err(pci->dev, "no free outbound window\n");
return -EINVAL;
@@ -106,13 +97,14 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
phys_addr, pci_addr, size);
- set_bit(free_win, &ep->ob_window_map);
+ set_bit(free_win, ep->ob_window_map);
ep->outbound_addr[free_win] = phys_addr;
return 0;
}
-static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar)
+static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no,
+ enum pci_barno bar)
{
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -121,10 +113,11 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar)
dw_pcie_ep_reset_bar(pci, bar);
dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
- clear_bit(atu_index, &ep->ib_window_map);
+ clear_bit(atu_index, ep->ib_window_map);
}
-static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar,
+static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
+ enum pci_barno bar,
dma_addr_t bar_phys, size_t size, int flags)
{
int ret;
@@ -142,8 +135,10 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar,
if (ret)
return ret;
+ dw_pcie_dbi_ro_wr_en(pci);
dw_pcie_writel_dbi2(pci, reg, size - 1);
dw_pcie_writel_dbi(pci, reg, flags);
+ dw_pcie_dbi_ro_wr_dis(pci);
return 0;
}
@@ -163,7 +158,8 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
return -EINVAL;
}
-static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr)
+static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no,
+ phys_addr_t addr)
{
int ret;
u32 atu_index;
@@ -175,10 +171,11 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr)
return;
dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND);
- clear_bit(atu_index, &ep->ob_window_map);
+ clear_bit(atu_index, ep->ob_window_map);
}
-static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr,
+static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no,
+ phys_addr_t addr,
u64 pci_addr, size_t size)
{
int ret;
@@ -194,39 +191,37 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr,
return 0;
}
-static int dw_pcie_ep_get_msi(struct pci_epc *epc)
+static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no)
{
int val;
- u32 lower_addr;
- u32 upper_addr;
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
- val = dw_pcie_readb_dbi(pci, MSI_MESSAGE_CONTROL);
- val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
-
- lower_addr = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
- upper_addr = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
-
- if (!(lower_addr || upper_addr))
+ val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
+ if (!(val & MSI_CAP_MSI_EN_MASK))
return -EINVAL;
+ val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
return val;
}
-static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int)
+static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int)
{
int val;
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
- val = (encode_int << MSI_CAP_MMC_SHIFT);
+ val = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
+ val &= ~MSI_CAP_MMC_MASK;
+ val |= (encode_int << MSI_CAP_MMC_SHIFT) & MSI_CAP_MMC_MASK;
+ dw_pcie_dbi_ro_wr_en(pci);
dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val);
+ dw_pcie_dbi_ro_wr_dis(pci);
return 0;
}
-static int dw_pcie_ep_raise_irq(struct pci_epc *epc,
+static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no,
enum pci_epc_irq_type type, u8 interrupt_num)
{
struct dw_pcie_ep *ep = epc_get_drvdata(epc);
@@ -234,7 +229,7 @@ static int dw_pcie_ep_raise_irq(struct pci_epc *epc,
if (!ep->ops->raise_irq)
return -EINVAL;
- return ep->ops->raise_irq(ep, type, interrupt_num);
+ return ep->ops->raise_irq(ep, func_no, type, interrupt_num);
}
static void dw_pcie_ep_stop(struct pci_epc *epc)
@@ -272,10 +267,48 @@ static const struct pci_epc_ops epc_ops = {
.stop = dw_pcie_ep_stop,
};
+int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
+ u8 interrupt_num)
+{
+ struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+ struct pci_epc *epc = ep->epc;
+ u16 msg_ctrl, msg_data;
+ u32 msg_addr_lower, msg_addr_upper;
+ u64 msg_addr;
+ bool has_upper;
+ int ret;
+
+ /* Raise MSI per the PCI Local Bus Specification Revision 3.0, 6.8.1. */
+ msg_ctrl = dw_pcie_readw_dbi(pci, MSI_MESSAGE_CONTROL);
+ has_upper = !!(msg_ctrl & PCI_MSI_FLAGS_64BIT);
+ msg_addr_lower = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
+ if (has_upper) {
+ msg_addr_upper = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
+ msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_64);
+ } else {
+ msg_addr_upper = 0;
+ msg_data = dw_pcie_readw_dbi(pci, MSI_MESSAGE_DATA_32);
+ }
+ msg_addr = ((u64) msg_addr_upper) << 32 | msg_addr_lower;
+ ret = dw_pcie_ep_map_addr(epc, func_no, ep->msi_mem_phys, msg_addr,
+ epc->mem->page_size);
+ if (ret)
+ return ret;
+
+ writel(msg_data | (interrupt_num - 1), ep->msi_mem);
+
+ dw_pcie_ep_unmap_addr(epc, func_no, ep->msi_mem_phys);
+
+ return 0;
+}
+
void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
{
struct pci_epc *epc = ep->epc;
+ pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
+ epc->mem->page_size);
+
pci_epc_mem_exit(epc);
}
@@ -298,12 +331,32 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
dev_err(dev, "unable to read *num-ib-windows* property\n");
return ret;
}
+ if (ep->num_ib_windows > MAX_IATU_IN) {
+ dev_err(dev, "invalid *num-ib-windows*\n");
+ return -EINVAL;
+ }
ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows);
if (ret < 0) {
dev_err(dev, "unable to read *num-ob-windows* property\n");
return ret;
}
+ if (ep->num_ob_windows > MAX_IATU_OUT) {
+ dev_err(dev, "invalid *num-ob-windows*\n");
+ return -EINVAL;
+ }
+
+ ep->ib_window_map = devm_kzalloc(dev, sizeof(long) *
+ BITS_TO_LONGS(ep->num_ib_windows),
+ GFP_KERNEL);
+ if (!ep->ib_window_map)
+ return -ENOMEM;
+
+ ep->ob_window_map = devm_kzalloc(dev, sizeof(long) *
+ BITS_TO_LONGS(ep->num_ob_windows),
+ GFP_KERNEL);
+ if (!ep->ob_window_map)
+ return -ENOMEM;
addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows,
GFP_KERNEL);
@@ -331,6 +384,13 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
return ret;
}
+ ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
+ epc->mem->page_size);
+ if (!ep->msi_mem) {
+ dev_err(dev, "Failed to reserve memory for MSI\n");
+ return -ENOMEM;
+ }
+
ep->epc = epc;
epc_set_drvdata(epc, ep);
dw_pcie_setup(pci);
diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c
index 81e2157a7cfb..8de2d5c69b1d 100644
--- a/drivers/pci/dwc/pcie-designware-host.c
+++ b/drivers/pci/dwc/pcie-designware-host.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Synopsys DesignWare PCIe host controller driver
*
@@ -5,10 +6,6 @@
* http://www.samsung.com
*
* Author: Jingoo Han <jg1.han@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/irqdomain.h>
@@ -83,10 +80,19 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
void dw_pcie_msi_init(struct pcie_port *pp)
{
+ struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+ struct device *dev = pci->dev;
+ struct page *page;
u64 msi_target;
- pp->msi_data = __get_free_pages(GFP_KERNEL, 0);
- msi_target = virt_to_phys((void *)pp->msi_data);
+ page = alloc_page(GFP_KERNEL);
+ pp->msi_data = dma_map_page(dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(dev, pp->msi_data)) {
+ dev_err(dev, "failed to map MSI data\n");
+ __free_page(page);
+ return;
+ }
+ msi_target = (u64)pp->msi_data;
/* program the msi_data */
dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4,
@@ -187,7 +193,7 @@ static void dw_msi_setup_msg(struct pcie_port *pp, unsigned int irq, u32 pos)
if (pp->ops->get_msi_addr)
msi_target = pp->ops->get_msi_addr(pp);
else
- msi_target = virt_to_phys((void *)pp->msi_data);
+ msi_target = (u64)pp->msi_data;
msg.address_lo = (u32)(msi_target & 0xffffffff);
msg.address_hi = (u32)(msi_target >> 32 & 0xffffffff);
diff --git a/drivers/pci/dwc/pcie-designware-plat.c b/drivers/pci/dwc/pcie-designware-plat.c
index 168e2380f493..ebdf28bcd67d 100644
--- a/drivers/pci/dwc/pcie-designware-plat.c
+++ b/drivers/pci/dwc/pcie-designware-plat.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe RC driver for Synopsys DesignWare Core
*
* Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com)
*
* Authors: Joao Pinto <Joao.Pinto@synopsys.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/delay.h>
diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c
index 88abdddee2ad..1b7282e5b494 100644
--- a/drivers/pci/dwc/pcie-designware.c
+++ b/drivers/pci/dwc/pcie-designware.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Synopsys DesignWare PCIe host controller driver
*
@@ -5,10 +6,6 @@
* http://www.samsung.com
*
* Author: Jingoo Han <jg1.han@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/delay.h>
@@ -149,7 +146,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
u32 retries, val;
if (pci->ops->cpu_addr_fixup)
- cpu_addr = pci->ops->cpu_addr_fixup(cpu_addr);
+ cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr);
if (pci->iatu_unroll_enabled) {
dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr,
diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h
index e5d9d77b778e..11b13864a406 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Synopsys DesignWare PCIe host controller driver
*
@@ -5,15 +6,12 @@
* http://www.samsung.com
*
* Author: Jingoo Han <jg1.han@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 _PCIE_DESIGNWARE_H
#define _PCIE_DESIGNWARE_H
+#include <linux/dma-mapping.h>
#include <linux/irq.h>
#include <linux/msi.h>
#include <linux/pci.h>
@@ -100,10 +98,14 @@
#define MSI_MESSAGE_CONTROL 0x52
#define MSI_CAP_MMC_SHIFT 1
+#define MSI_CAP_MMC_MASK (7 << MSI_CAP_MMC_SHIFT)
#define MSI_CAP_MME_SHIFT 4
+#define MSI_CAP_MSI_EN_MASK 0x1
#define MSI_CAP_MME_MASK (7 << MSI_CAP_MME_SHIFT)
#define MSI_MESSAGE_ADDR_L32 0x54
#define MSI_MESSAGE_ADDR_U32 0x58
+#define MSI_MESSAGE_DATA_32 0x58
+#define MSI_MESSAGE_DATA_64 0x5C
/*
* Maximum number of MSI IRQs can be 256 per controller. But keep
@@ -113,6 +115,10 @@
#define MAX_MSI_IRQS 32
#define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32)
+/* Maximum number of inbound/outbound iATUs */
+#define MAX_IATU_IN 256
+#define MAX_IATU_OUT 256
+
struct pcie_port;
struct dw_pcie;
struct dw_pcie_ep;
@@ -168,7 +174,7 @@ struct pcie_port {
const struct dw_pcie_host_ops *ops;
int msi_irq;
struct irq_domain *irq_domain;
- unsigned long msi_data;
+ dma_addr_t msi_data;
DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
};
@@ -180,8 +186,8 @@ enum dw_pcie_as_type {
struct dw_pcie_ep_ops {
void (*ep_init)(struct dw_pcie_ep *ep);
- int (*raise_irq)(struct dw_pcie_ep *ep, enum pci_epc_irq_type type,
- u8 interrupt_num);
+ int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no,
+ enum pci_epc_irq_type type, u8 interrupt_num);
};
struct dw_pcie_ep {
@@ -192,14 +198,16 @@ struct dw_pcie_ep {
size_t page_size;
u8 bar_to_atu[6];
phys_addr_t *outbound_addr;
- unsigned long ib_window_map;
- unsigned long ob_window_map;
+ unsigned long *ib_window_map;
+ unsigned long *ob_window_map;
u32 num_ib_windows;
u32 num_ob_windows;
+ void __iomem *msi_mem;
+ phys_addr_t msi_mem_phys;
};
struct dw_pcie_ops {
- u64 (*cpu_addr_fixup)(u64 cpu_addr);
+ u64 (*cpu_addr_fixup)(struct dw_pcie *pcie, u64 cpu_addr);
u32 (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
size_t size);
void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
@@ -334,6 +342,9 @@ static inline int dw_pcie_host_init(struct pcie_port *pp)
void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
int dw_pcie_ep_init(struct dw_pcie_ep *ep);
void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
+int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
+ u8 interrupt_num);
+void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar);
#else
static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
{
@@ -347,5 +358,15 @@ static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep)
static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
{
}
+
+static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
+ u8 interrupt_num)
+{
+ return 0;
+}
+
+static inline void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
+{
+}
#endif
#endif /* _PCIE_DESIGNWARE_H */
diff --git a/drivers/pci/dwc/pcie-hisi.c b/drivers/pci/dwc/pcie-hisi.c
index a20179169e06..2658aaebb993 100644
--- a/drivers/pci/dwc/pcie-hisi.c
+++ b/drivers/pci/dwc/pcie-hisi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for HiSilicon SoCs
*
@@ -6,10 +7,6 @@
* Authors: Zhou Wang <wangzhou1@hisilicon.com>
* Dacai Zhu <zhudacai@hisilicon.com>
* Gabriele Paoloni <gabriele.paoloni@huawei.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/interrupt.h>
#include <linux/init.h>
diff --git a/drivers/pci/dwc/pcie-histb.c b/drivers/pci/dwc/pcie-histb.c
index 33b01b734d7d..70b5c0b108bf 100644
--- a/drivers/pci/dwc/pcie-histb.c
+++ b/drivers/pci/dwc/pcie-histb.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for HiSilicon STB SoCs
*
@@ -5,10 +6,6 @@
*
* Authors: Ruqiang Ju <juruqiang@hisilicon.com>
* Jianguo Sun <sunjianguo1@huawei.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#include <linux/clk.h>
diff --git a/drivers/pci/dwc/pcie-kirin.c b/drivers/pci/dwc/pcie-kirin.c
index dc3033cf3c19..13d839bd6160 100644
--- a/drivers/pci/dwc/pcie-kirin.c
+++ b/drivers/pci/dwc/pcie-kirin.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for Kirin Phone SoCs
*
@@ -5,10 +6,6 @@
* http://www.huawei.com
*
* Author: Xiaowei Song <songxiaowei@huawei.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 <asm/compiler.h>
diff --git a/drivers/pci/dwc/pcie-qcom.c b/drivers/pci/dwc/pcie-qcom.c
index ce7ba5b7552a..6310c66e265c 100644
--- a/drivers/pci/dwc/pcie-qcom.c
+++ b/drivers/pci/dwc/pcie-qcom.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Qualcomm PCIe root complex driver
*
@@ -5,15 +6,6 @@
* Copyright 2015 Linaro Limited.
*
* Author: Stanimir Varbanov <svarbanov@mm-sol.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 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/clk.h>
@@ -171,7 +163,7 @@ struct qcom_pcie {
union qcom_pcie_resources res;
struct phy *phy;
struct gpio_desc *reset;
- struct qcom_pcie_ops *ops;
+ const struct qcom_pcie_ops *ops;
};
#define to_qcom_pcie(x) dev_get_drvdata((x)->dev)
@@ -1234,7 +1226,7 @@ static int qcom_pcie_probe(struct platform_device *pdev)
pcie->pci = pci;
- pcie->ops = (struct qcom_pcie_ops *)of_device_get_match_data(dev);
+ pcie->ops = of_device_get_match_data(dev);
pcie->reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_LOW);
if (IS_ERR(pcie->reset))
diff --git a/drivers/pci/dwc/pcie-spear13xx.c b/drivers/pci/dwc/pcie-spear13xx.c
index 709189d23b31..ecb58f7b7566 100644
--- a/drivers/pci/dwc/pcie-spear13xx.c
+++ b/drivers/pci/dwc/pcie-spear13xx.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe host controller driver for ST Microelectronics SPEAr13xx SoCs
*
@@ -6,10 +7,6 @@
* Copyright (C) 2010-2014 ST Microelectronics
* Pratyush Anand <pratyush.anand@gmail.com>
* Mohit Kumar <mohit.kumar.dhaka@gmail.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#include <linux/clk.h>
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
index c228a2eb7faa..1a81af0ba961 100644
--- a/drivers/pci/ecam.c
+++ b/drivers/pci/ecam.c
@@ -1,17 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2016 Broadcom
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation (the "GPL").
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 (GPLv2) for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 (GPLv2) along with this source code.
*/
#include <linux/device.h>
diff --git a/drivers/pci/endpoint/Kconfig b/drivers/pci/endpoint/Kconfig
index c09623ca8c3b..d1e7e4199432 100644
--- a/drivers/pci/endpoint/Kconfig
+++ b/drivers/pci/endpoint/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# PCI Endpoint Support
#
diff --git a/drivers/pci/endpoint/Makefile b/drivers/pci/endpoint/Makefile
index 1041f80a4645..95b2fe47e3b0 100644
--- a/drivers/pci/endpoint/Makefile
+++ b/drivers/pci/endpoint/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for PCI Endpoint Support
#
diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig
index 2942066607e0..8820d0f7ec77 100644
--- a/drivers/pci/endpoint/functions/Kconfig
+++ b/drivers/pci/endpoint/functions/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# PCI Endpoint Functions
#
diff --git a/drivers/pci/endpoint/functions/Makefile b/drivers/pci/endpoint/functions/Makefile
index 6d94a4801838..d6fafff080e2 100644
--- a/drivers/pci/endpoint/functions/Makefile
+++ b/drivers/pci/endpoint/functions/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for PCI Endpoint Functions
#
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
index f9308c2f22e6..64d8a17f8094 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/**
* Test driver to test endpoint functionality
*
* Copyright (C) 2017 Texas Instruments
* Author: Kishon Vijay Abraham I <kishon@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/crc32.h>
@@ -104,7 +93,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
goto err;
}
- ret = pci_epc_map_addr(epc, src_phys_addr, reg->src_addr, reg->size);
+ ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr,
+ reg->size);
if (ret) {
dev_err(dev, "failed to map source address\n");
reg->status = STATUS_SRC_ADDR_INVALID;
@@ -119,7 +109,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
goto err_src_map_addr;
}
- ret = pci_epc_map_addr(epc, dst_phys_addr, reg->dst_addr, reg->size);
+ ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr,
+ reg->size);
if (ret) {
dev_err(dev, "failed to map destination address\n");
reg->status = STATUS_DST_ADDR_INVALID;
@@ -128,13 +119,13 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test)
memcpy(dst_addr, src_addr, reg->size);
- pci_epc_unmap_addr(epc, dst_phys_addr);
+ pci_epc_unmap_addr(epc, epf->func_no, dst_phys_addr);
err_dst_addr:
pci_epc_mem_free_addr(epc, dst_phys_addr, dst_addr, reg->size);
err_src_map_addr:
- pci_epc_unmap_addr(epc, src_phys_addr);
+ pci_epc_unmap_addr(epc, epf->func_no, src_phys_addr);
err_src_addr:
pci_epc_mem_free_addr(epc, src_phys_addr, src_addr, reg->size);
@@ -164,7 +155,8 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
goto err;
}
- ret = pci_epc_map_addr(epc, phys_addr, reg->src_addr, reg->size);
+ ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->src_addr,
+ reg->size);
if (ret) {
dev_err(dev, "failed to map address\n");
reg->status = STATUS_SRC_ADDR_INVALID;
@@ -186,7 +178,7 @@ static int pci_epf_test_read(struct pci_epf_test *epf_test)
kfree(buf);
err_map_addr:
- pci_epc_unmap_addr(epc, phys_addr);
+ pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
err_addr:
pci_epc_mem_free_addr(epc, phys_addr, src_addr, reg->size);
@@ -215,7 +207,8 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
goto err;
}
- ret = pci_epc_map_addr(epc, phys_addr, reg->dst_addr, reg->size);
+ ret = pci_epc_map_addr(epc, epf->func_no, phys_addr, reg->dst_addr,
+ reg->size);
if (ret) {
dev_err(dev, "failed to map address\n");
reg->status = STATUS_DST_ADDR_INVALID;
@@ -242,7 +235,7 @@ static int pci_epf_test_write(struct pci_epf_test *epf_test)
kfree(buf);
err_map_addr:
- pci_epc_unmap_addr(epc, phys_addr);
+ pci_epc_unmap_addr(epc, epf->func_no, phys_addr);
err_addr:
pci_epc_mem_free_addr(epc, phys_addr, dst_addr, reg->size);
@@ -260,11 +253,11 @@ static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test, u8 irq)
struct pci_epf_test_reg *reg = epf_test->reg[test_reg_bar];
reg->status |= STATUS_IRQ_RAISED;
- msi_count = pci_epc_get_msi(epc);
+ msi_count = pci_epc_get_msi(epc, epf->func_no);
if (irq > msi_count || msi_count <= 0)
- pci_epc_raise_irq(epc, PCI_EPC_IRQ_LEGACY, 0);
+ pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
else
- pci_epc_raise_irq(epc, PCI_EPC_IRQ_MSI, irq);
+ pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
}
static void pci_epf_test_cmd_handler(struct work_struct *work)
@@ -291,7 +284,7 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
if (command & COMMAND_RAISE_LEGACY_IRQ) {
reg->status = STATUS_IRQ_RAISED;
- pci_epc_raise_irq(epc, PCI_EPC_IRQ_LEGACY, 0);
+ pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_LEGACY, 0);
goto reset_handler;
}
@@ -326,11 +319,11 @@ static void pci_epf_test_cmd_handler(struct work_struct *work)
}
if (command & COMMAND_RAISE_MSI_IRQ) {
- msi_count = pci_epc_get_msi(epc);
+ msi_count = pci_epc_get_msi(epc, epf->func_no);
if (irq > msi_count || msi_count <= 0)
goto reset_handler;
reg->status = STATUS_IRQ_RAISED;
- pci_epc_raise_irq(epc, PCI_EPC_IRQ_MSI, irq);
+ pci_epc_raise_irq(epc, epf->func_no, PCI_EPC_IRQ_MSI, irq);
goto reset_handler;
}
@@ -358,7 +351,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
for (bar = BAR_0; bar <= BAR_5; bar++) {
if (epf_test->reg[bar]) {
pci_epf_free_space(epf, epf_test->reg[bar], bar);
- pci_epc_clear_bar(epc, bar);
+ pci_epc_clear_bar(epc, epf->func_no, bar);
}
}
}
@@ -380,7 +373,8 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
for (bar = BAR_0; bar <= BAR_5; bar++) {
epf_bar = &epf->bar[bar];
- ret = pci_epc_set_bar(epc, bar, epf_bar->phys_addr,
+ ret = pci_epc_set_bar(epc, epf->func_no, bar,
+ epf_bar->phys_addr,
epf_bar->size, flags);
if (ret) {
pci_epf_free_space(epf, epf_test->reg[bar], bar);
@@ -433,7 +427,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
if (WARN_ON_ONCE(!epc))
return -EINVAL;
- ret = pci_epc_write_header(epc, header);
+ ret = pci_epc_write_header(epc, epf->func_no, header);
if (ret) {
dev_err(dev, "configuration header write failed\n");
return ret;
@@ -447,7 +441,7 @@ static int pci_epf_test_bind(struct pci_epf *epf)
if (ret)
return ret;
- ret = pci_epc_set_msi(epc, epf->msi_interrupts);
+ ret = pci_epc_set_msi(epc, epf->func_no, epf->msi_interrupts);
if (ret)
return ret;
diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c
index 4f74386c1ced..018ea3433cb5 100644
--- a/drivers/pci/endpoint/pci-ep-cfs.c
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -1,35 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
/**
* configfs to configure the PCI endpoint
*
* Copyright (C) 2017 Texas Instruments
* Author: Kishon Vijay Abraham I <kishon@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/module.h>
+#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/pci-epc.h>
#include <linux/pci-epf.h>
#include <linux/pci-ep-cfs.h>
+static DEFINE_IDR(functions_idr);
+static DEFINE_MUTEX(functions_mutex);
static struct config_group *functions_group;
static struct config_group *controllers_group;
struct pci_epf_group {
struct config_group group;
struct pci_epf *epf;
+ int index;
};
struct pci_epc_group {
@@ -97,22 +90,23 @@ static int pci_epc_epf_link(struct config_item *epc_item,
{
int ret;
u32 func_no = 0;
- struct pci_epc *epc;
- struct pci_epf *epf;
struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
-
- epc = epc_group->epc;
- epf = epf_group->epf;
- ret = pci_epc_add_epf(epc, epf);
- if (ret)
- goto err_add_epf;
+ struct pci_epc *epc = epc_group->epc;
+ struct pci_epf *epf = epf_group->epf;
func_no = find_first_zero_bit(&epc_group->function_num_map,
- sizeof(epc_group->function_num_map));
+ BITS_PER_LONG);
+ if (func_no >= BITS_PER_LONG)
+ return -EINVAL;
+
set_bit(func_no, &epc_group->function_num_map);
epf->func_no = func_no;
+ ret = pci_epc_add_epf(epc, epf);
+ if (ret)
+ goto err_add_epf;
+
ret = pci_epf_bind(epf);
if (ret)
goto err_epf_bind;
@@ -353,6 +347,9 @@ static void pci_epf_release(struct config_item *item)
{
struct pci_epf_group *epf_group = to_pci_epf_group(item);
+ mutex_lock(&functions_mutex);
+ idr_remove(&functions_idr, epf_group->index);
+ mutex_unlock(&functions_mutex);
pci_epf_destroy(epf_group->epf);
kfree(epf_group);
}
@@ -372,22 +369,57 @@ static struct config_group *pci_epf_make(struct config_group *group,
{
struct pci_epf_group *epf_group;
struct pci_epf *epf;
+ char *epf_name;
+ int index, err;
epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
if (!epf_group)
return ERR_PTR(-ENOMEM);
+ mutex_lock(&functions_mutex);
+ index = idr_alloc(&functions_idr, epf_group, 0, 0, GFP_KERNEL);
+ mutex_unlock(&functions_mutex);
+ if (index < 0) {
+ err = index;
+ goto free_group;
+ }
+
+ epf_group->index = index;
+
config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
- epf = pci_epf_create(group->cg_item.ci_name);
+ epf_name = kasprintf(GFP_KERNEL, "%s.%d",
+ group->cg_item.ci_name, epf_group->index);
+ if (!epf_name) {
+ err = -ENOMEM;
+ goto remove_idr;
+ }
+
+ epf = pci_epf_create(epf_name);
if (IS_ERR(epf)) {
pr_err("failed to create endpoint function device\n");
- return ERR_PTR(-EINVAL);
+ err = -EINVAL;
+ goto free_name;
}
epf_group->epf = epf;
+ kfree(epf_name);
+
return &epf_group->group;
+
+free_name:
+ kfree(epf_name);
+
+remove_idr:
+ mutex_lock(&functions_mutex);
+ idr_remove(&functions_idr, epf_group->index);
+ mutex_unlock(&functions_mutex);
+
+free_group:
+ kfree(epf_group);
+
+ return ERR_PTR(err);
}
static void pci_epf_drop(struct config_group *group, struct config_item *item)
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 42c2a1156325..e245bba0ab53 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -1,24 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
/**
* PCI Endpoint *Controller* (EPC) library
*
* Copyright (C) 2017 Texas Instruments
* Author: Kishon Vijay Abraham I <kishon@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/device.h>
-#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/of_device.h>
@@ -142,25 +130,26 @@ EXPORT_SYMBOL_GPL(pci_epc_start);
/**
* pci_epc_raise_irq() - interrupt the host system
* @epc: the EPC device which has to interrupt the host
+ * @func_no: the endpoint function number in the EPC device
* @type: specify the type of interrupt; legacy or MSI
* @interrupt_num: the MSI interrupt number
*
* Invoke to raise an MSI or legacy interrupt
*/
-int pci_epc_raise_irq(struct pci_epc *epc, enum pci_epc_irq_type type,
- u8 interrupt_num)
+int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+ enum pci_epc_irq_type type, u8 interrupt_num)
{
int ret;
unsigned long flags;
- if (IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
return -EINVAL;
if (!epc->ops->raise_irq)
return 0;
spin_lock_irqsave(&epc->lock, flags);
- ret = epc->ops->raise_irq(epc, type, interrupt_num);
+ ret = epc->ops->raise_irq(epc, func_no, type, interrupt_num);
spin_unlock_irqrestore(&epc->lock, flags);
return ret;
@@ -170,22 +159,23 @@ EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
/**
* pci_epc_get_msi() - get the number of MSI interrupt numbers allocated
* @epc: the EPC device to which MSI interrupts was requested
+ * @func_no: the endpoint function number in the EPC device
*
* Invoke to get the number of MSI interrupts allocated by the RC
*/
-int pci_epc_get_msi(struct pci_epc *epc)
+int pci_epc_get_msi(struct pci_epc *epc, u8 func_no)
{
int interrupt;
unsigned long flags;
- if (IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
return 0;
if (!epc->ops->get_msi)
return 0;
spin_lock_irqsave(&epc->lock, flags);
- interrupt = epc->ops->get_msi(epc);
+ interrupt = epc->ops->get_msi(epc, func_no);
spin_unlock_irqrestore(&epc->lock, flags);
if (interrupt < 0)
@@ -200,17 +190,18 @@ EXPORT_SYMBOL_GPL(pci_epc_get_msi);
/**
* pci_epc_set_msi() - set the number of MSI interrupt numbers required
* @epc: the EPC device on which MSI has to be configured
+ * @func_no: the endpoint function number in the EPC device
* @interrupts: number of MSI interrupts required by the EPF
*
* Invoke to set the required number of MSI interrupts.
*/
-int pci_epc_set_msi(struct pci_epc *epc, u8 interrupts)
+int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts)
{
int ret;
u8 encode_int;
unsigned long flags;
- if (IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
return -EINVAL;
if (!epc->ops->set_msi)
@@ -219,7 +210,7 @@ int pci_epc_set_msi(struct pci_epc *epc, u8 interrupts)
encode_int = order_base_2(interrupts);
spin_lock_irqsave(&epc->lock, flags);
- ret = epc->ops->set_msi(epc, encode_int);
+ ret = epc->ops->set_msi(epc, func_no, encode_int);
spin_unlock_irqrestore(&epc->lock, flags);
return ret;
@@ -229,22 +220,24 @@ EXPORT_SYMBOL_GPL(pci_epc_set_msi);
/**
* pci_epc_unmap_addr() - unmap CPU address from PCI address
* @epc: the EPC device on which address is allocated
+ * @func_no: the endpoint function number in the EPC device
* @phys_addr: physical address of the local system
*
* Invoke to unmap the CPU address from PCI address.
*/
-void pci_epc_unmap_addr(struct pci_epc *epc, phys_addr_t phys_addr)
+void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
+ phys_addr_t phys_addr)
{
unsigned long flags;
- if (IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
return;
if (!epc->ops->unmap_addr)
return;
spin_lock_irqsave(&epc->lock, flags);
- epc->ops->unmap_addr(epc, phys_addr);
+ epc->ops->unmap_addr(epc, func_no, phys_addr);
spin_unlock_irqrestore(&epc->lock, flags);
}
EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
@@ -252,26 +245,27 @@ EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
/**
* pci_epc_map_addr() - map CPU address to PCI address
* @epc: the EPC device on which address is allocated
+ * @func_no: the endpoint function number in the EPC device
* @phys_addr: physical address of the local system
* @pci_addr: PCI address to which the physical address should be mapped
* @size: the size of the allocation
*
* Invoke to map CPU address with PCI address.
*/
-int pci_epc_map_addr(struct pci_epc *epc, phys_addr_t phys_addr,
- u64 pci_addr, size_t size)
+int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
+ phys_addr_t phys_addr, u64 pci_addr, size_t size)
{
int ret;
unsigned long flags;
- if (IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
return -EINVAL;
if (!epc->ops->map_addr)
return 0;
spin_lock_irqsave(&epc->lock, flags);
- ret = epc->ops->map_addr(epc, phys_addr, pci_addr, size);
+ ret = epc->ops->map_addr(epc, func_no, phys_addr, pci_addr, size);
spin_unlock_irqrestore(&epc->lock, flags);
return ret;
@@ -281,22 +275,23 @@ EXPORT_SYMBOL_GPL(pci_epc_map_addr);
/**
* pci_epc_clear_bar() - reset the BAR
* @epc: the EPC device for which the BAR has to be cleared
+ * @func_no: the endpoint function number in the EPC device
* @bar: the BAR number that has to be reset
*
* Invoke to reset the BAR of the endpoint device.
*/
-void pci_epc_clear_bar(struct pci_epc *epc, int bar)
+void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, int bar)
{
unsigned long flags;
- if (IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
return;
if (!epc->ops->clear_bar)
return;
spin_lock_irqsave(&epc->lock, flags);
- epc->ops->clear_bar(epc, bar);
+ epc->ops->clear_bar(epc, func_no, bar);
spin_unlock_irqrestore(&epc->lock, flags);
}
EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
@@ -304,26 +299,27 @@ EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
/**
* pci_epc_set_bar() - configure BAR in order for host to assign PCI addr space
* @epc: the EPC device on which BAR has to be configured
+ * @func_no: the endpoint function number in the EPC device
* @bar: the BAR number that has to be configured
* @size: the size of the addr space
* @flags: specify memory allocation/io allocation/32bit address/64 bit address
*
* Invoke to configure the BAR of the endpoint device.
*/
-int pci_epc_set_bar(struct pci_epc *epc, enum pci_barno bar,
+int pci_epc_set_bar(struct pci_epc *epc, u8 func_no, enum pci_barno bar,
dma_addr_t bar_phys, size_t size, int flags)
{
int ret;
unsigned long irq_flags;
- if (IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
return -EINVAL;
if (!epc->ops->set_bar)
return 0;
spin_lock_irqsave(&epc->lock, irq_flags);
- ret = epc->ops->set_bar(epc, bar, bar_phys, size, flags);
+ ret = epc->ops->set_bar(epc, func_no, bar, bar_phys, size, flags);
spin_unlock_irqrestore(&epc->lock, irq_flags);
return ret;
@@ -333,6 +329,7 @@ EXPORT_SYMBOL_GPL(pci_epc_set_bar);
/**
* pci_epc_write_header() - write standard configuration header
* @epc: the EPC device to which the configuration header should be written
+ * @func_no: the endpoint function number in the EPC device
* @header: standard configuration header fields
*
* Invoke to write the configuration header to the endpoint controller. Every
@@ -340,19 +337,20 @@ EXPORT_SYMBOL_GPL(pci_epc_set_bar);
* configuration header would be written. The callback function should write
* the header fields to this dedicated location.
*/
-int pci_epc_write_header(struct pci_epc *epc, struct pci_epf_header *header)
+int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
+ struct pci_epf_header *header)
{
int ret;
unsigned long flags;
- if (IS_ERR(epc))
+ if (IS_ERR_OR_NULL(epc) || func_no >= epc->max_functions)
return -EINVAL;
if (!epc->ops->write_header)
return 0;
spin_lock_irqsave(&epc->lock, flags);
- ret = epc->ops->write_header(epc, header);
+ ret = epc->ops->write_header(epc, func_no, header);
spin_unlock_irqrestore(&epc->lock, flags);
return ret;
@@ -371,7 +369,6 @@ EXPORT_SYMBOL_GPL(pci_epc_write_header);
int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
{
unsigned long flags;
- struct device *dev = epc->dev.parent;
if (epf->epc)
return -EBUSY;
@@ -383,12 +380,6 @@ int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
return -EINVAL;
epf->epc = epc;
- if (dev->of_node) {
- of_dma_configure(&epf->dev, dev->of_node);
- } else {
- dma_set_coherent_mask(&epf->dev, epc->dev.coherent_dma_mask);
- epf->dev.dma_mask = epc->dev.dma_mask;
- }
spin_lock_irqsave(&epc->lock, flags);
list_add_tail(&epf->list, &epc->pci_epf);
@@ -503,9 +494,7 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
INIT_LIST_HEAD(&epc->pci_epf);
device_initialize(&epc->dev);
- dma_set_coherent_mask(&epc->dev, dev->coherent_dma_mask);
epc->dev.class = pci_epc_class;
- epc->dev.dma_mask = dev->dma_mask;
epc->dev.parent = dev;
epc->ops = ops;
diff --git a/drivers/pci/endpoint/pci-epc-mem.c b/drivers/pci/endpoint/pci-epc-mem.c
index 83b7d5d3fc3e..2bf8bd1f0563 100644
--- a/drivers/pci/endpoint/pci-epc-mem.c
+++ b/drivers/pci/endpoint/pci-epc-mem.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/**
* PCI Endpoint *Controller* Address Space Management
*
* Copyright (C) 2017 Texas Instruments
* Author: Kishon Vijay Abraham I <kishon@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/io.h>
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index ae1611a62808..766ce1dca2ec 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/**
* PCI Endpoint *Function* (EPF) library
*
* Copyright (C) 2017 Texas Instruments
* Author: Kishon Vijay Abraham I <kishon@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/device.h>
@@ -99,7 +88,7 @@ EXPORT_SYMBOL_GPL(pci_epf_bind);
*/
void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar)
{
- struct device *dev = &epf->dev;
+ struct device *dev = epf->epc->dev.parent;
if (!addr)
return;
@@ -122,7 +111,7 @@ EXPORT_SYMBOL_GPL(pci_epf_free_space);
void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar)
{
void *space;
- struct device *dev = &epf->dev;
+ struct device *dev = epf->epc->dev.parent;
dma_addr_t phys_addr;
if (size < 128)
diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index add66236215c..ac8d81268296 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* host bridge related code
*/
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig
index 38d12980db0f..a4ed7484d127 100644
--- a/drivers/pci/host/Kconfig
+++ b/drivers/pci/host/Kconfig
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
menu "PCI host controller drivers"
depends on PCI
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 34ec1d88f961..3b1059190867 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -34,6 +34,8 @@ obj-$(CONFIG_VMD) += vmd.o
# ARM64 and use internal ifdefs to only build the pieces we need
# depending on whether ACPI, the DT driver, or both are enabled.
+ifdef CONFIG_PCI
obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
obj-$(CONFIG_ARM64) += pci-thunder-pem.o
obj-$(CONFIG_ARM64) += pci-xgene.o
+endif
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c
index 26ed0c08f209..b04d37b3c5de 100644
--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Driver for the Aardvark PCIe controller, used on Marvell Armada
* 3700.
@@ -5,10 +6,6 @@
* Copyright (C) 2016 Marvell
*
* Author: Hezi Shahmoon <hezi.shahmoon@marvell.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#include <linux/delay.h>
diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c
index 44a47d4f0b8f..5d028f53fdcd 100644
--- a/drivers/pci/host/pci-host-common.c
+++ b/drivers/pci/host/pci-host-common.c
@@ -1,18 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Generic PCI host driver common code
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU 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/>.
- *
* Copyright (C) 2014 ARM Limited
*
* Author: Will Deacon <will.deacon@arm.com>
@@ -24,50 +13,6 @@
#include <linux/pci-ecam.h>
#include <linux/platform_device.h>
-static int gen_pci_parse_request_of_pci_ranges(struct device *dev,
- struct list_head *resources, struct resource **bus_range)
-{
- int err, res_valid = 0;
- struct device_node *np = dev->of_node;
- resource_size_t iobase;
- struct resource_entry *win, *tmp;
-
- err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase);
- if (err)
- return err;
-
- err = devm_request_pci_bus_resources(dev, resources);
- if (err)
- return err;
-
- resource_list_for_each_entry_safe(win, tmp, resources) {
- struct resource *res = win->res;
-
- switch (resource_type(res)) {
- case IORESOURCE_IO:
- err = pci_remap_iospace(res, iobase);
- if (err) {
- dev_warn(dev, "error %d: failed to map resource %pR\n",
- err, res);
- resource_list_destroy_entry(win);
- }
- break;
- case IORESOURCE_MEM:
- res_valid |= !(res->flags & IORESOURCE_PREFETCH);
- break;
- case IORESOURCE_BUS:
- *bus_range = res;
- break;
- }
- }
-
- if (res_valid)
- return 0;
-
- dev_err(dev, "non-prefetchable memory resource required\n");
- return -EINVAL;
-}
-
static void gen_pci_unmap_cfg(void *ptr)
{
pci_ecam_free((struct pci_config_window *)ptr);
@@ -82,9 +27,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev,
struct pci_config_window *cfg;
/* Parse our PCI ranges and request their resources */
- err = gen_pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
+ err = pci_parse_request_of_pci_ranges(dev, resources, &bus_range);
if (err)
- goto err_out;
+ return ERR_PTR(err);
err = of_address_to_resource(dev->of_node, 0, &cfgres);
if (err) {
@@ -116,7 +61,6 @@ int pci_host_common_probe(struct platform_device *pdev,
const char *type;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
- struct pci_bus *bus, *child;
struct pci_host_bridge *bridge;
struct pci_config_window *cfg;
struct list_head resources;
@@ -135,14 +79,13 @@ int pci_host_common_probe(struct platform_device *pdev,
of_pci_check_probe_only();
/* Parse and map our Configuration Space windows */
- INIT_LIST_HEAD(&resources);
cfg = gen_pci_init(dev, &resources, ops);
if (IS_ERR(cfg))
return PTR_ERR(cfg);
/* Do not reassign resources if probe only */
if (!pci_has_flag(PCI_PROBE_ONLY))
- pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
list_splice_init(&resources, &bridge->windows);
bridge->dev.parent = dev;
@@ -152,29 +95,11 @@ int pci_host_common_probe(struct platform_device *pdev,
bridge->map_irq = of_irq_parse_and_map_pci;
bridge->swizzle_irq = pci_common_swizzle;
- ret = pci_scan_root_bus_bridge(bridge);
+ ret = pci_host_probe(bridge);
if (ret < 0) {
- dev_err(dev, "Scanning root bridge failed");
+ pci_free_resource_list(&resources);
return ret;
}
- bus = bridge->bus;
-
- /*
- * We insert PCI resources into the iomem_resource and
- * ioport_resource trees in either pci_bus_claim_resources()
- * or pci_bus_assign_resources().
- */
- if (pci_has_flag(PCI_PROBE_ONLY)) {
- pci_bus_claim_resources(bus);
- } else {
- pci_bus_size_bridges(bus);
- pci_bus_assign_resources(bus);
-
- list_for_each_entry(child, &bus->children, node)
- pcie_bus_configure_settings(child);
- }
-
- pci_bus_add_devices(bus);
return 0;
}
diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c
index 2f05511ce718..45319ee3b484 100644
--- a/drivers/pci/host/pci-host-generic.c
+++ b/drivers/pci/host/pci-host-generic.c
@@ -1,19 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Simple, generic PCI host controller driver targetting firmware-initialised
* systems and virtual machines (e.g. the PCI emulation provided by kvmtool).
*
- * This program is free software; you can 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/>.
- *
* Copyright (C) 2014 ARM Limited
*
* Author: Will Deacon <will.deacon@arm.com>
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index 6b8d060d07de..2faf38eab785 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) Microsoft Corporation.
*
@@ -34,17 +35,6 @@
* read and write handlers for config space must be aware of this mechanism.
* Similarly, device setup and teardown involves messages sent to and from
* the PCI back-end driver in Hyper-V.
- *
- * This program is free software; you can 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU General Public License for more
- * details.
- *
*/
#include <linux/kernel.h>
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 8d88f19dc171..5d4dccfc9d81 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe driver for Marvell Armada 370 and Armada XP SoCs
*
* Author: 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>
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c
index e46de69f0380..a28370bb2b2a 100644
--- a/drivers/pci/host/pci-rcar-gen2.c
+++ b/drivers/pci/host/pci-rcar-gen2.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* pci-rcar-gen2: internal PCI bus support
*
@@ -5,10 +6,6 @@
* Copyright (C) 2013 Cogent Embedded, Inc.
*
* Author: Valentine Barshak <valentine.barshak@cogentembedded.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>
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index f9d3960dc39f..dd9b3bcc41c3 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCIe host controller driver for Tegra SoCs
*
@@ -10,20 +11,6 @@
* Bits taken from arch/arm/mach-dove/pcie.c
*
* Author: Thierry Reding <treding@nvidia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <linux/clk.h>
@@ -269,11 +256,10 @@ struct tegra_pcie {
void __iomem *pads;
void __iomem *afi;
+ void __iomem *cfg;
int irq;
- struct list_head buses;
- struct resource *cs;
-
+ struct resource cs;
struct resource io;
struct resource pio;
struct resource mem;
@@ -322,7 +308,6 @@ struct tegra_pcie_port {
};
struct tegra_pcie_bus {
- struct vm_struct *area;
struct list_head list;
unsigned int nr;
};
@@ -362,109 +347,26 @@ static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset)
*
* Mapping the whole extended configuration space would require 256 MiB of
* virtual address space, only a small part of which will actually be used.
- * To work around this, a 1 MiB of virtual addresses are allocated per bus
- * when the bus is first accessed. When the physical range is mapped, the
- * the bus number bits are hidden so that the extended register number bits
- * appear as bits [19:16]. Therefore the virtual mapping looks like this:
*
- * [19:16] extended register number
- * [15:11] device number
- * [10: 8] function number
- * [ 7: 0] register number
- *
- * This is achieved by stitching together 16 chunks of 64 KiB of physical
- * address space via the MMU.
+ * To work around this, a 4 KiB region is used to generate the required
+ * configuration transaction with relevant B:D:F and register offset values.
+ * This is achieved by dynamically programming base address and size of
+ * AFI_AXI_BAR used for end point config space mapping to make sure that the
+ * address (access to which generates correct config transaction) falls in
+ * this 4 KiB region.
*/
-static unsigned long tegra_pcie_conf_offset(unsigned int devfn, int where)
-{
- return ((where & 0xf00) << 8) | (PCI_SLOT(devfn) << 11) |
- (PCI_FUNC(devfn) << 8) | (where & 0xfc);
-}
-
-static struct tegra_pcie_bus *tegra_pcie_bus_alloc(struct tegra_pcie *pcie,
- unsigned int busnr)
-{
- struct device *dev = pcie->dev;
- pgprot_t prot = pgprot_noncached(PAGE_KERNEL);
- phys_addr_t cs = pcie->cs->start;
- struct tegra_pcie_bus *bus;
- unsigned int i;
- int err;
-
- bus = kzalloc(sizeof(*bus), GFP_KERNEL);
- if (!bus)
- return ERR_PTR(-ENOMEM);
-
- INIT_LIST_HEAD(&bus->list);
- bus->nr = busnr;
-
- /* allocate 1 MiB of virtual addresses */
- bus->area = get_vm_area(SZ_1M, VM_IOREMAP);
- if (!bus->area) {
- err = -ENOMEM;
- goto free;
- }
-
- /* map each of the 16 chunks of 64 KiB each */
- for (i = 0; i < 16; i++) {
- unsigned long virt = (unsigned long)bus->area->addr +
- i * SZ_64K;
- phys_addr_t phys = cs + i * SZ_16M + busnr * SZ_64K;
-
- err = ioremap_page_range(virt, virt + SZ_64K, phys, prot);
- if (err < 0) {
- dev_err(dev, "ioremap_page_range() failed: %d\n", err);
- goto unmap;
- }
- }
-
- return bus;
-
-unmap:
- vunmap(bus->area->addr);
-free:
- kfree(bus);
- return ERR_PTR(err);
-}
-
-static int tegra_pcie_add_bus(struct pci_bus *bus)
-{
- struct pci_host_bridge *host = pci_find_host_bridge(bus);
- struct tegra_pcie *pcie = pci_host_bridge_priv(host);
- struct tegra_pcie_bus *b;
-
- b = tegra_pcie_bus_alloc(pcie, bus->number);
- if (IS_ERR(b))
- return PTR_ERR(b);
-
- list_add_tail(&b->list, &pcie->buses);
-
- return 0;
-}
-
-static void tegra_pcie_remove_bus(struct pci_bus *child)
+static unsigned int tegra_pcie_conf_offset(u8 bus, unsigned int devfn,
+ unsigned int where)
{
- struct pci_host_bridge *host = pci_find_host_bridge(child);
- struct tegra_pcie *pcie = pci_host_bridge_priv(host);
- struct tegra_pcie_bus *bus, *tmp;
-
- list_for_each_entry_safe(bus, tmp, &pcie->buses, list) {
- if (bus->nr == child->number) {
- vunmap(bus->area->addr);
- list_del(&bus->list);
- kfree(bus);
- break;
- }
- }
+ return ((where & 0xf00) << 16) | (bus << 16) | (PCI_SLOT(devfn) << 11) |
+ (PCI_FUNC(devfn) << 8) | (where & 0xff);
}
static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
unsigned int devfn,
int where)
{
- struct pci_host_bridge *host = pci_find_host_bridge(bus);
- struct tegra_pcie *pcie = pci_host_bridge_priv(host);
- struct device *dev = pcie->dev;
+ struct tegra_pcie *pcie = bus->sysdata;
void __iomem *addr = NULL;
if (bus->number == 0) {
@@ -478,19 +380,17 @@ static void __iomem *tegra_pcie_map_bus(struct pci_bus *bus,
}
}
} else {
- struct tegra_pcie_bus *b;
+ unsigned int offset;
+ u32 base;
- list_for_each_entry(b, &pcie->buses, list)
- if (b->nr == bus->number)
- addr = (void __iomem *)b->area->addr;
+ offset = tegra_pcie_conf_offset(bus->number, devfn, where);
- if (!addr) {
- dev_err(dev, "failed to map cfg. space for bus %u\n",
- bus->number);
- return NULL;
- }
+ /* move 4 KiB window to offset within the FPCI region */
+ base = 0xfe100000 + ((offset & ~(SZ_4K - 1)) >> 8);
+ afi_writel(pcie, base, AFI_FPCI_BAR0);
- addr += tegra_pcie_conf_offset(devfn, where);
+ /* move to correct offset within the 4 KiB page */
+ addr = pcie->cfg + (offset & (SZ_4K - 1));
}
return addr;
@@ -517,8 +417,6 @@ static int tegra_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
}
static struct pci_ops tegra_pcie_ops = {
- .add_bus = tegra_pcie_add_bus,
- .remove_bus = tegra_pcie_remove_bus,
.map_bus = tegra_pcie_map_bus,
.read = tegra_pcie_config_read,
.write = tegra_pcie_config_write,
@@ -661,8 +559,7 @@ static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
- struct pci_host_bridge *host = pci_find_host_bridge(pdev->bus);
- struct tegra_pcie *pcie = pci_host_bridge_priv(host);
+ struct tegra_pcie *pcie = pdev->bus->sysdata;
int irq;
tegra_cpuidle_pcie_irqs_in_use();
@@ -743,12 +640,9 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
u32 fpci_bar, size, axi_address;
/* Bar 0: type 1 extended configuration space */
- fpci_bar = 0xfe100000;
- size = resource_size(pcie->cs);
- axi_address = pcie->cs->start;
- afi_writel(pcie, axi_address, AFI_AXI_BAR0_START);
+ size = resource_size(&pcie->cs);
+ afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
- afi_writel(pcie, fpci_bar, AFI_FPCI_BAR0);
/* Bar 1: downstream IO bar */
fpci_bar = 0xfdfc0000;
@@ -1353,10 +1247,14 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
goto poweroff;
}
- pcie->cs = devm_request_mem_region(dev, res->start,
- resource_size(res), res->name);
- if (!pcie->cs) {
- err = -EADDRNOTAVAIL;
+ pcie->cs = *res;
+
+ /* constrain configuration space to 4 KiB */
+ pcie->cs.end = pcie->cs.start + SZ_4K - 1;
+
+ pcie->cfg = devm_ioremap_resource(dev, &pcie->cs);
+ if (IS_ERR(pcie->cfg)) {
+ err = PTR_ERR(pcie->cfg);
goto poweroff;
}
@@ -2345,9 +2243,9 @@ static int tegra_pcie_probe(struct platform_device *pdev)
return -ENOMEM;
pcie = pci_host_bridge_priv(host);
+ host->sysdata = pcie;
pcie->soc = of_device_get_match_data(dev);
- INIT_LIST_HEAD(&pcie->buses);
INIT_LIST_HEAD(&pcie->ports);
pcie->dev = dev;
@@ -2382,7 +2280,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
tegra_pcie_enable_ports(pcie);
- pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
host->busnr = pcie->busn.start;
host->dev.parent = &pdev->dev;
host->ops = &tegra_pcie_ops;
diff --git a/drivers/pci/host/pci-thunder-ecam.c b/drivers/pci/host/pci-thunder-ecam.c
index fc0ca03f280e..32d1d7b81ef4 100644
--- a/drivers/pci/host/pci-thunder-ecam.c
+++ b/drivers/pci/host/pci-thunder-ecam.c
@@ -1,8 +1,5 @@
+// SPDX-License-Identifier: GPL-2.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) 2015, 2016 Cavium, Inc.
*/
diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c
index 6e066f8b74df..f127ce8bd4ef 100644
--- a/drivers/pci/host/pci-thunder-pem.c
+++ b/drivers/pci/host/pci-thunder-pem.c
@@ -1,16 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License 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/>.
- *
* Copyright (C) 2015 - 2016 Cavium, Inc.
*/
diff --git a/drivers/pci/host/pci-v3-semi.c b/drivers/pci/host/pci-v3-semi.c
index 02f6e1e3a421..7fef64869d19 100644
--- a/drivers/pci/host/pci-v3-semi.c
+++ b/drivers/pci/host/pci-v3-semi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Support for V3 Semiconductor PCI Local Bus to PCI Bridge
* Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c
index d417acab0ecf..5b3876f5312b 100644
--- a/drivers/pci/host/pci-versatile.c
+++ b/drivers/pci/host/pci-versatile.c
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2004 Koninklijke Philips Electronics NV
*
* Conversion to platform driver and DT:
* Copyright 2014 Linaro Ltd.
*
- * 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.
- *
* 14/04/2005 Initial version, colin.king@philips.com
*/
#include <linux/kernel.h>
@@ -202,7 +194,7 @@ static int versatile_pci_probe(struct platform_device *pdev)
writel(0, versatile_cfg_base[0] + PCI_INTERRUPT_LINE);
pci_add_flags(PCI_ENABLE_PROC_DOMAINS);
- pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
list_splice_init(&pci_res, &bridge->windows);
bridge->dev.parent = dev;
diff --git a/drivers/pci/host/pci-xgene-msi.c b/drivers/pci/host/pci-xgene-msi.c
index 1f42a202b021..df8e4bd5ddb2 100644
--- a/drivers/pci/host/pci-xgene-msi.c
+++ b/drivers/pci/host/pci-xgene-msi.c
@@ -1,19 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* APM X-Gene MSI Driver
*
* Copyright (c) 2014, Applied Micro Circuits Corporation
* Author: Tanmay Inamdar <tinamdar@apm.com>
* Duc Dang <dhdang@apm.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/cpu.h>
#include <linux/interrupt.h>
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index 465aa2a1b38d..0a0d7ee6d3c9 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -1,20 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
/**
* APM X-Gene PCIe Driver
*
* Copyright (c) 2014 Applied Micro Circuits Corporation.
*
* Author: Tanmay Inamdar <tinamdar@apm.com>.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#include <linux/clk.h>
#include <linux/delay.h>
@@ -668,7 +658,6 @@ static int xgene_pcie_probe(struct platform_device *pdev)
bus = bridge->bus;
- pci_scan_child_bus(bus);
pci_assign_unassigned_bus_resources(bus);
list_for_each_entry(child, &bus->children, node)
pcie_bus_configure_settings(child);
diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c
index d8141f4865de..025ef7d9a046 100644
--- a/drivers/pci/host/pcie-altera-msi.c
+++ b/drivers/pci/host/pcie-altera-msi.c
@@ -1,21 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Altera PCIe MSI support
*
* Author: Ley Foon Tan <lftan@altera.com>
*
* Copyright Altera Corporation (C) 2013-2015. All rights reserved
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/interrupt.h>
diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c
index 5cc4f594d79a..2235f4760951 100644
--- a/drivers/pci/host/pcie-altera.c
+++ b/drivers/pci/host/pcie-altera.c
@@ -1,20 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright Altera Corporation (C) 2013-2015. All rights reserved
*
* Author: Ley Foon Tan <lftan@altera.com>
* Description: Altera PCIe host controller driver
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * 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/delay.h>
diff --git a/drivers/pci/host/pcie-iproc-bcma.c b/drivers/pci/host/pcie-iproc-bcma.c
index f03d5e3612e9..603c83429cb3 100644
--- a/drivers/pci/host/pcie-iproc-bcma.c
+++ b/drivers/pci/host/pcie-iproc-bcma.c
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2015 Broadcom Corporation
* Copyright (C) 2015 Hauke Mehrtens <hauke@hauke-m.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 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>
diff --git a/drivers/pci/host/pcie-iproc-msi.c b/drivers/pci/host/pcie-iproc-msi.c
index 990fc906d73d..9deb56989d72 100644
--- a/drivers/pci/host/pcie-iproc-msi.c
+++ b/drivers/pci/host/pcie-iproc-msi.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2015 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/interrupt.h>
diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c
index a5073a921a04..e764a2a2693c 100644
--- a/drivers/pci/host/pcie-iproc-platform.c
+++ b/drivers/pci/host/pcie-iproc-platform.c
@@ -1,14 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2015 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/kernel.h>
@@ -92,6 +84,13 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
pcie->need_ob_cfg = true;
}
+ /*
+ * DT nodes are not used by all platforms that use the iProc PCIe
+ * core driver. For platforms that require explict inbound mapping
+ * configuration, "dma-ranges" would have been present in DT
+ */
+ pcie->need_ib_cfg = of_property_read_bool(np, "dma-ranges");
+
/* PHY use is optional */
pcie->phy = devm_phy_get(dev, "pcie-phy");
if (IS_ERR(pcie->phy)) {
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
index 935909bbe5c4..cbb095481cdc 100644
--- a/drivers/pci/host/pcie-iproc.c
+++ b/drivers/pci/host/pcie-iproc.c
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2014 Hauke Mehrtens <hauke@hauke-m.de>
* Copyright (C) 2015 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/kernel.h>
@@ -1378,9 +1370,11 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
}
}
- ret = iproc_pcie_map_dma_ranges(pcie);
- if (ret && ret != -ENOENT)
- goto err_power_off_phy;
+ if (pcie->need_ib_cfg) {
+ ret = iproc_pcie_map_dma_ranges(pcie);
+ if (ret && ret != -ENOENT)
+ goto err_power_off_phy;
+ }
#ifdef CONFIG_ARM
pcie->sysdata.private_data = pcie;
diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h
index a6b55cec9a66..d55f56a186cd 100644
--- a/drivers/pci/host/pcie-iproc.h
+++ b/drivers/pci/host/pcie-iproc.h
@@ -1,14 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2014-2015 Broadcom Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#ifndef _PCIE_IPROC_H
@@ -74,6 +66,7 @@ struct iproc_msi;
* @ob: outbound mapping related parameters
* @ob_map: outbound mapping related parameters specific to the controller
*
+ * @need_ib_cfg: indicates SW needs to configure the inbound mapping window
* @ib: inbound mapping related parameters
* @ib_map: outbound mapping region related parameters
*
@@ -101,6 +94,7 @@ struct iproc_pcie {
struct iproc_pcie_ob ob;
const struct iproc_pcie_ob_map *ob_map;
+ bool need_ib_cfg;
struct iproc_pcie_ib ib;
const struct iproc_pcie_ib_map *ib_map;
diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
index db93efdf1d63..a8b20c5012a9 100644
--- a/drivers/pci/host/pcie-mediatek.c
+++ b/drivers/pci/host/pcie-mediatek.c
@@ -1,18 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* MediaTek PCIe host controller driver.
*
* Copyright (c) 2017 MediaTek Inc.
* Author: Ryder Lee <ryder.lee@mediatek.com>
* Honghui Zhang <honghui.zhang@mediatek.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/clk.h>
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 52ab3cb0a0bf..b4c4aad2cf66 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe driver for Renesas R-Car SoCs
* Copyright (C) 2014 Renesas Electronics Europe Ltd
@@ -8,10 +9,6 @@
* Copyright (C) 2009 - 2011 Paul Mundt
*
* Author: Phil Edworthy <phil.edworthy@renesas.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
*/
#include <linux/clk.h>
@@ -459,7 +456,7 @@ static int rcar_pcie_enable(struct rcar_pcie *pcie)
rcar_pcie_setup(&bridge->windows, pcie);
- pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);
+ pci_add_flags(PCI_REASSIGN_ALL_BUS);
bridge->dev.parent = dev;
bridge->sysdata = pcie;
@@ -1123,7 +1120,9 @@ static int rcar_pcie_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&pcie->resources);
- rcar_pcie_parse_request_of_pci_ranges(pcie);
+ err = rcar_pcie_parse_request_of_pci_ranges(pcie);
+ if (err)
+ goto err_free_bridge;
err = rcar_pcie_get_resources(pcie);
if (err < 0) {
@@ -1178,6 +1177,7 @@ err_pm_disable:
err_free_resource_list:
pci_free_resource_list(&pcie->resources);
+err_free_bridge:
pci_free_host_bridge(bridge);
return err;
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c
index 9051c6c8fea4..f1e8f97ea1fb 100644
--- a/drivers/pci/host/pcie-rockchip.c
+++ b/drivers/pci/host/pcie-rockchip.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Rockchip AXI PCIe host controller driver
*
@@ -8,11 +9,6 @@
*
* Bits taken from Synopsys DesignWare Host controller driver and
* ARM PCI Host generic 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/bitrev.h>
diff --git a/drivers/pci/host/pcie-xilinx-nwl.c b/drivers/pci/host/pcie-xilinx-nwl.c
index 65dea98b2643..0acaf483d031 100644
--- a/drivers/pci/host/pcie-xilinx-nwl.c
+++ b/drivers/pci/host/pcie-xilinx-nwl.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCIe host controller driver for NWL PCIe Bridge
* Based on pcie-xilinx.c, pci-tegra.c
*
* (C) Copyright 2014 - 2015, Xilinx, 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/delay.h>
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
index 7b5325990f5e..0ad188effc09 100644
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCIe host controller driver for Xilinx AXI PCIe Bridge
*
@@ -7,11 +8,6 @@
*
* Bits taken from Synopsys DesignWare Host controller driver and
* ARM PCI Host generic 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/interrupt.h>
diff --git a/drivers/pci/host/vmd.c b/drivers/pci/host/vmd.c
index 509893bc3e63..930a8fa08bd6 100644
--- a/drivers/pci/host/vmd.c
+++ b/drivers/pci/host/vmd.c
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Volume Management Device driver
* Copyright (c) 2015, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
*/
#include <linux/device.h>
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig
index aadce45a9b4a..a8f21d051e0c 100644
--- a/drivers/pci/hotplug/Kconfig
+++ b/drivers/pci/hotplug/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# PCI Hotplug support
#
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index a5e66df4ad14..c9816166978e 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Common ACPI functions for hot plug platforms
*
@@ -5,21 +6,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <kristen.c.accardi@intel.com>
*
*/
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h
index f0ebc8b9a15a..e438a2d734f2 100644
--- a/drivers/pci/hotplug/acpiphp.h
+++ b/drivers/pci/hotplug/acpiphp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* ACPI PCI Hot Plug Controller Driver
*
@@ -12,21 +13,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <gregkh@us.ibm.com>,
* <t-kochi@bq.jp.nec.com>
*
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 3c81fc8b0103..12b5655fd390 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* ACPI PCI Hot Plug Controller Driver
*
@@ -12,21 +13,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <kristen.c.accardi@intel.com>
*
*/
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 5db6f1839dad..e2198a2feeca 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* ACPI PCI HotPlug glue functions to ACPI CA subsystem
*
@@ -11,21 +12,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <kristen.c.accardi@intel.com>
*
*/
@@ -811,10 +797,8 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
handle = adev->handle;
bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL);
- if (!bridge) {
- acpi_handle_err(handle, "No memory for bridge object\n");
+ if (!bridge)
return;
- }
INIT_LIST_HEAD(&bridge->slots);
kref_init(&bridge->ref);
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index 984c7e8cec5a..3903d90fe51c 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* ACPI PCI Hot Plug IBM Extension
*
@@ -6,21 +7,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <vernux@us.ibm.com>
*
*/
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h
index 60e66e027ebc..4658557be01a 100644
--- a/drivers/pci/hotplug/cpci_hotplug.h
+++ b/drivers/pci/hotplug/cpci_hotplug.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* CompactPCI Hot Plug Core Functions
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <scottm@somanetworks.com>
*/
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c
index 95f689f53920..07b533adc9df 100644
--- a/drivers/pci/hotplug/cpci_hotplug_core.c
+++ b/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* CompactPCI Hot Plug Driver
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <scottm@somanetworks.com>
*/
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
index f616358fa938..389b8fb50cd9 100644
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* CompactPCI Hot Plug Driver PCI functions
*
@@ -5,21 +6,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <scottm@somanetworks.com>
*/
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c
index bbf9cf8aeaad..17d71edf046f 100644
--- a/drivers/pci/hotplug/cpcihp_generic.c
+++ b/drivers/pci/hotplug/cpcihp_generic.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* cpcihp_generic.c
*
@@ -7,26 +8,6 @@
* Copyright 2001 Intel San Luis Obispo
* Copyright 2000,2001 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.
- *
* This generic CompactPCI hotplug driver should allow using the PCI hotplug
* mechanism on any CompactPCI board that exposes the #ENUM signal as a bit
* in a system register that can be read through standard port I/O.
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
index 2f8659a148f5..ae63e5a393c2 100644
--- a/drivers/pci/hotplug/cpcihp_zt5550.c
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* cpcihp_zt5550.c
*
@@ -7,26 +8,6 @@
* Copyright 2001 Intel San Luis Obispo
* Copyright 2000,2001 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.
- *
* Send feedback to <scottm@somanetworks.com>
*/
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.h b/drivers/pci/hotplug/cpcihp_zt5550.h
index 9a57fda5348c..5ea10df83dd9 100644
--- a/drivers/pci/hotplug/cpcihp_zt5550.h
+++ b/drivers/pci/hotplug/cpcihp_zt5550.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* cpcihp_zt5550.h
*
@@ -7,26 +8,6 @@
* Copyright 2001 Intel San Luis Obispo
* Copyright 2000,2001 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.
- *
* Send feedback to <scottm@somanetworks.com>
*/
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h
index c2bbe6b65d06..db78b394a075 100644
--- a/drivers/pci/hotplug/cpqphp.h
+++ b/drivers/pci/hotplug/cpqphp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Compaq Hot Plug Controller Driver
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>
*
*/
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index 70967ac75265..1797e36ec586 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Compaq Hot Plug Controller Driver
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>
*
* Jan 12, 2003 - Added 66/100/133MHz PCI-X support,
@@ -835,7 +821,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
bus = pdev->subordinate;
if (!bus) {
- dev_notice(&pdev->dev, "the device is not a bridge, skipping\n");
+ pci_notice(pdev, "the device is not a bridge, skipping\n");
rc = -ENODEV;
goto err_disable_device;
}
@@ -883,7 +869,6 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL);
if (!ctrl) {
- err("%s : out of memory\n", __func__);
rc = -ENOMEM;
goto err_disable_device;
}
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c
index a93069e739cb..b1b6e45253b2 100644
--- a/drivers/pci/hotplug/cpqphp_ctrl.c
+++ b/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Compaq Hot Plug Controller Driver
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>
*
*/
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c
index daae8071a156..00cd2b43364f 100644
--- a/drivers/pci/hotplug/cpqphp_nvram.c
+++ b/drivers/pci/hotplug/cpqphp_nvram.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Compaq Hot Plug Controller Driver
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>
*
*/
diff --git a/drivers/pci/hotplug/cpqphp_nvram.h b/drivers/pci/hotplug/cpqphp_nvram.h
index 34e4e54fcf15..918ff8dbfe62 100644
--- a/drivers/pci/hotplug/cpqphp_nvram.h
+++ b/drivers/pci/hotplug/cpqphp_nvram.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Compaq Hot Plug Controller Driver
*
@@ -6,21 +7,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>
*
*/
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c
index e220d49307bd..1b2b3f3b648b 100644
--- a/drivers/pci/hotplug/cpqphp_pci.c
+++ b/drivers/pci/hotplug/cpqphp_pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Compaq Hot Plug Controller Driver
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>
*
*/
@@ -89,7 +75,9 @@ int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func)
pci_lock_rescan_remove();
if (func->pci_dev == NULL)
- func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function));
+ func->pci_dev = pci_get_domain_bus_and_slot(0, func->bus,
+ PCI_DEVFN(func->device,
+ func->function));
/* No pci device, we need to create it then */
if (func->pci_dev == NULL) {
@@ -99,7 +87,9 @@ int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func)
if (num)
pci_bus_add_devices(ctrl->pci_dev->bus);
- func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function));
+ func->pci_dev = pci_get_domain_bus_and_slot(0, func->bus,
+ PCI_DEVFN(func->device,
+ func->function));
if (func->pci_dev == NULL) {
dbg("ERROR: pci_dev still null\n");
goto out;
@@ -129,7 +119,10 @@ int cpqhp_unconfigure_device(struct pci_func *func)
pci_lock_rescan_remove();
for (j = 0; j < 8 ; j++) {
- struct pci_dev *temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j));
+ struct pci_dev *temp = pci_get_domain_bus_and_slot(0,
+ func->bus,
+ PCI_DEVFN(func->device,
+ j));
if (temp) {
pci_dev_put(temp);
pci_stop_and_remove_bus_device(temp);
@@ -319,6 +312,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
int cloop = 0;
int stop_it;
int index;
+ u16 devfn;
/* Decide which slots are supported */
@@ -416,7 +410,9 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
new_slot->switch_save = 0x10;
/* In case of unsupported board */
new_slot->status = DevError;
- new_slot->pci_dev = pci_get_bus_and_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
+ devfn = (new_slot->device << 3) | new_slot->function;
+ new_slot->pci_dev = pci_get_domain_bus_and_slot(0,
+ new_slot->bus, devfn);
for (cloop = 0; cloop < 0x20; cloop++) {
rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) &(new_slot->config_space[cloop]));
diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c
index 775974deda74..fed1360ee9b1 100644
--- a/drivers/pci/hotplug/cpqphp_sysfs.c
+++ b/drivers/pci/hotplug/cpqphp_sysfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Compaq Hot Plug Controller Driver
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>
*
*/
diff --git a/drivers/pci/hotplug/ibmphp.h b/drivers/pci/hotplug/ibmphp.h
index d3256838cb05..fddb78606c74 100644
--- a/drivers/pci/hotplug/ibmphp.h
+++ b/drivers/pci/hotplug/ibmphp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef __IBMPHP_H
#define __IBMPHP_H
@@ -11,21 +12,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <gregkh@us.ibm.com>
*
*/
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 73cf84645c82..b81ca3fa0e84 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* IBM Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <gregkh@us.ibm.com>
*
*/
@@ -603,10 +589,8 @@ int ibmphp_update_slot_info(struct slot *slot_cur)
u8 mode;
info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
- if (!info) {
- err("out of system memory\n");
+ if (!info)
return -ENOMEM;
- }
info->power_status = SLOT_PWRGD(slot_cur->status);
info->attention_status = SLOT_ATTN(slot_cur->status,
@@ -707,7 +691,8 @@ static void ibm_unconfigure_device(struct pci_func *func)
pci_lock_rescan_remove();
for (j = 0; j < 0x08; j++) {
- temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);
+ temp = pci_get_domain_bus_and_slot(0, func->busno,
+ (func->device << 3) | j);
if (temp) {
pci_stop_and_remove_bus_device(temp);
pci_dev_put(temp);
@@ -734,14 +719,12 @@ static u8 bus_structure_fixup(u8 busno)
return 1;
bus = kmalloc(sizeof(*bus), GFP_KERNEL);
- if (!bus) {
- err("%s - out of memory\n", __func__);
+ if (!bus)
return 1;
- }
+
dev = kmalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) {
kfree(bus);
- err("%s - out of memory\n", __func__);
return 1;
}
@@ -780,7 +763,7 @@ static int ibm_configure_device(struct pci_func *func)
if (!(bus_structure_fixup(func->busno)))
flag = 1;
if (func->dev == NULL)
- func->dev = pci_get_bus_and_slot(func->busno,
+ func->dev = pci_get_domain_bus_and_slot(0, func->busno,
PCI_DEVFN(func->device, func->function));
if (func->dev == NULL) {
@@ -793,7 +776,7 @@ static int ibm_configure_device(struct pci_func *func)
if (num)
pci_bus_add_devices(bus);
- func->dev = pci_get_bus_and_slot(func->busno,
+ func->dev = pci_get_domain_bus_and_slot(0, func->busno,
PCI_DEVFN(func->device, func->function));
if (func->dev == NULL) {
err("ERROR... : pci_dev still NULL\n");
@@ -1101,7 +1084,6 @@ static int enable_slot(struct hotplug_slot *hs)
if (!slot_cur->func) {
/* We cannot do update_slot_info here, since no memory for
* kmalloc n.e.ways, and update_slot_info allocates some */
- err("out of system memory\n");
rc = -ENOMEM;
goto error_power;
}
@@ -1208,7 +1190,6 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)
/* We need this for functions that were there on bootup */
slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
if (!slot_cur->func) {
- err("out of system memory\n");
rc = -ENOMEM;
goto error;
}
@@ -1306,7 +1287,6 @@ static int __init ibmphp_init(void)
ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL);
if (!ibmphp_pci_bus) {
- err("out of memory\n");
rc = -ENOMEM;
goto exit;
}
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
index a6a4dac798e5..64549aa24c0f 100644
--- a/drivers/pci/hotplug/ibmphp_ebda.c
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* IBM Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <gregkh@us.ibm.com>
*
*/
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
index a6b458e4ab46..752c384cbd4c 100644
--- a/drivers/pci/hotplug/ibmphp_hpc.c
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* IBM Hot Plug Controller Driver
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <gregkh@us.ibm.com>
* <jshah@us.ibm.com>
*
diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c
index 25edd0b18b75..e22d023f91d1 100644
--- a/drivers/pci/hotplug/ibmphp_pci.c
+++ b/drivers/pci/hotplug/ibmphp_pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* IBM Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <gregkh@us.ibm.com>
*
*/
@@ -167,10 +153,9 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno)
goto error;
}
newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
- if (!newfunc) {
- err("out of system memory\n");
+ if (!newfunc)
return -ENOMEM;
- }
+
newfunc->busno = cur_func->busno;
newfunc->device = device;
cur_func->next = newfunc;
@@ -205,10 +190,9 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno)
for (i = 0; i < 32; i++) {
if (func->devices[i]) {
newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
- if (!newfunc) {
- err("out of system memory\n");
+ if (!newfunc)
return -ENOMEM;
- }
+
newfunc->busno = sec_number;
newfunc->device = (u8) i;
for (j = 0; j < 4; j++)
@@ -233,10 +217,9 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno)
}
newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
- if (!newfunc) {
- err("out of system memory\n");
+ if (!newfunc)
return -ENOMEM;
- }
+
newfunc->busno = cur_func->busno;
newfunc->device = device;
for (j = 0; j < 4; j++)
@@ -279,10 +262,9 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno)
if (func->devices[i]) {
debug("inside for loop, device is %x\n", i);
newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL);
- if (!newfunc) {
- err(" out of system memory\n");
+ if (!newfunc)
return -ENOMEM;
- }
+
newfunc->busno = sec_number;
newfunc->device = (u8) i;
for (j = 0; j < 4; j++)
@@ -405,10 +387,9 @@ static int configure_device(struct pci_func *func)
io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
- if (!io[count]) {
- err("out of system memory\n");
+ if (!io[count])
return -ENOMEM;
- }
+
io[count]->type = IO;
io[count]->busno = func->busno;
io[count]->devfunc = PCI_DEVFN(func->device, func->function);
@@ -442,10 +423,9 @@ static int configure_device(struct pci_func *func)
debug("len[count] in PFMEM %x, count %d\n", len[count], count);
pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
- if (!pfmem[count]) {
- err("out of system memory\n");
+ if (!pfmem[count])
return -ENOMEM;
- }
+
pfmem[count]->type = PFMEM;
pfmem[count]->busno = func->busno;
pfmem[count]->devfunc = PCI_DEVFN(func->device,
@@ -458,7 +438,6 @@ static int configure_device(struct pci_func *func)
} else {
mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
if (!mem_tmp) {
- err("out of system memory\n");
kfree(pfmem[count]);
return -ENOMEM;
}
@@ -508,10 +487,9 @@ static int configure_device(struct pci_func *func)
debug("len[count] in Mem %x, count %d\n", len[count], count);
mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
- if (!mem[count]) {
- err("out of system memory\n");
+ if (!mem[count])
return -ENOMEM;
- }
+
mem[count]->type = MEM;
mem[count]->busno = func->busno;
mem[count]->devfunc = PCI_DEVFN(func->device,
@@ -674,7 +652,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
bus_io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
if (!bus_io[count]) {
- err("out of system memory\n");
retval = -ENOMEM;
goto error;
}
@@ -706,7 +683,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
bus_pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
if (!bus_pfmem[count]) {
- err("out of system memory\n");
retval = -ENOMEM;
goto error;
}
@@ -722,7 +698,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
} else {
mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
if (!mem_tmp) {
- err("out of system memory\n");
retval = -ENOMEM;
goto error;
}
@@ -763,7 +738,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
bus_mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
if (!bus_mem[count]) {
- err("out of system memory\n");
retval = -ENOMEM;
goto error;
}
@@ -834,7 +808,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
io = kzalloc(sizeof(*io), GFP_KERNEL);
if (!io) {
- err("out of system memory\n");
retval = -ENOMEM;
goto error;
}
@@ -856,7 +829,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
debug("it wants %x memory behind the bridge\n", amount_needed->mem);
mem = kzalloc(sizeof(*mem), GFP_KERNEL);
if (!mem) {
- err("out of system memory\n");
retval = -ENOMEM;
goto error;
}
@@ -878,7 +850,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
debug("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem);
pfmem = kzalloc(sizeof(*pfmem), GFP_KERNEL);
if (!pfmem) {
- err("out of system memory\n");
retval = -ENOMEM;
goto error;
}
@@ -893,7 +864,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
} else {
mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL);
if (!mem_tmp) {
- err("out of system memory\n");
retval = -ENOMEM;
goto error;
}
@@ -924,7 +894,6 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno)
if (!bus) {
bus = kzalloc(sizeof(*bus), GFP_KERNEL);
if (!bus) {
- err("out of system memory\n");
retval = -ENOMEM;
goto error;
}
@@ -1652,10 +1621,9 @@ static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct re
}
if (io) {
io_range = kzalloc(sizeof(*io_range), GFP_KERNEL);
- if (!io_range) {
- err("out of system memory\n");
+ if (!io_range)
return -ENOMEM;
- }
+
io_range->start = io->start;
io_range->end = io->end;
io_range->rangeno = 1;
@@ -1664,10 +1632,9 @@ static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct re
}
if (mem) {
mem_range = kzalloc(sizeof(*mem_range), GFP_KERNEL);
- if (!mem_range) {
- err("out of system memory\n");
+ if (!mem_range)
return -ENOMEM;
- }
+
mem_range->start = mem->start;
mem_range->end = mem->end;
mem_range->rangeno = 1;
@@ -1676,10 +1643,9 @@ static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct re
}
if (pfmem) {
pfmem_range = kzalloc(sizeof(*pfmem_range), GFP_KERNEL);
- if (!pfmem_range) {
- err("out of system memory\n");
+ if (!pfmem_range)
return -ENOMEM;
- }
+
pfmem_range->start = pfmem->start;
pfmem_range->end = pfmem->end;
pfmem_range->rangeno = 1;
diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c
index aee6e41001e1..5e8caf7a4452 100644
--- a/drivers/pci/hotplug/ibmphp_res.c
+++ b/drivers/pci/hotplug/ibmphp_res.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* IBM Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <gregkh@us.ibm.com>
*
*/
@@ -56,10 +42,8 @@ static struct bus_node * __init alloc_error_bus(struct ebda_pci_rsrc *curr, u8 b
}
newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL);
- if (!newbus) {
- err("out of system memory\n");
+ if (!newbus)
return NULL;
- }
if (flag)
newbus->busno = busno;
@@ -79,10 +63,9 @@ static struct resource_node * __init alloc_resources(struct ebda_pci_rsrc *curr)
}
rs = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
- if (!rs) {
- err("out of system memory\n");
+ if (!rs)
return NULL;
- }
+
rs->busno = curr->bus_num;
rs->devfunc = curr->dev_fun;
rs->start = curr->start_addr;
@@ -99,10 +82,9 @@ static int __init alloc_bus_range(struct bus_node **new_bus, struct range_node *
if (first_bus) {
newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL);
- if (!newbus) {
- err("out of system memory.\n");
+ if (!newbus)
return -ENOMEM;
- }
+
newbus->busno = curr->bus_num;
} else {
newbus = *new_bus;
@@ -123,7 +105,6 @@ static int __init alloc_bus_range(struct bus_node **new_bus, struct range_node *
if (!newrange) {
if (first_bus)
kfree(newbus);
- err("out of system memory\n");
return -ENOMEM;
}
newrange->start = curr->start_addr;
@@ -1707,10 +1688,9 @@ static int __init once_over(void)
bus_cur->firstPFMemFromMem = pfmem_cur;
mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
- if (!mem) {
- err("out of system memory\n");
+ if (!mem)
return -ENOMEM;
- }
+
mem->type = MEM;
mem->busno = pfmem_cur->busno;
mem->devfunc = pfmem_cur->devfunc;
@@ -1989,10 +1969,9 @@ static int __init update_bridge_ranges(struct bus_node **bus)
if ((start_address) && (start_address <= end_address)) {
range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
- if (!range) {
- err("out of system memory\n");
+ if (!range)
return -ENOMEM;
- }
+
range->start = start_address;
range->end = end_address + 0xfff;
@@ -2016,7 +1995,6 @@ static int __init update_bridge_ranges(struct bus_node **bus)
io = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
if (!io) {
kfree(range);
- err("out of system memory\n");
return -ENOMEM;
}
io->type = IO;
@@ -2038,10 +2016,9 @@ static int __init update_bridge_ranges(struct bus_node **bus)
if ((start_address) && (start_address <= end_address)) {
range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
- if (!range) {
- err("out of system memory\n");
+ if (!range)
return -ENOMEM;
- }
+
range->start = start_address;
range->end = end_address + 0xfffff;
@@ -2066,7 +2043,6 @@ static int __init update_bridge_ranges(struct bus_node **bus)
mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
if (!mem) {
kfree(range);
- err("out of system memory\n");
return -ENOMEM;
}
mem->type = MEM;
@@ -2092,10 +2068,9 @@ static int __init update_bridge_ranges(struct bus_node **bus)
if ((start_address) && (start_address <= end_address)) {
range = kzalloc(sizeof(struct range_node), GFP_KERNEL);
- if (!range) {
- err("out of system memory\n");
+ if (!range)
return -ENOMEM;
- }
+
range->start = start_address;
range->end = end_address + 0xfffff;
@@ -2119,7 +2094,6 @@ static int __init update_bridge_ranges(struct bus_node **bus)
pfmem = kzalloc(sizeof(struct resource_node), GFP_KERNEL);
if (!pfmem) {
kfree(range);
- err("out of system memory\n");
return -ENOMEM;
}
pfmem->type = PFMEM;
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 7b0e97be9063..af92fed46ab7 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI HotPlug Controller Core
*
@@ -6,21 +7,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <kristen.c.accardi@intel.com>
*
* Authors:
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 06109d40c4ac..636ed8f4b869 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* PCI Express Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
*/
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 35d84845d5af..332b723ff9e6 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI Express Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
* Authors:
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 83f3d4af3677..c684faa43387 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI Express Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
*/
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7bab0606f1a9..18a42f8f5dc5 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI Express PCI Hot Plug Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
*
*/
@@ -838,16 +824,22 @@ struct controller *pcie_init(struct pcie_device *dev)
struct pci_dev *pdev = dev->port;
ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
- if (!ctrl) {
- dev_err(&dev->device, "%s: Out of memory\n", __func__);
+ if (!ctrl)
goto abort;
- }
+
ctrl->pcie = dev;
pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);
if (pdev->hotplug_user_indicators)
slot_cap &= ~(PCI_EXP_SLTCAP_AIP | PCI_EXP_SLTCAP_PIP);
+ /*
+ * We assume no Thunderbolt controllers support Command Complete events,
+ * but some controllers falsely claim they do.
+ */
+ if (pdev->is_thunderbolt)
+ slot_cap |= PCI_EXP_SLTCAP_NCCS;
+
ctrl->slot_cap = slot_cap;
mutex_init(&ctrl->ctrl_lock);
init_waitqueue_head(&ctrl->queue);
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 2a1ca020cf5a..3f518dea856d 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI Express Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
*/
@@ -79,7 +65,6 @@ int pciehp_configure_device(struct slot *p_slot)
int pciehp_unconfigure_device(struct slot *p_slot)
{
int rc = 0;
- u8 bctl = 0;
u8 presence = 0;
struct pci_dev *dev, *temp;
struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate;
@@ -101,17 +86,6 @@ int pciehp_unconfigure_device(struct slot *p_slot)
list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
bus_list) {
pci_dev_get(dev);
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
- pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
- if (bctl & PCI_BRIDGE_CTL_VGA) {
- ctrl_err(ctrl,
- "Cannot remove display device %s\n",
- pci_name(dev));
- pci_dev_put(dev);
- rc = -EINVAL;
- break;
- }
- }
if (!presence) {
pci_dev_set_disconnected(dev, NULL);
if (pci_has_subordinate(dev))
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c
index 172ed89200cd..c19694a04d2c 100644
--- a/drivers/pci/hotplug/pcihp_skeleton.c
+++ b/drivers/pci/hotplug/pcihp_skeleton.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI Hot Plug Controller Skeleton Driver - 0.3
*
@@ -6,21 +7,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* This driver is to be used as a skeleton driver to show how to interface
* with the pci hotplug core easily.
*
diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c
index 74f6a17e4614..23da3046f160 100644
--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI Hotplug Driver for PowerPC PowerNV platform.
*
* Copyright Gavin Shan, IBM Corporation 2016.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the 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/libfdt.h>
@@ -266,22 +262,18 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
fdt1 = kzalloc(0x10000, GFP_KERNEL);
if (!fdt1) {
ret = -ENOMEM;
- dev_warn(&php_slot->pdev->dev, "Cannot alloc FDT blob\n");
goto out;
}
ret = pnv_pci_get_device_tree(php_slot->dn->phandle, fdt1, 0x10000);
if (ret) {
- dev_warn(&php_slot->pdev->dev, "Error %d getting FDT blob\n",
- ret);
+ pci_warn(php_slot->pdev, "Error %d getting FDT blob\n", ret);
goto free_fdt1;
}
fdt = kzalloc(fdt_totalsize(fdt1), GFP_KERNEL);
if (!fdt) {
ret = -ENOMEM;
- dev_warn(&php_slot->pdev->dev, "Cannot %d bytes memory\n",
- fdt_totalsize(fdt1));
goto free_fdt1;
}
@@ -290,7 +282,7 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
dt = of_fdt_unflatten_tree(fdt, php_slot->dn, NULL);
if (!dt) {
ret = -EINVAL;
- dev_warn(&php_slot->pdev->dev, "Cannot unflatten FDT\n");
+ pci_warn(php_slot->pdev, "Cannot unflatten FDT\n");
goto free_fdt;
}
@@ -300,7 +292,7 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
ret = pnv_php_populate_changeset(&php_slot->ocs, php_slot->dn);
if (ret) {
pnv_php_reverse_nodes(php_slot->dn);
- dev_warn(&php_slot->pdev->dev, "Error %d populating changeset\n",
+ pci_warn(php_slot->pdev, "Error %d populating changeset\n",
ret);
goto free_dt;
}
@@ -308,8 +300,7 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
php_slot->dn->child = NULL;
ret = of_changeset_apply(&php_slot->ocs);
if (ret) {
- dev_warn(&php_slot->pdev->dev, "Error %d applying changeset\n",
- ret);
+ pci_warn(php_slot->pdev, "Error %d applying changeset\n", ret);
goto destroy_changeset;
}
@@ -345,14 +336,14 @@ int pnv_php_set_slot_power_state(struct hotplug_slot *slot,
if (be64_to_cpu(msg.params[1]) != php_slot->dn->phandle ||
be64_to_cpu(msg.params[2]) != state ||
be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) {
- dev_warn(&php_slot->pdev->dev, "Wrong msg (%lld, %lld, %lld)\n",
+ pci_warn(php_slot->pdev, "Wrong msg (%lld, %lld, %lld)\n",
be64_to_cpu(msg.params[1]),
be64_to_cpu(msg.params[2]),
be64_to_cpu(msg.params[3]));
return -ENOMSG;
}
} else if (ret < 0) {
- dev_warn(&php_slot->pdev->dev, "Error %d powering %s\n",
+ pci_warn(php_slot->pdev, "Error %d powering %s\n",
ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off");
return ret;
}
@@ -379,7 +370,7 @@ static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state)
*/
ret = pnv_pci_get_power_state(php_slot->id, &power_state);
if (ret) {
- dev_warn(&php_slot->pdev->dev, "Error %d getting power status\n",
+ pci_warn(php_slot->pdev, "Error %d getting power status\n",
ret);
} else {
*state = power_state;
@@ -405,8 +396,7 @@ static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
slot->info->adapter_status = presence;
ret = 0;
} else {
- dev_warn(&php_slot->pdev->dev, "Error %d getting presence\n",
- ret);
+ pci_warn(php_slot->pdev, "Error %d getting presence\n", ret);
}
return ret;
@@ -629,8 +619,7 @@ static int pnv_php_register_slot(struct pnv_php_slot *php_slot)
ret = pci_hp_register(&php_slot->slot, php_slot->bus,
php_slot->slot_no, php_slot->name);
if (ret) {
- dev_warn(&php_slot->pdev->dev, "Error %d registering slot\n",
- ret);
+ pci_warn(php_slot->pdev, "Error %d registering slot\n", ret);
return ret;
}
@@ -683,7 +672,7 @@ static int pnv_php_enable_msix(struct pnv_php_slot *php_slot)
/* Enable MSIx */
ret = pci_enable_msix_exact(pdev, &entry, 1);
if (ret) {
- dev_warn(&pdev->dev, "Error %d enabling MSIx\n", ret);
+ pci_warn(pdev, "Error %d enabling MSIx\n", ret);
return ret;
}
@@ -727,7 +716,7 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
(sts & PCI_EXP_SLTSTA_PDC)) {
ret = pnv_pci_get_presence_state(php_slot->id, &presence);
if (ret) {
- dev_warn(&pdev->dev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
+ pci_warn(pdev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
php_slot->name, ret, sts);
return IRQ_HANDLED;
}
@@ -757,12 +746,12 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
*/
event = kzalloc(sizeof(*event), GFP_ATOMIC);
if (!event) {
- dev_warn(&pdev->dev, "PCI slot [%s] missed hotplug event 0x%04x\n",
+ pci_warn(pdev, "PCI slot [%s] missed hotplug event 0x%04x\n",
php_slot->name, sts);
return IRQ_HANDLED;
}
- dev_info(&pdev->dev, "PCI slot [%s] %s (IRQ: %d)\n",
+ pci_info(pdev, "PCI slot [%s] %s (IRQ: %d)\n",
php_slot->name, added ? "added" : "removed", irq);
INIT_WORK(&event->work, pnv_php_event_handler);
event->added = added;
@@ -782,7 +771,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
/* Allocate workqueue */
php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name);
if (!php_slot->wq) {
- dev_warn(&pdev->dev, "Cannot alloc workqueue\n");
+ pci_warn(pdev, "Cannot alloc workqueue\n");
pnv_php_disable_irq(php_slot, true);
return;
}
@@ -806,7 +795,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
php_slot->name, php_slot);
if (ret) {
pnv_php_disable_irq(php_slot, true);
- dev_warn(&pdev->dev, "Error %d enabling IRQ %d\n", ret, irq);
+ pci_warn(pdev, "Error %d enabling IRQ %d\n", ret, irq);
return;
}
@@ -842,7 +831,7 @@ static void pnv_php_enable_irq(struct pnv_php_slot *php_slot)
ret = pci_enable_device(pdev);
if (ret) {
- dev_warn(&pdev->dev, "Error %d enabling device\n", ret);
+ pci_warn(pdev, "Error %d enabling device\n", ret);
return;
}
diff --git a/drivers/pci/hotplug/rpadlpar.h b/drivers/pci/hotplug/rpadlpar.h
index 81df93931ad0..1eeb55d33171 100644
--- a/drivers/pci/hotplug/rpadlpar.h
+++ b/drivers/pci/hotplug/rpadlpar.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Interface for Dynamic Logical Partitioning of I/O Slots on
* RPA-compliant PPC64 platform.
@@ -6,11 +7,6 @@
* October 2003
*
* Copyright (C) 2003 IBM.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the 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 _RPADLPAR_IO_H_
#define _RPADLPAR_IO_H_
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index fc01d7d807f3..e2356a9c7088 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Interface for Dynamic Logical Partitioning of I/O Slots on
* RPA-compliant PPC64 platform.
@@ -8,11 +9,6 @@
* October 2003
*
* Copyright (C) 2003 IBM.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
*/
#undef DEBUG
diff --git a/drivers/pci/hotplug/rpadlpar_sysfs.c b/drivers/pci/hotplug/rpadlpar_sysfs.c
index b806314349cf..cdbfa5df3a51 100644
--- a/drivers/pci/hotplug/rpadlpar_sysfs.c
+++ b/drivers/pci/hotplug/rpadlpar_sysfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Interface for Dynamic Logical Partitioning of I/O Slots on
* RPA-compliant PPC64 platform.
@@ -6,11 +7,6 @@
* October 2003
*
* Copyright (C) 2003 IBM.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the 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/kobject.h>
#include <linux/string.h>
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index bdb844b01a3d..c8311724bd76 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
*
@@ -5,21 +6,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <lxie@us.ibm.com>,
*
*/
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 53902c7c38f2..fb5e0845429d 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -1,24 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
* Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <lxie@us.ibm.com>
*
*/
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index 32aabc533be8..0aac33e15dab 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -1,24 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI Hot Plug Controller Driver for RPA-compliant PPC64 platform.
* Copyright (C) 2003 Linda Xie <lxie@us.ibm.com>
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <lxie@us.ibm.com>
*
*/
diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c
index 489862360f2c..3840a2075e6a 100644
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -1,24 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* RPA Virtual I/O device functions
* Copyright (C) 2004 Linda Xie <lxie@us.ibm.com>
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <lxie@us.ibm.com>
*
*/
diff --git a/drivers/pci/hotplug/s390_pci_hpc.c b/drivers/pci/hotplug/s390_pci_hpc.c
index 530d0e49f2ed..ffdc2977395d 100644
--- a/drivers/pci/hotplug/s390_pci_hpc.c
+++ b/drivers/pci/hotplug/s390_pci_hpc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI Hot Plug Controller Driver for System z
*
@@ -5,8 +6,6 @@
*
* Author(s):
* Jan Glauber <jang@linux.vnet.ibm.com>
- *
- * License: GPL
*/
#define KMSG_COMPONENT "zpci"
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index 339bce0403dd..78b6bdbb3a39 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -1,8 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
* Copyright (C) 2005-2006 Silicon Graphics, Inc. All rights reserved.
*
* This work was based on the 2.4/2.6 kernel development by Dick Reigner.
@@ -245,18 +242,18 @@ static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
if (rc == PCI_SLOT_ALREADY_UP) {
- dev_dbg(&slot->pci_bus->self->dev, "is already active\n");
+ pci_dbg(slot->pci_bus->self, "is already active\n");
return 1; /* return 1 to user */
}
if (rc == PCI_L1_ERR) {
- dev_dbg(&slot->pci_bus->self->dev, "L1 failure %d with message: %s",
+ pci_dbg(slot->pci_bus->self, "L1 failure %d with message: %s",
resp.resp_sub_errno, resp.resp_l1_msg);
return -EPERM;
}
if (rc) {
- dev_dbg(&slot->pci_bus->self->dev, "insert failed with error %d sub-error %d\n",
+ pci_dbg(slot->pci_bus->self, "insert failed with error %d sub-error %d\n",
rc, resp.resp_sub_errno);
return -EIO;
}
@@ -281,23 +278,23 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
(rc == PCI_SLOT_ALREADY_DOWN)) {
- dev_dbg(&slot->pci_bus->self->dev, "Slot %s already inactive\n", slot->physical_path);
+ pci_dbg(slot->pci_bus->self, "Slot %s already inactive\n", slot->physical_path);
return 1; /* return 1 to user */
}
if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
- dev_dbg(&slot->pci_bus->self->dev, "Cannot remove last 33MHz card\n");
+ pci_dbg(slot->pci_bus->self, "Cannot remove last 33MHz card\n");
return -EPERM;
}
if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
- dev_dbg(&slot->pci_bus->self->dev, "L1 failure %d with message \n%s\n",
+ pci_dbg(slot->pci_bus->self, "L1 failure %d with message \n%s\n",
resp.resp_sub_errno, resp.resp_l1_msg);
return -EPERM;
}
if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
- dev_dbg(&slot->pci_bus->self->dev, "remove failed with error %d sub-error %d\n",
+ pci_dbg(slot->pci_bus->self, "remove failed with error %d sub-error %d\n",
rc, resp.resp_sub_errno);
return -EIO;
}
@@ -308,12 +305,12 @@ static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
- dev_dbg(&slot->pci_bus->self->dev, "remove successful\n");
+ pci_dbg(slot->pci_bus->self, "remove successful\n");
return 0;
}
if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
- dev_dbg(&slot->pci_bus->self->dev, "remove failed rc = %d\n", rc);
+ pci_dbg(slot->pci_bus->self, "remove failed rc = %d\n", rc);
}
return rc;
@@ -366,7 +363,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
num_funcs = pci_scan_slot(slot->pci_bus,
PCI_DEVFN(slot->device_num + 1, 0));
if (!num_funcs) {
- dev_dbg(&slot->pci_bus->self->dev, "no device in slot\n");
+ pci_dbg(slot->pci_bus->self, "no device in slot\n");
mutex_unlock(&sn_hotplug_mutex);
return -ENODEV;
}
@@ -412,7 +409,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
phandle = acpi_device_handle(PCI_CONTROLLER(slot->pci_bus)->companion);
if (acpi_bus_get_device(phandle, &pdevice)) {
- dev_dbg(&slot->pci_bus->self->dev, "no parent device, assuming NULL\n");
+ pci_dbg(slot->pci_bus->self, "no parent device, assuming NULL\n");
pdevice = NULL;
}
@@ -463,9 +460,9 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
mutex_unlock(&sn_hotplug_mutex);
if (rc == 0)
- dev_dbg(&slot->pci_bus->self->dev, "insert operation successful\n");
+ pci_dbg(slot->pci_bus->self, "insert operation successful\n");
else
- dev_dbg(&slot->pci_bus->self->dev, "insert operation failed rc = %d\n", rc);
+ pci_dbg(slot->pci_bus->self, "insert operation failed rc = %d\n", rc);
return rc;
}
@@ -643,16 +640,16 @@ static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
if (rc)
goto register_err;
}
- dev_dbg(&pci_bus->self->dev, "Registered bus with hotplug\n");
+ pci_dbg(pci_bus->self, "Registered bus with hotplug\n");
return rc;
register_err:
- dev_dbg(&pci_bus->self->dev, "bus failed to register with err = %d\n",
+ pci_dbg(pci_bus->self, "bus failed to register with err = %d\n",
rc);
alloc_err:
if (rc == -ENOMEM)
- dev_dbg(&pci_bus->self->dev, "Memory allocation error\n");
+ pci_dbg(pci_bus->self, "Memory allocation error\n");
/* destroy THIS element */
if (bss_hotplug_slot)
@@ -685,10 +682,10 @@ static int __init sn_pci_hotplug_init(void)
rc = sn_pci_bus_valid(pci_bus);
if (rc != 1) {
- dev_dbg(&pci_bus->self->dev, "not a valid hotplug bus\n");
+ pci_dbg(pci_bus->self, "not a valid hotplug bus\n");
continue;
}
- dev_dbg(&pci_bus->self->dev, "valid hotplug bus\n");
+ pci_dbg(pci_bus->self, "valid hotplug bus\n");
rc = sn_hotplug_slot_register(pci_bus);
if (!rc) {
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 70c7ea6af034..c55730b61c9a 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Standard Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
*
*/
@@ -62,15 +48,15 @@ do { \
#define ctrl_dbg(ctrl, format, arg...) \
do { \
if (shpchp_debug) \
- dev_printk(KERN_DEBUG, &ctrl->pci_dev->dev, \
+ pci_printk(KERN_DEBUG, ctrl->pci_dev, \
format, ## arg); \
} while (0)
#define ctrl_err(ctrl, format, arg...) \
- dev_err(&ctrl->pci_dev->dev, format, ## arg)
+ pci_err(ctrl->pci_dev, format, ## arg)
#define ctrl_info(ctrl, format, arg...) \
- dev_info(&ctrl->pci_dev->dev, format, ## arg)
+ pci_info(ctrl->pci_dev, format, ## arg)
#define ctrl_warn(ctrl, format, arg...) \
- dev_warn(&ctrl->pci_dev->dev, format, ## arg)
+ pci_warn(ctrl->pci_dev, format, ## arg)
#define SLOT_NAME_SIZE 10
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index 7bfb87bd2b7e..1f0f96908b5a 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Standard Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
*/
@@ -305,10 +291,9 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
return -ENODEV;
ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
- if (!ctrl) {
- dev_err(&pdev->dev, "%s: Out of memory\n", __func__);
+ if (!ctrl)
goto err_out_none;
- }
+
INIT_LIST_HEAD(&ctrl->slot_list);
rc = shpc_init(ctrl, pdev);
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 10c7927599b3..bedda5bda910 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Standard Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
*/
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 4810e9626d9f..db047284c291 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Standard PCI Hot Plug Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
*
*/
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index ea63db58b4b1..115701301487 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Standard Hot Plug Controller Driver
*
@@ -8,21 +9,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com>
*
*/
@@ -78,7 +64,6 @@ int shpchp_configure_device(struct slot *p_slot)
int shpchp_unconfigure_device(struct slot *p_slot)
{
int rc = 0;
- u8 bctl = 0;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
struct pci_dev *dev, *temp;
struct controller *ctrl = p_slot->ctrl;
@@ -93,17 +78,6 @@ int shpchp_unconfigure_device(struct slot *p_slot)
continue;
pci_dev_get(dev);
- if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl);
- if (bctl & PCI_BRIDGE_CTL_VGA) {
- ctrl_err(ctrl,
- "Cannot remove display device %s\n",
- pci_name(dev));
- pci_dev_put(dev);
- rc = -EINVAL;
- break;
- }
- }
pci_stop_and_remove_bus_device(dev);
pci_dev_put(dev);
}
diff --git a/drivers/pci/hotplug/shpchp_sysfs.c b/drivers/pci/hotplug/shpchp_sysfs.c
index 7efb56a28c9f..45658bb5c554 100644
--- a/drivers/pci/hotplug/shpchp_sysfs.c
+++ b/drivers/pci/hotplug/shpchp_sysfs.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Compaq Hot Plug Controller Driver
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <greg@kroah.com>
*
*/
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index 0b7b5da63d4e..677924ae0350 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/iov.c
*
@@ -259,19 +260,19 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
nres++;
}
if (nres != iov->nres) {
- dev_err(&dev->dev, "not enough MMIO resources for SR-IOV\n");
+ pci_err(dev, "not enough MMIO resources for SR-IOV\n");
return -ENOMEM;
}
bus = pci_iov_virtfn_bus(dev, nr_virtfn - 1);
if (bus > dev->bus->busn_res.end) {
- dev_err(&dev->dev, "can't enable %d VFs (bus %02x out of range of %pR)\n",
+ pci_err(dev, "can't enable %d VFs (bus %02x out of range of %pR)\n",
nr_virtfn, bus, &dev->bus->busn_res);
return -ENOMEM;
}
if (pci_enable_resources(dev, bars)) {
- dev_err(&dev->dev, "SR-IOV: IOV BARS not allocated\n");
+ pci_err(dev, "SR-IOV: IOV BARS not allocated\n");
return -ENOMEM;
}
@@ -298,7 +299,7 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
rc = pcibios_sriov_enable(dev, initial);
if (rc) {
- dev_err(&dev->dev, "failure %d from pcibios_sriov_enable()\n", rc);
+ pci_err(dev, "failure %d from pcibios_sriov_enable()\n", rc);
goto err_pcibios;
}
@@ -432,7 +433,7 @@ found:
}
iov->barsz[i] = resource_size(res);
res->end = res->start + resource_size(res) * total - 1;
- dev_info(&dev->dev, "VF(n) BAR%d space: %pR (contains BAR%d for %d VFs)\n",
+ pci_info(dev, "VF(n) BAR%d space: %pR (contains BAR%d for %d VFs)\n",
i, res, i, total);
i += bar64;
nres++;
diff --git a/drivers/pci/irq.c b/drivers/pci/irq.c
index 10929cd43d5d..2a808e10645f 100644
--- a/drivers/pci/irq.c
+++ b/drivers/pci/irq.c
@@ -16,11 +16,10 @@ static void pci_note_irq_problem(struct pci_dev *pdev, const char *reason)
{
struct pci_dev *parent = to_pci_dev(pdev->dev.parent);
- dev_err(&pdev->dev,
- "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n",
+ pci_err(pdev, "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n",
dev_name(&parent->dev), parent->vendor, parent->device);
- dev_err(&pdev->dev, "%s\n", reason);
- dev_err(&pdev->dev, "Please report to linux-kernel@vger.kernel.org\n");
+ pci_err(pdev, "%s\n", reason);
+ pci_err(pdev, "Please report to linux-kernel@vger.kernel.org\n");
WARN_ON(1);
}
diff --git a/drivers/pci/mmap.c b/drivers/pci/mmap.c
index 9a5e5a9055eb..814a3ce341fc 100644
--- a/drivers/pci/mmap.c
+++ b/drivers/pci/mmap.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* mmap.c — generic PCI resource mmap helper
*
* Copyright © 2017 Amazon.com, Inc. or its affiliates.
*
* Author: David Woodhouse <dwmw2@infradead.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/kernel.h>
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index e06607167858..8b0729c94bb7 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* File: msi.c
* Purpose: PCI Message Signaled Interrupt (MSI)
@@ -578,7 +579,7 @@ static int msi_verify_entries(struct pci_dev *dev)
for_each_pci_msi_entry(entry, dev) {
if (!dev->no_64bit_msi || !entry->msg.address_hi)
continue;
- dev_err(&dev->dev, "Device has broken 64-bit MSI but arch"
+ pci_err(dev, "Device has broken 64-bit MSI but arch"
" tried to assign one above 4G\n");
return -EIO;
}
@@ -962,7 +963,7 @@ static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries,
/* Check whether driver already requested for MSI irq */
if (dev->msi_enabled) {
- dev_info(&dev->dev, "can't enable MSI-X (MSI IRQ already assigned)\n");
+ pci_info(dev, "can't enable MSI-X (MSI IRQ already assigned)\n");
return -EINVAL;
}
return msix_capability_init(dev, entries, nvec, affd);
@@ -1032,8 +1033,7 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
/* Check whether driver already requested MSI-X irqs */
if (dev->msix_enabled) {
- dev_info(&dev->dev,
- "can't enable MSI (MSI-X already enabled)\n");
+ pci_info(dev, "can't enable MSI (MSI-X already enabled)\n");
return -EINVAL;
}
diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index e112da11630e..a28355c273ae 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -1,19 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* PCI <-> OF mapping helpers
*
* Copyright 2011 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.
*/
+#define pr_fmt(fmt) "PCI: OF: " fmt
#include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/of.h>
#include <linux/of_irq.h>
+#include <linux/of_address.h>
#include <linux/of_pci.h>
#include "pci.h"
@@ -51,8 +49,9 @@ struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus)
if (WARN_ON(bus->self || bus->parent))
return NULL;
- /* Look for a node pointer in either the intermediary device we
- * create above the root bus or it's own parent. Normally only
+ /*
+ * Look for a node pointer in either the intermediary device we
+ * create above the root bus or its own parent. Normally only
* the later is populated.
*/
if (bus->bridge->of_node)
@@ -88,3 +87,561 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus)
return NULL;
#endif
}
+
+static inline int __of_pci_pci_compare(struct device_node *node,
+ unsigned int data)
+{
+ int devfn;
+
+ devfn = of_pci_get_devfn(node);
+ if (devfn < 0)
+ return 0;
+
+ return devfn == data;
+}
+
+struct device_node *of_pci_find_child_device(struct device_node *parent,
+ unsigned int devfn)
+{
+ struct device_node *node, *node2;
+
+ for_each_child_of_node(parent, node) {
+ if (__of_pci_pci_compare(node, devfn))
+ return node;
+ /*
+ * Some OFs create a parent node "multifunc-device" as
+ * a fake root for all functions of a multi-function
+ * device we go down them as well.
+ */
+ if (!strcmp(node->name, "multifunc-device")) {
+ for_each_child_of_node(node, node2) {
+ if (__of_pci_pci_compare(node2, devfn)) {
+ of_node_put(node);
+ return node2;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(of_pci_find_child_device);
+
+/**
+ * of_pci_get_devfn() - Get device and function numbers for a device node
+ * @np: device node
+ *
+ * Parses a standard 5-cell PCI resource and returns an 8-bit value that can
+ * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device
+ * and function numbers respectively. On error a negative error code is
+ * returned.
+ */
+int of_pci_get_devfn(struct device_node *np)
+{
+ u32 reg[5];
+ int error;
+
+ error = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
+ if (error)
+ return error;
+
+ return (reg[0] >> 8) & 0xff;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_devfn);
+
+/**
+ * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
+ * @node: device node
+ * @res: address to a struct resource to return the bus-range
+ *
+ * Returns 0 on success or a negative error-code on failure.
+ */
+int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
+{
+ u32 bus_range[2];
+ int error;
+
+ error = of_property_read_u32_array(node, "bus-range", bus_range,
+ ARRAY_SIZE(bus_range));
+ if (error)
+ return error;
+
+ res->name = node->name;
+ res->start = bus_range[0];
+ res->end = bus_range[1];
+ res->flags = IORESOURCE_BUS;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
+
+/**
+ * This function will try to obtain the host bridge domain number by
+ * finding a property called "linux,pci-domain" of the given device node.
+ *
+ * @node: device tree node with the domain information
+ *
+ * Returns the associated domain number from DT in the range [0-0xffff], or
+ * a negative value if the required property is not found.
+ */
+int of_get_pci_domain_nr(struct device_node *node)
+{
+ u32 domain;
+ int error;
+
+ error = of_property_read_u32(node, "linux,pci-domain", &domain);
+ if (error)
+ return error;
+
+ return (u16)domain;
+}
+EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
+
+/**
+ * This function will try to find the limitation of link speed by finding
+ * a property called "max-link-speed" of the given device node.
+ *
+ * @node: device tree node with the max link speed information
+ *
+ * Returns the associated max link speed from DT, or a negative value if the
+ * required property is not found or is invalid.
+ */
+int of_pci_get_max_link_speed(struct device_node *node)
+{
+ u32 max_link_speed;
+
+ if (of_property_read_u32(node, "max-link-speed", &max_link_speed) ||
+ max_link_speed > 4)
+ return -EINVAL;
+
+ return max_link_speed;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
+
+/**
+ * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
+ * is present and valid
+ */
+void of_pci_check_probe_only(void)
+{
+ u32 val;
+ int ret;
+
+ ret = of_property_read_u32(of_chosen, "linux,pci-probe-only", &val);
+ if (ret) {
+ if (ret == -ENODATA || ret == -EOVERFLOW)
+ pr_warn("linux,pci-probe-only without valid value, ignoring\n");
+ return;
+ }
+
+ if (val)
+ pci_add_flags(PCI_PROBE_ONLY);
+ else
+ pci_clear_flags(PCI_PROBE_ONLY);
+
+ pr_info("PROBE_ONLY %sabled\n", val ? "en" : "dis");
+}
+EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
+
+#if defined(CONFIG_OF_ADDRESS)
+/**
+ * of_pci_get_host_bridge_resources - Parse PCI host bridge resources from DT
+ * @dev: device node of the host bridge having the range property
+ * @busno: bus number associated with the bridge root bus
+ * @bus_max: maximum number of buses for this bridge
+ * @resources: list where the range of resources will be added after DT parsing
+ * @io_base: pointer to a variable that will contain on return the physical
+ * address for the start of the I/O range. Can be NULL if the caller doesn't
+ * expect I/O ranges to be present in the device tree.
+ *
+ * It is the caller's job to free the @resources list.
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping based on its content. It is expected
+ * that the property conforms with the Power ePAPR document.
+ *
+ * It returns zero if the range parsing has been successful or a standard error
+ * value if it failed.
+ */
+int of_pci_get_host_bridge_resources(struct device_node *dev,
+ unsigned char busno, unsigned char bus_max,
+ struct list_head *resources, resource_size_t *io_base)
+{
+ struct resource_entry *window;
+ struct resource *res;
+ struct resource *bus_range;
+ struct of_pci_range range;
+ struct of_pci_range_parser parser;
+ char range_type[4];
+ int err;
+
+ if (io_base)
+ *io_base = (resource_size_t)OF_BAD_ADDR;
+
+ bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL);
+ if (!bus_range)
+ return -ENOMEM;
+
+ pr_info("host bridge %pOF ranges:\n", dev);
+
+ err = of_pci_parse_bus_range(dev, bus_range);
+ if (err) {
+ bus_range->start = busno;
+ bus_range->end = bus_max;
+ bus_range->flags = IORESOURCE_BUS;
+ pr_info(" No bus range found for %pOF, using %pR\n",
+ dev, bus_range);
+ } else {
+ if (bus_range->end > bus_range->start + bus_max)
+ bus_range->end = bus_range->start + bus_max;
+ }
+ pci_add_resource(resources, bus_range);
+
+ /* Check for ranges property */
+ err = of_pci_range_parser_init(&parser, dev);
+ if (err)
+ goto parse_failed;
+
+ pr_debug("Parsing ranges property...\n");
+ for_each_of_pci_range(&parser, &range) {
+ /* Read next ranges element */
+ if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
+ snprintf(range_type, 4, " IO");
+ else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
+ snprintf(range_type, 4, "MEM");
+ else
+ snprintf(range_type, 4, "err");
+ pr_info(" %s %#010llx..%#010llx -> %#010llx\n", range_type,
+ range.cpu_addr, range.cpu_addr + range.size - 1,
+ range.pci_addr);
+
+ /*
+ * If we failed translation or got a zero-sized region
+ * then skip this range
+ */
+ if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
+ continue;
+
+ res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ if (!res) {
+ err = -ENOMEM;
+ goto parse_failed;
+ }
+
+ err = of_pci_range_to_resource(&range, dev, res);
+ if (err) {
+ kfree(res);
+ continue;
+ }
+
+ if (resource_type(res) == IORESOURCE_IO) {
+ if (!io_base) {
+ pr_err("I/O range found for %pOF. Please provide an io_base pointer to save CPU base address\n",
+ dev);
+ err = -EINVAL;
+ goto conversion_failed;
+ }
+ if (*io_base != (resource_size_t)OF_BAD_ADDR)
+ pr_warn("More than one I/O resource converted for %pOF. CPU base address for old range lost!\n",
+ dev);
+ *io_base = range.cpu_addr;
+ }
+
+ pci_add_resource_offset(resources, res, res->start - range.pci_addr);
+ }
+
+ return 0;
+
+conversion_failed:
+ kfree(res);
+parse_failed:
+ resource_list_for_each_entry(window, resources)
+ kfree(window->res);
+ pci_free_resource_list(resources);
+ return err;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_host_bridge_resources);
+#endif /* CONFIG_OF_ADDRESS */
+
+/**
+ * of_pci_map_rid - Translate a requester ID through a downstream mapping.
+ * @np: root complex device node.
+ * @rid: PCI requester ID to map.
+ * @map_name: property name of the map to use.
+ * @map_mask_name: optional property name of the mask to use.
+ * @target: optional pointer to a target device node.
+ * @id_out: optional pointer to receive the translated ID.
+ *
+ * Given a PCI requester ID, look up the appropriate implementation-defined
+ * platform ID and/or the target device which receives transactions on that
+ * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or
+ * @id_out may be NULL if only the other is required. If @target points to
+ * a non-NULL device node pointer, only entries targeting that node will be
+ * matched; if it points to a NULL value, it will receive the device node of
+ * the first matching target phandle, with a reference held.
+ *
+ * Return: 0 on success or a standard error code on failure.
+ */
+int of_pci_map_rid(struct device_node *np, u32 rid,
+ const char *map_name, const char *map_mask_name,
+ struct device_node **target, u32 *id_out)
+{
+ u32 map_mask, masked_rid;
+ int map_len;
+ const __be32 *map = NULL;
+
+ if (!np || !map_name || (!target && !id_out))
+ return -EINVAL;
+
+ map = of_get_property(np, map_name, &map_len);
+ if (!map) {
+ if (target)
+ return -ENODEV;
+ /* Otherwise, no map implies no translation */
+ *id_out = rid;
+ return 0;
+ }
+
+ if (!map_len || map_len % (4 * sizeof(*map))) {
+ pr_err("%pOF: Error: Bad %s length: %d\n", np,
+ map_name, map_len);
+ return -EINVAL;
+ }
+
+ /* The default is to select all bits. */
+ map_mask = 0xffffffff;
+
+ /*
+ * Can be overridden by "{iommu,msi}-map-mask" property.
+ * If of_property_read_u32() fails, the default is used.
+ */
+ if (map_mask_name)
+ of_property_read_u32(np, map_mask_name, &map_mask);
+
+ masked_rid = map_mask & rid;
+ for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {
+ struct device_node *phandle_node;
+ u32 rid_base = be32_to_cpup(map + 0);
+ u32 phandle = be32_to_cpup(map + 1);
+ u32 out_base = be32_to_cpup(map + 2);
+ u32 rid_len = be32_to_cpup(map + 3);
+
+ if (rid_base & ~map_mask) {
+ pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n",
+ np, map_name, map_name,
+ map_mask, rid_base);
+ return -EFAULT;
+ }
+
+ if (masked_rid < rid_base || masked_rid >= rid_base + rid_len)
+ continue;
+
+ phandle_node = of_find_node_by_phandle(phandle);
+ if (!phandle_node)
+ return -ENODEV;
+
+ if (target) {
+ if (*target)
+ of_node_put(phandle_node);
+ else
+ *target = phandle_node;
+
+ if (*target != phandle_node)
+ continue;
+ }
+
+ if (id_out)
+ *id_out = masked_rid - rid_base + out_base;
+
+ pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n",
+ np, map_name, map_mask, rid_base, out_base,
+ rid_len, rid, masked_rid - rid_base + out_base);
+ return 0;
+ }
+
+ pr_err("%pOF: Invalid %s translation - no match for rid 0x%x on %pOF\n",
+ np, map_name, rid, target && *target ? *target : NULL);
+ return -EFAULT;
+}
+
+#if IS_ENABLED(CONFIG_OF_IRQ)
+/**
+ * of_irq_parse_pci - Resolve the interrupt for a PCI device
+ * @pdev: the device whose interrupt is to be resolved
+ * @out_irq: structure of_irq filled by this function
+ *
+ * This function resolves the PCI interrupt for a given PCI device. If a
+ * device-node exists for a given pci_dev, it will use normal OF tree
+ * walking. If not, it will implement standard swizzling and walk up the
+ * PCI tree until an device-node is found, at which point it will finish
+ * resolving using the OF tree walking.
+ */
+static int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
+{
+ struct device_node *dn, *ppnode;
+ struct pci_dev *ppdev;
+ __be32 laddr[3];
+ u8 pin;
+ int rc;
+
+ /*
+ * Check if we have a device node, if yes, fallback to standard
+ * device tree parsing
+ */
+ dn = pci_device_to_OF_node(pdev);
+ if (dn) {
+ rc = of_irq_parse_one(dn, 0, out_irq);
+ if (!rc)
+ return rc;
+ }
+
+ /*
+ * Ok, we don't, time to have fun. Let's start by building up an
+ * interrupt spec. we assume #interrupt-cells is 1, which is standard
+ * for PCI. If you do different, then don't use that routine.
+ */
+ rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
+ if (rc != 0)
+ goto err;
+ /* No pin, exit with no error message. */
+ if (pin == 0)
+ return -ENODEV;
+
+ /* Now we walk up the PCI tree */
+ for (;;) {
+ /* Get the pci_dev of our parent */
+ ppdev = pdev->bus->self;
+
+ /* Ouch, it's a host bridge... */
+ if (ppdev == NULL) {
+ ppnode = pci_bus_to_OF_node(pdev->bus);
+
+ /* No node for host bridge ? give up */
+ if (ppnode == NULL) {
+ rc = -EINVAL;
+ goto err;
+ }
+ } else {
+ /* We found a P2P bridge, check if it has a node */
+ ppnode = pci_device_to_OF_node(ppdev);
+ }
+
+ /*
+ * Ok, we have found a parent with a device-node, hand over to
+ * the OF parsing code.
+ * We build a unit address from the linux device to be used for
+ * resolution. Note that we use the linux bus number which may
+ * not match your firmware bus numbering.
+ * Fortunately, in most cases, interrupt-map-mask doesn't
+ * include the bus number as part of the matching.
+ * You should still be careful about that though if you intend
+ * to rely on this function (you ship a firmware that doesn't
+ * create device nodes for all PCI devices).
+ */
+ if (ppnode)
+ break;
+
+ /*
+ * We can only get here if we hit a P2P bridge with no node;
+ * let's do standard swizzling and try again
+ */
+ pin = pci_swizzle_interrupt_pin(pdev, pin);
+ pdev = ppdev;
+ }
+
+ out_irq->np = ppnode;
+ out_irq->args_count = 1;
+ out_irq->args[0] = pin;
+ laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
+ laddr[1] = laddr[2] = cpu_to_be32(0);
+ rc = of_irq_parse_raw(laddr, out_irq);
+ if (rc)
+ goto err;
+ return 0;
+err:
+ if (rc == -ENOENT) {
+ dev_warn(&pdev->dev,
+ "%s: no interrupt-map found, INTx interrupts not available\n",
+ __func__);
+ pr_warn_once("%s: possibly some PCI slots don't have level triggered interrupts capability\n",
+ __func__);
+ } else {
+ dev_err(&pdev->dev, "%s: failed with rc=%d\n", __func__, rc);
+ }
+ return rc;
+}
+
+/**
+ * of_irq_parse_and_map_pci() - Decode a PCI IRQ from the device tree and map to a VIRQ
+ * @dev: The PCI device needing an IRQ
+ * @slot: PCI slot number; passed when used as map_irq callback. Unused
+ * @pin: PCI IRQ pin number; passed when used as map_irq callback. Unused
+ *
+ * @slot and @pin are unused, but included in the function so that this
+ * function can be used directly as the map_irq callback to
+ * pci_assign_irq() and struct pci_host_bridge.map_irq pointer
+ */
+int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ struct of_phandle_args oirq;
+ int ret;
+
+ ret = of_irq_parse_pci(dev, &oirq);
+ if (ret)
+ return 0; /* Proper return code 0 == NO_IRQ */
+
+ return irq_create_of_mapping(&oirq);
+}
+EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
+#endif /* CONFIG_OF_IRQ */
+
+int pci_parse_request_of_pci_ranges(struct device *dev,
+ struct list_head *resources,
+ struct resource **bus_range)
+{
+ int err, res_valid = 0;
+ struct device_node *np = dev->of_node;
+ resource_size_t iobase;
+ struct resource_entry *win, *tmp;
+
+ INIT_LIST_HEAD(resources);
+ err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase);
+ if (err)
+ return err;
+
+ err = devm_request_pci_bus_resources(dev, resources);
+ if (err)
+ goto out_release_res;
+
+ resource_list_for_each_entry_safe(win, tmp, resources) {
+ struct resource *res = win->res;
+
+ switch (resource_type(res)) {
+ case IORESOURCE_IO:
+ err = pci_remap_iospace(res, iobase);
+ if (err) {
+ dev_warn(dev, "error %d: failed to map resource %pR\n",
+ err, res);
+ resource_list_destroy_entry(win);
+ }
+ break;
+ case IORESOURCE_MEM:
+ res_valid |= !(res->flags & IORESOURCE_PREFETCH);
+ break;
+ case IORESOURCE_BUS:
+ if (bus_range)
+ *bus_range = res;
+ break;
+ }
+ }
+
+ if (res_valid)
+ return 0;
+
+ dev_err(dev, "non-prefetchable memory resource required\n");
+ err = -EINVAL;
+
+ out_release_res:
+ pci_free_resource_list(resources);
+ return err;
+}
+
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 4708eb9df71b..78157688dcc9 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* File: pci-acpi.c
* Purpose: Provide PCI support in ACPI
@@ -542,7 +543,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
}
if (!error)
- dev_dbg(&dev->dev, "power state changed by ACPI to %s\n",
+ pci_dbg(dev, "power state changed by ACPI to %s\n",
acpi_power_state_string(state_conv[state]));
return error;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 5958c8dda4e3..3bed6beda051 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1,11 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/pci-driver.c
*
* (C) Copyright 2002-2004, 2007 Greg Kroah-Hartman <greg@kroah.com>
* (C) Copyright 2007 Novell Inc.
- *
- * Released under the GPL v2 only.
- *
*/
#include <linux/pci.h>
diff --git a/drivers/pci/pci-mid.c b/drivers/pci/pci-mid.c
index a4ac940c7696..314e135014dc 100644
--- a/drivers/pci/pci-mid.c
+++ b/drivers/pci/pci-mid.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Intel MID platform PM support
*
* Copyright (C) 2016, Intel Corporation
*
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
*/
#include <linux/init.h>
diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c
index 886fb3570278..10d54f939048 100644
--- a/drivers/pci/pci-stub.c
+++ b/drivers/pci/pci-stub.c
@@ -1,11 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/* pci-stub - simple stub driver to reserve a pci device
*
* Copyright (C) 2008 Red Hat, Inc.
* Author:
* Chris Wright
*
- * This work is licensed under the terms of the GNU GPL, version 2.
- *
* Usage is simple, allocate a new id to the stub driver and bind the
* device to it. For example:
*
@@ -28,7 +27,7 @@ MODULE_PARM_DESC(ids, "Initial PCI IDs to add to the stub driver, format is "
static int pci_stub_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
- dev_info(&dev->dev, "claimed by stub\n");
+ pci_info(dev, "claimed by stub\n");
return 0;
}
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 06c7f0b85cd2..eb6bee8724cc 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -278,6 +278,16 @@ static ssize_t subordinate_bus_number_show(struct device *dev,
}
static DEVICE_ATTR_RO(subordinate_bus_number);
+static ssize_t ari_enabled_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
+
+ return sprintf(buf, "%u\n", pci_ari_enabled(pci_dev->bus));
+}
+static DEVICE_ATTR_RO(ari_enabled);
+
static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -348,7 +358,7 @@ static ssize_t numa_node_store(struct device *dev,
return -EINVAL;
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
- dev_alert(&pdev->dev, FW_BUG "Overriding NUMA node to %d. Contact your vendor for updates.",
+ pci_alert(pdev, FW_BUG "Overriding NUMA node to %d. Contact your vendor for updates.",
node);
dev->numa_node = node;
@@ -411,7 +421,7 @@ static ssize_t msi_bus_store(struct device *dev, struct device_attribute *attr,
*/
if (!subordinate) {
pdev->no_msi = !val;
- dev_info(&pdev->dev, "MSI/MSI-X %s for future drivers\n",
+ pci_info(pdev, "MSI/MSI-X %s for future drivers\n",
val ? "allowed" : "disallowed");
return count;
}
@@ -613,7 +623,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
/* is PF driver loaded w/callback */
if (!pdev->driver || !pdev->driver->sriov_configure) {
- dev_info(&pdev->dev, "Driver doesn't support SRIOV configuration via sysfs\n");
+ pci_info(pdev, "Driver doesn't support SRIOV configuration via sysfs\n");
ret = -ENOENT;
goto exit;
}
@@ -626,7 +636,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
/* enable VFs */
if (pdev->sriov->num_VFs) {
- dev_warn(&pdev->dev, "%d VFs already enabled. Disable before enabling %d VFs\n",
+ pci_warn(pdev, "%d VFs already enabled. Disable before enabling %d VFs\n",
pdev->sriov->num_VFs, num_vfs);
ret = -EBUSY;
goto exit;
@@ -637,7 +647,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
goto exit;
if (ret != num_vfs)
- dev_warn(&pdev->dev, "%d VFs requested; only %d enabled\n",
+ pci_warn(pdev, "%d VFs requested; only %d enabled\n",
num_vfs, ret);
exit:
@@ -786,6 +796,7 @@ static struct attribute *pci_dev_attrs[] = {
&dev_attr_devspec.attr,
#endif
&dev_attr_driver_override.attr,
+ &dev_attr_ari_enabled.attr,
NULL,
};
@@ -1216,14 +1227,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
return -EINVAL;
- if (!pci_mmap_fits(pdev, bar, vma, PCI_MMAP_SYSFS)) {
- WARN(1, "process \"%s\" tried to map 0x%08lx bytes at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
- current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
- pci_name(pdev), bar,
- (u64)pci_resource_start(pdev, bar),
- (u64)pci_resource_len(pdev, bar));
+ if (!pci_mmap_fits(pdev, bar, vma, PCI_MMAP_SYSFS))
return -EINVAL;
- }
+
mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
return pci_mmap_resource_range(pdev, bar, vma, mmap_type, write_combine);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 764ca7b8840d..f6a4dd10d9b0 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCI Bus Services, see include/linux/pci.h for further explanation.
*
@@ -156,7 +157,7 @@ void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar)
* Make sure the BAR is actually a memory resource, not an IO resource
*/
if (res->flags & IORESOURCE_UNSET || !(res->flags & IORESOURCE_MEM)) {
- dev_warn(&pdev->dev, "can't ioremap BAR %d: %pR\n", bar, res);
+ pci_warn(pdev, "can't ioremap BAR %d: %pR\n", bar, res);
return NULL;
}
return ioremap_nocache(res->start, resource_size(res));
@@ -648,7 +649,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
*/
if (state != PCI_D0 && dev->current_state <= PCI_D3cold
&& dev->current_state > state) {
- dev_err(&dev->dev, "invalid power transition (from state %d to %d)\n",
+ pci_err(dev, "invalid power transition (from state %d to %d)\n",
dev->current_state, state);
return -EINVAL;
}
@@ -696,7 +697,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
if (dev->current_state != state && printk_ratelimit())
- dev_info(&dev->dev, "Refused to change power state, currently in D%d\n",
+ pci_info(dev, "Refused to change power state, currently in D%d\n",
dev->current_state);
/*
@@ -970,7 +971,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
case PM_EVENT_HIBERNATE:
return PCI_D3hot;
default:
- dev_info(&dev->dev, "unrecognized suspend event %d\n",
+ pci_info(dev, "unrecognized suspend event %d\n",
state.event);
BUG();
}
@@ -1013,7 +1014,7 @@ static int pci_save_pcie_state(struct pci_dev *dev)
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
if (!save_state) {
- dev_err(&dev->dev, "buffer not found in %s\n", __func__);
+ pci_err(dev, "buffer not found in %s\n", __func__);
return -ENOMEM;
}
@@ -1061,7 +1062,7 @@ static int pci_save_pcix_state(struct pci_dev *dev)
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
if (!save_state) {
- dev_err(&dev->dev, "buffer not found in %s\n", __func__);
+ pci_err(dev, "buffer not found in %s\n", __func__);
return -ENOMEM;
}
@@ -1121,7 +1122,7 @@ static void pci_restore_config_dword(struct pci_dev *pdev, int offset,
return;
for (;;) {
- dev_dbg(&pdev->dev, "restoring config space at offset %#x (was %#x, writing %#x)\n",
+ pci_dbg(pdev, "restoring config space at offset %#x (was %#x, writing %#x)\n",
offset, val, saved_val);
pci_write_config_dword(pdev, offset, saved_val);
if (retry-- <= 0)
@@ -1358,7 +1359,7 @@ static void pci_enable_bridge(struct pci_dev *dev)
retval = pci_enable_device(dev);
if (retval)
- dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n",
+ pci_err(dev, "Error enabling bridge (%d), continuing\n",
retval);
pci_set_master(dev);
}
@@ -1867,7 +1868,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
pme_dev = kmalloc(sizeof(struct pci_pme_device),
GFP_KERNEL);
if (!pme_dev) {
- dev_warn(&dev->dev, "can't enable PME#\n");
+ pci_warn(dev, "can't enable PME#\n");
return;
}
pme_dev->dev = dev;
@@ -1891,7 +1892,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
}
}
- dev_dbg(&dev->dev, "PME# %s\n", enable ? "enabled" : "disabled");
+ pci_dbg(dev, "PME# %s\n", enable ? "enabled" : "disabled");
}
EXPORT_SYMBOL(pci_pme_active);
@@ -2428,7 +2429,7 @@ void pci_pm_init(struct pci_dev *dev)
pci_read_config_word(dev, pm + PCI_PM_PMC, &pmc);
if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
- dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n",
+ pci_err(dev, "unsupported PM cap regs version (%u)\n",
pmc & PCI_PM_CAP_VER_MASK);
return;
}
@@ -2448,15 +2449,14 @@ void pci_pm_init(struct pci_dev *dev)
dev->d2_support = true;
if (dev->d1_support || dev->d2_support)
- dev_printk(KERN_DEBUG, &dev->dev, "supports%s%s\n",
+ pci_printk(KERN_DEBUG, dev, "supports%s%s\n",
dev->d1_support ? " D1" : "",
dev->d2_support ? " D2" : "");
}
pmc &= PCI_PM_CAP_PME_MASK;
if (pmc) {
- dev_printk(KERN_DEBUG, &dev->dev,
- "PME# supported from%s%s%s%s%s\n",
+ pci_printk(KERN_DEBUG, dev, "PME# supported from%s%s%s%s%s\n",
(pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
(pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
(pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
@@ -2548,13 +2548,13 @@ static int pci_ea_read(struct pci_dev *dev, int offset)
res = pci_ea_get_resource(dev, bei, prop);
if (!res) {
- dev_err(&dev->dev, "Unsupported EA entry BEI: %u\n", bei);
+ pci_err(dev, "Unsupported EA entry BEI: %u\n", bei);
goto out;
}
flags = pci_ea_flags(dev, prop);
if (!flags) {
- dev_err(&dev->dev, "Unsupported EA properties: %#x\n", prop);
+ pci_err(dev, "Unsupported EA properties: %#x\n", prop);
goto out;
}
@@ -2604,13 +2604,12 @@ static int pci_ea_read(struct pci_dev *dev, int offset)
}
if (end < start) {
- dev_err(&dev->dev, "EA Entry crosses address boundary\n");
+ pci_err(dev, "EA Entry crosses address boundary\n");
goto out;
}
if (ent_size != ent_offset - offset) {
- dev_err(&dev->dev,
- "EA Entry Size (%d) does not match length read (%d)\n",
+ pci_err(dev, "EA Entry Size (%d) does not match length read (%d)\n",
ent_size, ent_offset - offset);
goto out;
}
@@ -2621,16 +2620,16 @@ static int pci_ea_read(struct pci_dev *dev, int offset)
res->flags = flags;
if (bei <= PCI_EA_BEI_BAR5)
- dev_printk(KERN_DEBUG, &dev->dev, "BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
+ pci_printk(KERN_DEBUG, dev, "BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
bei, res, prop);
else if (bei == PCI_EA_BEI_ROM)
- dev_printk(KERN_DEBUG, &dev->dev, "ROM: %pR (from Enhanced Allocation, properties %#02x)\n",
+ pci_printk(KERN_DEBUG, dev, "ROM: %pR (from Enhanced Allocation, properties %#02x)\n",
res, prop);
else if (bei >= PCI_EA_BEI_VF_BAR0 && bei <= PCI_EA_BEI_VF_BAR5)
- dev_printk(KERN_DEBUG, &dev->dev, "VF BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
+ pci_printk(KERN_DEBUG, dev, "VF BAR %d: %pR (from Enhanced Allocation, properties %#02x)\n",
bei - PCI_EA_BEI_VF_BAR0, res, prop);
else
- dev_printk(KERN_DEBUG, &dev->dev, "BEI %d res: %pR (from Enhanced Allocation, properties %#02x)\n",
+ pci_printk(KERN_DEBUG, dev, "BEI %d res: %pR (from Enhanced Allocation, properties %#02x)\n",
bei, res, prop);
out:
@@ -2727,13 +2726,11 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP,
PCI_EXP_SAVE_REGS * sizeof(u16));
if (error)
- dev_err(&dev->dev,
- "unable to preallocate PCI Express save buffer\n");
+ pci_err(dev, "unable to preallocate PCI Express save buffer\n");
error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_PCIX, sizeof(u16));
if (error)
- dev_err(&dev->dev,
- "unable to preallocate PCI-X save buffer\n");
+ pci_err(dev, "unable to preallocate PCI-X save buffer\n");
pci_allocate_vc_save_buffers(dev);
}
@@ -3070,6 +3067,81 @@ int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size)
}
/**
+ * pci_enable_atomic_ops_to_root - enable AtomicOp requests to root port
+ * @dev: the PCI device
+ * @cap_mask: mask of desired AtomicOp sizes, including one or more of:
+ * PCI_EXP_DEVCAP2_ATOMIC_COMP32
+ * PCI_EXP_DEVCAP2_ATOMIC_COMP64
+ * PCI_EXP_DEVCAP2_ATOMIC_COMP128
+ *
+ * Return 0 if all upstream bridges support AtomicOp routing, egress
+ * blocking is disabled on all upstream ports, and the root port supports
+ * the requested completion capabilities (32-bit, 64-bit and/or 128-bit
+ * AtomicOp completion), or negative otherwise.
+ */
+int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask)
+{
+ struct pci_bus *bus = dev->bus;
+ struct pci_dev *bridge;
+ u32 cap, ctl2;
+
+ if (!pci_is_pcie(dev))
+ return -EINVAL;
+
+ /*
+ * Per PCIe r4.0, sec 6.15, endpoints and root ports may be
+ * AtomicOp requesters. For now, we only support endpoints as
+ * requesters and root ports as completers. No endpoints as
+ * completers, and no peer-to-peer.
+ */
+
+ switch (pci_pcie_type(dev)) {
+ case PCI_EXP_TYPE_ENDPOINT:
+ case PCI_EXP_TYPE_LEG_END:
+ case PCI_EXP_TYPE_RC_END:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ while (bus->parent) {
+ bridge = bus->self;
+
+ pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap);
+
+ switch (pci_pcie_type(bridge)) {
+ /* Ensure switch ports support AtomicOp routing */
+ case PCI_EXP_TYPE_UPSTREAM:
+ case PCI_EXP_TYPE_DOWNSTREAM:
+ if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE))
+ return -EINVAL;
+ break;
+
+ /* Ensure root port supports all the sizes we care about */
+ case PCI_EXP_TYPE_ROOT_PORT:
+ if ((cap & cap_mask) != cap_mask)
+ return -EINVAL;
+ break;
+ }
+
+ /* Ensure upstream ports don't block AtomicOps on egress */
+ if (!bridge->has_secondary_link) {
+ pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2,
+ &ctl2);
+ if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK)
+ return -EINVAL;
+ }
+
+ bus = bus->parent;
+ }
+
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
+ PCI_EXP_DEVCTL2_ATOMIC_REQ);
+ return 0;
+}
+EXPORT_SYMBOL(pci_enable_atomic_ops_to_root);
+
+/**
* pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
* @dev: the PCI device
* @pin: the INTx pin (1=INTA, 2=INTB, 3=INTC, 4=INTD)
@@ -3202,7 +3274,7 @@ static int __pci_request_region(struct pci_dev *pdev, int bar,
return 0;
err_out:
- dev_warn(&pdev->dev, "BAR %d: can't reserve %pR\n", bar,
+ pci_warn(pdev, "BAR %d: can't reserve %pR\n", bar,
&pdev->resource[bar]);
return -EBUSY;
}
@@ -3625,7 +3697,7 @@ static void __pci_set_master(struct pci_dev *dev, bool enable)
else
cmd = old_cmd & ~PCI_COMMAND_MASTER;
if (cmd != old_cmd) {
- dev_dbg(&dev->dev, "%s bus mastering\n",
+ pci_dbg(dev, "%s bus mastering\n",
enable ? "enabling" : "disabling");
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
@@ -3726,7 +3798,7 @@ int pci_set_cacheline_size(struct pci_dev *dev)
if (cacheline_size == pci_cache_line_size)
return 0;
- dev_printk(KERN_DEBUG, &dev->dev, "cache line size of %d is not supported\n",
+ pci_printk(KERN_DEBUG, dev, "cache line size of %d is not supported\n",
pci_cache_line_size << 2);
return -EINVAL;
@@ -3755,7 +3827,7 @@ int pci_set_mwi(struct pci_dev *dev)
pci_read_config_word(dev, PCI_COMMAND, &cmd);
if (!(cmd & PCI_COMMAND_INVALIDATE)) {
- dev_dbg(&dev->dev, "enabling Mem-Wr-Inval\n");
+ pci_dbg(dev, "enabling Mem-Wr-Inval\n");
cmd |= PCI_COMMAND_INVALIDATE;
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
@@ -3972,13 +4044,13 @@ static void pci_flr_wait(struct pci_dev *dev)
pci_read_config_dword(dev, PCI_COMMAND, &id);
while (id == ~0) {
if (delay > timeout) {
- dev_warn(&dev->dev, "not ready %dms after FLR; giving up\n",
+ pci_warn(dev, "not ready %dms after FLR; giving up\n",
100 + delay - 1);
return;
}
if (delay > 1000)
- dev_info(&dev->dev, "not ready %dms after FLR; waiting\n",
+ pci_info(dev, "not ready %dms after FLR; waiting\n",
100 + delay - 1);
msleep(delay);
@@ -3987,7 +4059,7 @@ static void pci_flr_wait(struct pci_dev *dev)
}
if (delay > 1000)
- dev_info(&dev->dev, "ready %dms after FLR\n", 100 + delay - 1);
+ pci_info(dev, "ready %dms after FLR\n", 100 + delay - 1);
}
/**
@@ -4019,7 +4091,7 @@ static bool pcie_has_flr(struct pci_dev *dev)
void pcie_flr(struct pci_dev *dev)
{
if (!pci_wait_for_pending_transaction(dev))
- dev_err(&dev->dev, "timed out waiting for pending transaction; performing function level reset anyway\n");
+ pci_err(dev, "timed out waiting for pending transaction; performing function level reset anyway\n");
pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
pci_flr_wait(dev);
@@ -4052,7 +4124,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe)
*/
if (!pci_wait_for_pending(dev, pos + PCI_AF_CTRL,
PCI_AF_STATUS_TP << 8))
- dev_err(&dev->dev, "timed out waiting for pending transaction; performing AF function level reset anyway\n");
+ pci_err(dev, "timed out waiting for pending transaction; performing AF function level reset anyway\n");
pci_write_config_byte(dev, pos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
pci_flr_wait(dev);
@@ -5175,12 +5247,12 @@ void pci_add_dma_alias(struct pci_dev *dev, u8 devfn)
dev->dma_alias_mask = kcalloc(BITS_TO_LONGS(U8_MAX),
sizeof(long), GFP_KERNEL);
if (!dev->dma_alias_mask) {
- dev_warn(&dev->dev, "Unable to allocate DMA alias mask\n");
+ pci_warn(dev, "Unable to allocate DMA alias mask\n");
return;
}
set_bit(devfn, dev->dma_alias_mask);
- dev_info(&dev->dev, "Enabling fixed DMA alias to %02x.%d\n",
+ pci_info(dev, "Enabling fixed DMA alias to %02x.%d\n",
PCI_SLOT(devfn), PCI_FUNC(devfn));
}
@@ -5329,7 +5401,7 @@ static void pci_request_resource_alignment(struct pci_dev *dev, int bar,
return;
if (r->flags & IORESOURCE_PCI_FIXED) {
- dev_info(&dev->dev, "BAR%d %pR: ignoring requested alignment %#llx\n",
+ pci_info(dev, "BAR%d %pR: ignoring requested alignment %#llx\n",
bar, r, (unsigned long long)align);
return;
}
@@ -5366,7 +5438,7 @@ static void pci_request_resource_alignment(struct pci_dev *dev, int bar,
* devices and we use the second.
*/
- dev_info(&dev->dev, "BAR%d %pR: requesting alignment to %#llx\n",
+ pci_info(dev, "BAR%d %pR: requesting alignment to %#llx\n",
bar, r, (unsigned long long)align);
if (resize) {
@@ -5412,13 +5484,11 @@ void pci_reassigndev_resource_alignment(struct pci_dev *dev)
if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
(dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
- dev_warn(&dev->dev,
- "Can't reassign resources to host bridge.\n");
+ pci_warn(dev, "Can't reassign resources to host bridge\n");
return;
}
- dev_info(&dev->dev,
- "Disabling memory decoding and releasing memory resources.\n");
+ pci_info(dev, "Disabling memory decoding and releasing memory resources\n");
pci_read_config_word(dev, PCI_COMMAND, &command);
command &= ~PCI_COMMAND_MEMORY;
pci_write_config_word(dev, PCI_COMMAND, command);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index f6b58b32a67c..fcd81911b127 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -38,21 +38,21 @@ int pci_probe_reset_function(struct pci_dev *dev);
* struct pci_platform_pm_ops - Firmware PM callbacks
*
* @is_manageable: returns 'true' if given device is power manageable by the
- * platform firmware
+ * platform firmware
*
* @set_state: invokes the platform firmware to set the device's power state
*
* @get_state: queries the platform firmware for a device's current power state
*
* @choose_state: returns PCI power state of given device preferred by the
- * platform; to be used during system-wide transitions from a
- * sleeping state to the working state and vice versa
+ * platform; to be used during system-wide transitions from a
+ * sleeping state to the working state and vice versa
*
* @set_wakeup: enables/disables wakeup capability for the device
*
* @need_resume: returns 'true' if the given device (which is currently
- * suspended) needs to be resumed to be configured for system
- * wakeup.
+ * suspended) needs to be resumed to be configured for system
+ * wakeup.
*
* If given platform is generally capable of power managing PCI devices, all of
* these callbacks are mandatory.
@@ -112,7 +112,7 @@ struct pci_vpd_ops {
struct pci_vpd {
const struct pci_vpd_ops *ops;
- struct bin_attribute *attr; /* descriptor for sysfs VPD entry */
+ struct bin_attribute *attr; /* Descriptor for sysfs VPD entry */
struct mutex lock;
unsigned int len;
u16 flag;
@@ -199,7 +199,7 @@ extern const struct attribute_group *pci_bus_groups[];
/**
* pci_match_one_device - Tell if a PCI device structure has a matching
- * PCI device id structure
+ * PCI device id structure
* @id: single PCI device id structure to match
* @dev: the PCI device structure to match against
*
@@ -231,7 +231,7 @@ struct pci_slot_attribute {
enum pci_bar_type {
pci_bar_unknown, /* Standard PCI BAR probe */
- pci_bar_io, /* An io port BAR */
+ pci_bar_io, /* An I/O port BAR */
pci_bar_mem32, /* A 32-bit memory BAR */
pci_bar_mem64, /* A 64-bit memory BAR */
};
@@ -255,24 +255,24 @@ void pci_disable_bridge_window(struct pci_dev *dev);
/* Single Root I/O Virtualization */
struct pci_sriov {
- int pos; /* capability position */
- int nres; /* number of resources */
- u32 cap; /* SR-IOV Capabilities */
- u16 ctrl; /* SR-IOV Control */
- u16 total_VFs; /* total VFs associated with the PF */
- u16 initial_VFs; /* initial VFs associated with the PF */
- u16 num_VFs; /* number of VFs available */
- u16 offset; /* first VF Routing ID offset */
- u16 stride; /* following VF stride */
- u16 vf_device; /* VF device ID */
- u32 pgsz; /* page size for BAR alignment */
- u8 link; /* Function Dependency Link */
- u8 max_VF_buses; /* max buses consumed by VFs */
- u16 driver_max_VFs; /* max num VFs driver supports */
- struct pci_dev *dev; /* lowest numbered PF */
- struct pci_dev *self; /* this PF */
- resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */
- bool drivers_autoprobe; /* auto probing of VFs by driver */
+ int pos; /* Capability position */
+ int nres; /* Number of resources */
+ u32 cap; /* SR-IOV Capabilities */
+ u16 ctrl; /* SR-IOV Control */
+ u16 total_VFs; /* Total VFs associated with the PF */
+ u16 initial_VFs; /* Initial VFs associated with the PF */
+ u16 num_VFs; /* Number of VFs available */
+ u16 offset; /* First VF Routing ID offset */
+ u16 stride; /* Following VF stride */
+ u16 vf_device; /* VF device ID */
+ u32 pgsz; /* Page size for BAR alignment */
+ u8 link; /* Function Dependency Link */
+ u8 max_VF_buses; /* Max buses consumed by VFs */
+ u16 driver_max_VFs; /* Max num VFs driver supports */
+ struct pci_dev *dev; /* Lowest numbered PF */
+ struct pci_dev *self; /* This PF */
+ resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */
+ bool drivers_autoprobe; /* Auto probing of VFs by driver */
};
/* pci_dev priv_flags */
@@ -335,13 +335,33 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
return pci_sriov_resource_alignment(dev, resno);
#endif
- if (dev->class >> 8 == PCI_CLASS_BRIDGE_CARDBUS)
+ if (dev->class >> 8 == PCI_CLASS_BRIDGE_CARDBUS)
return pci_cardbus_resource_alignment(res);
return resource_alignment(res);
}
void pci_enable_acs(struct pci_dev *dev);
+#ifdef CONFIG_PCIEASPM
+void pcie_aspm_init_link_state(struct pci_dev *pdev);
+void pcie_aspm_exit_link_state(struct pci_dev *pdev);
+void pcie_aspm_pm_state_change(struct pci_dev *pdev);
+void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
+#else
+static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) { }
+static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev) { }
+static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) { }
+static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev) { }
+#endif
+
+#ifdef CONFIG_PCIEASPM_DEBUG
+void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev);
+void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev);
+#else
+static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) { }
+static inline void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) { }
+#endif
+
#ifdef CONFIG_PCIE_PTM
void pci_ptm_init(struct pci_dev *dev);
#else
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index ac53edbc9613..b12e28b3d8f9 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# PCI Express Port Bus Configuration
#
@@ -92,7 +93,7 @@ config PCIE_PME
config PCIE_DPC
bool "PCIe Downstream Port Containment support"
- depends on PCIEPORTBUS
+ depends on PCIEPORTBUS && PCIEAER
default n
help
This enables PCI Express Downstream Port Containment (DPC)
diff --git a/drivers/pci/pcie/aer/Kconfig b/drivers/pci/pcie/aer/Kconfig
index 7d1437b01fdd..5a64eb3d6c7a 100644
--- a/drivers/pci/pcie/aer/Kconfig
+++ b/drivers/pci/pcie/aer/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# PCI Express Root Port Device AER Configuration
#
diff --git a/drivers/pci/pcie/aer/Kconfig.debug b/drivers/pci/pcie/aer/Kconfig.debug
index 9142949734f5..67e02174b65b 100644
--- a/drivers/pci/pcie/aer/Kconfig.debug
+++ b/drivers/pci/pcie/aer/Kconfig.debug
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# PCI Express Root Port Device AER Debug Configuration
#
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 2b6a59266689..25e1feb962c5 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe AER software error injection support.
*
@@ -9,12 +10,6 @@
*
* Copyright 2009 Intel Corporation.
* 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
- * as published by the Free Software Foundation; version 2
- * of the License.
- *
*/
#include <linux/module.h>
@@ -344,14 +339,14 @@ static int aer_inject(struct aer_error_inj *einj)
return -ENODEV;
rpdev = pcie_find_root_port(dev);
if (!rpdev) {
- dev_err(&dev->dev, "aer_inject: Root port not found\n");
+ pci_err(dev, "aer_inject: Root port not found\n");
ret = -ENODEV;
goto out_put;
}
pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos_cap_err) {
- dev_err(&dev->dev, "aer_inject: Device doesn't support AER\n");
+ pci_err(dev, "aer_inject: Device doesn't support AER\n");
ret = -EPROTONOSUPPORT;
goto out_put;
}
@@ -362,8 +357,7 @@ static int aer_inject(struct aer_error_inj *einj)
rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR);
if (!rp_pos_cap_err) {
- dev_err(&rpdev->dev,
- "aer_inject: Root port doesn't support AER\n");
+ pci_err(rpdev, "aer_inject: Root port doesn't support AER\n");
ret = -EPROTONOSUPPORT;
goto out_put;
}
@@ -411,16 +405,14 @@ static int aer_inject(struct aer_error_inj *einj)
if (!aer_mask_override && einj->cor_status &&
!(einj->cor_status & ~cor_mask)) {
ret = -EINVAL;
- dev_warn(&dev->dev,
- "aer_inject: The correctable error(s) is masked by device\n");
+ pci_warn(dev, "aer_inject: The correctable error(s) is masked by device\n");
spin_unlock_irqrestore(&inject_lock, flags);
goto out_put;
}
if (!aer_mask_override && einj->uncor_status &&
!(einj->uncor_status & ~uncor_mask)) {
ret = -EINVAL;
- dev_warn(&dev->dev,
- "aer_inject: The uncorrectable error(s) is masked by device\n");
+ pci_warn(dev, "aer_inject: The uncorrectable error(s) is masked by device\n");
spin_unlock_irqrestore(&inject_lock, flags);
goto out_put;
}
@@ -483,7 +475,7 @@ static int aer_inject(struct aer_error_inj *einj)
einj->cor_status, einj->uncor_status, pci_name(dev));
aer_irq(-1, edev);
} else {
- dev_err(&rpdev->dev, "aer_inject: AER device not found\n");
+ pci_err(rpdev, "aer_inject: AER device not found\n");
ret = -ENODEV;
}
out_put:
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 6ff5f5b4f5e6..da8331f5684d 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/pcie/aer/aerdrv.c
*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
* This file implements the AER root port service driver. The driver will
* register an irq handler. When root port triggers an AER interrupt, the irq
* handler will collect root port status and schedule a work.
@@ -326,7 +323,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, reg32);
pci_reset_bridge_secondary_bus(dev);
- dev_printk(KERN_DEBUG, &dev->dev, "Root Port link has been reset\n");
+ pci_printk(KERN_DEBUG, dev, "Root Port link has been reset\n");
/* Clear Root Error Status */
pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 8d7448063fd1..a4bfea52e7d4 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/pcie/aer/aerdrv_core.c
*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
* This file implements the core part of PCIe AER. When a PCIe
* error is delivered, an error message will be collected and printed to
* console, then, an error recovery procedure will be executed by following
@@ -226,9 +223,8 @@ static bool find_source_device(struct pci_dev *parent,
pci_walk_bus(parent->subordinate, find_device_iter, e_info);
if (!e_info->error_dev_num) {
- dev_printk(KERN_DEBUG, &parent->dev,
- "can't find device of ID%04x\n",
- e_info->id);
+ pci_printk(KERN_DEBUG, parent, "can't find device of ID%04x\n",
+ e_info->id);
return false;
}
return true;
@@ -256,7 +252,7 @@ static int report_error_detected(struct pci_dev *dev, void *data)
* of a driver for this device is unaware of
* its hw state.
*/
- dev_printk(KERN_DEBUG, &dev->dev, "device has %s\n",
+ pci_printk(KERN_DEBUG, dev, "device has %s\n",
dev->driver ?
"no AER-aware driver" : "no driver");
}
@@ -366,7 +362,7 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
{
struct aer_broadcast_data result_data;
- dev_printk(KERN_DEBUG, &dev->dev, "broadcast %s message\n", error_mesg);
+ pci_printk(KERN_DEBUG, dev, "broadcast %s message\n", error_mesg);
result_data.state = state;
if (cb == report_error_detected)
result_data.result = PCI_ERS_RESULT_CAN_RECOVER;
@@ -415,7 +411,7 @@ static pci_ers_result_t broadcast_error_message(struct pci_dev *dev,
static pci_ers_result_t default_reset_link(struct pci_dev *dev)
{
pci_reset_bridge_secondary_bus(dev);
- dev_printk(KERN_DEBUG, &dev->dev, "downstream link has been reset\n");
+ pci_printk(KERN_DEBUG, dev, "downstream link has been reset\n");
return PCI_ERS_RESULT_RECOVERED;
}
@@ -467,15 +463,13 @@ static pci_ers_result_t reset_link(struct pci_dev *dev)
} else if (udev->has_secondary_link) {
status = default_reset_link(udev);
} else {
- dev_printk(KERN_DEBUG, &dev->dev,
- "no link-reset support at upstream device %s\n",
+ pci_printk(KERN_DEBUG, dev, "no link-reset support at upstream device %s\n",
pci_name(udev));
return PCI_ERS_RESULT_DISCONNECT;
}
if (status != PCI_ERS_RESULT_RECOVERED) {
- dev_printk(KERN_DEBUG, &dev->dev,
- "link reset at upstream device %s failed\n",
+ pci_printk(KERN_DEBUG, dev, "link reset at upstream device %s failed\n",
pci_name(udev));
return PCI_ERS_RESULT_DISCONNECT;
}
@@ -539,13 +533,13 @@ static void do_recovery(struct pci_dev *dev, int severity)
"resume",
report_resume);
- dev_info(&dev->dev, "AER: Device recovery successful\n");
+ pci_info(dev, "AER: Device recovery successful\n");
return;
failed:
pci_uevent_ers(dev, PCI_ERS_RESULT_DISCONNECT);
/* TODO: Should kernel panic here? */
- dev_info(&dev->dev, "AER: Device recovery failed\n");
+ pci_info(dev, "AER: Device recovery failed\n");
}
/**
@@ -636,7 +630,8 @@ static void aer_recover_work_func(struct work_struct *work)
continue;
}
cper_print_aer(pdev, entry.severity, entry.regs);
- do_recovery(pdev, entry.severity);
+ if (entry.severity != AER_CORRECTABLE)
+ do_recovery(pdev, entry.severity);
pci_dev_put(pdev);
}
}
@@ -663,7 +658,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
/* The device might not support AER */
if (!pos)
- return 1;
+ return 0;
if (info->severity == AER_CORRECTABLE) {
pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS,
diff --git a/drivers/pci/pcie/aer/aerdrv_errprint.c b/drivers/pci/pcie/aer/aerdrv_errprint.c
index 54c4b691e51f..6a352e638699 100644
--- a/drivers/pci/pcie/aer/aerdrv_errprint.c
+++ b/drivers/pci/pcie/aer/aerdrv_errprint.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/pcie/aer/aerdrv_errprint.c
*
- * 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.
- *
* Format error messages and print them to console.
*
* Copyright (C) 2006 Intel Corp.
@@ -132,7 +129,7 @@ static const char *aer_agent_string[] = {
static void __print_tlp_header(struct pci_dev *dev,
struct aer_header_log_regs *t)
{
- dev_err(&dev->dev, " TLP Header: %08x %08x %08x %08x\n",
+ pci_err(dev, " TLP Header: %08x %08x %08x %08x\n",
t->dw0, t->dw1, t->dw2, t->dw3);
}
@@ -155,10 +152,10 @@ static void __aer_print_error(struct pci_dev *dev,
aer_uncorrectable_error_string[i] : NULL;
if (errmsg)
- dev_err(&dev->dev, " [%2d] %-22s%s\n", i, errmsg,
+ pci_err(dev, " [%2d] %-22s%s\n", i, errmsg,
info->first_error == i ? " (First)" : "");
else
- dev_err(&dev->dev, " [%2d] Unknown Error Bit%s\n",
+ pci_err(dev, " [%2d] Unknown Error Bit%s\n",
i, info->first_error == i ? " (First)" : "");
}
}
@@ -169,7 +166,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
int id = ((dev->bus->number << 8) | dev->devfn);
if (!info->status) {
- dev_err(&dev->dev, "PCIe Bus Error: severity=%s, type=Unaccessible, id=%04x(Unregistered Agent ID)\n",
+ pci_err(dev, "PCIe Bus Error: severity=%s, type=Unaccessible, id=%04x(Unregistered Agent ID)\n",
aer_error_severity_string[info->severity], id);
goto out;
}
@@ -177,11 +174,11 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
layer = AER_GET_LAYER_ERROR(info->severity, info->status);
agent = AER_GET_AGENT(info->severity, info->status);
- dev_err(&dev->dev, "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n",
+ pci_err(dev, "PCIe Bus Error: severity=%s, type=%s, id=%04x(%s)\n",
aer_error_severity_string[info->severity],
aer_error_layer[layer], id, aer_agent_string[agent]);
- dev_err(&dev->dev, " device [%04x:%04x] error status/mask=%08x/%08x\n",
+ pci_err(dev, " device [%04x:%04x] error status/mask=%08x/%08x\n",
dev->vendor, dev->device,
info->status, info->mask);
@@ -192,7 +189,7 @@ void aer_print_error(struct pci_dev *dev, struct aer_err_info *info)
out:
if (info->id && info->error_dev_num > 1 && info->id == id)
- dev_err(&dev->dev, " Error of this Agent(%04x) is reported first\n", id);
+ pci_err(dev, " Error of this Agent(%04x) is reported first\n", id);
trace_aer_event(dev_name(&dev->dev), (info->status & ~info->mask),
info->severity);
@@ -200,7 +197,7 @@ out:
void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info)
{
- dev_info(&dev->dev, "AER: %s%s error received: id=%04x\n",
+ pci_info(dev, "AER: %s%s error received: id=%04x\n",
info->multi_error_valid ? "Multiple " : "",
aer_error_severity_string[info->severity], info->id);
}
@@ -242,13 +239,13 @@ void cper_print_aer(struct pci_dev *dev, int aer_severity,
layer = AER_GET_LAYER_ERROR(aer_severity, status);
agent = AER_GET_AGENT(aer_severity, status);
- dev_err(&dev->dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", status, mask);
+ pci_err(dev, "aer_status: 0x%08x, aer_mask: 0x%08x\n", status, mask);
cper_print_bits("", status, status_strs, status_strs_size);
- dev_err(&dev->dev, "aer_layer=%s, aer_agent=%s\n",
+ pci_err(dev, "aer_layer=%s, aer_agent=%s\n",
aer_error_layer[layer], aer_agent_string[agent]);
if (aer_severity != AER_CORRECTABLE)
- dev_err(&dev->dev, "aer_uncor_severity: 0x%08x\n",
+ pci_err(dev, "aer_uncor_severity: 0x%08x\n",
aer->uncor_severity);
if (tlp_header_valid)
diff --git a/drivers/pci/pcie/aer/ecrc.c b/drivers/pci/pcie/aer/ecrc.c
index a2747a663bc9..26d3cac9e635 100644
--- a/drivers/pci/pcie/aer/ecrc.c
+++ b/drivers/pci/pcie/aer/ecrc.c
@@ -1,23 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Enables/disables PCIe ECRC checking.
*
* (C) Copyright 2009 Hewlett-Packard Development Company, L.P.
* Andrew Patterson <andrew.patterson@hp.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/kernel.h>
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 9783e10da3a9..57feef2ecfe7 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -43,18 +43,6 @@
#define ASPM_STATE_ALL (ASPM_STATE_L0S | ASPM_STATE_L1 | \
ASPM_STATE_L1SS)
-/*
- * When L1 substates are enabled, the LTR L1.2 threshold is a timing parameter
- * that decides whether L1.1 or L1.2 is entered (Refer PCIe spec for details).
- * Not sure is there is a way to "calculate" this on the fly, but maybe we
- * could turn it into a parameter in future. This value has been taken from
- * the following files from Intel's coreboot (which is the only code I found
- * to have used this):
- * https://www.coreboot.org/pipermail/coreboot-gerrit/2015-March/021134.html
- * https://review.coreboot.org/#/c/8832/
- */
-#define LTR_L1_2_THRESHOLD_BITS ((1 << 21) | (1 << 23) | (1 << 30))
-
struct aspm_latency {
u32 l0s; /* L0s latency (nsec) */
u32 l1; /* L1 latency (nsec) */
@@ -278,7 +266,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
return;
/* Training failed. Restore common clock configurations */
- dev_err(&parent->dev, "ASPM: Could not configure common clock\n");
+ pci_err(parent, "ASPM: Could not configure common clock\n");
list_for_each_entry(child, &linkbus->devices, bus_list)
pcie_capability_write_word(child, PCI_EXP_LNKCTL,
child_reg[PCI_FUNC(child->devfn)]);
@@ -328,11 +316,36 @@ static u32 calc_l1ss_pwron(struct pci_dev *pdev, u32 scale, u32 val)
case 2:
return val * 100;
}
- dev_err(&pdev->dev, "%s: Invalid T_PwrOn scale: %u\n",
- __func__, scale);
+ pci_err(pdev, "%s: Invalid T_PwrOn scale: %u\n", __func__, scale);
return 0;
}
+static void encode_l12_threshold(u32 threshold_us, u32 *scale, u32 *value)
+{
+ u64 threshold_ns = threshold_us * 1000;
+
+ /* See PCIe r3.1, sec 7.33.3 and sec 6.18 */
+ if (threshold_ns < 32) {
+ *scale = 0;
+ *value = threshold_ns;
+ } else if (threshold_ns < 1024) {
+ *scale = 1;
+ *value = threshold_ns >> 5;
+ } else if (threshold_ns < 32768) {
+ *scale = 2;
+ *value = threshold_ns >> 10;
+ } else if (threshold_ns < 1048576) {
+ *scale = 3;
+ *value = threshold_ns >> 15;
+ } else if (threshold_ns < 33554432) {
+ *scale = 4;
+ *value = threshold_ns >> 20;
+ } else {
+ *scale = 5;
+ *value = threshold_ns >> 25;
+ }
+}
+
struct aspm_register_info {
u32 support:2;
u32 enabled:2;
@@ -443,6 +456,7 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
struct aspm_register_info *dwreg)
{
u32 val1, val2, scale1, scale2;
+ u32 t_common_mode, t_power_on, l1_2_threshold, scale, value;
link->l1ss.up_cap_ptr = upreg->l1ss_cap_ptr;
link->l1ss.dw_cap_ptr = dwreg->l1ss_cap_ptr;
@@ -454,16 +468,7 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
/* Choose the greater of the two Port Common_Mode_Restore_Times */
val1 = (upreg->l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
val2 = (dwreg->l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
- if (val1 > val2)
- link->l1ss.ctl1 |= val1 << 8;
- else
- link->l1ss.ctl1 |= val2 << 8;
-
- /*
- * We currently use LTR L1.2 threshold to be fixed constant picked from
- * Intel's coreboot.
- */
- link->l1ss.ctl1 |= LTR_L1_2_THRESHOLD_BITS;
+ t_common_mode = max(val1, val2);
/* Choose the greater of the two Port T_POWER_ON times */
val1 = (upreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
@@ -472,10 +477,27 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
scale2 = (dwreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
if (calc_l1ss_pwron(link->pdev, scale1, val1) >
- calc_l1ss_pwron(link->downstream, scale2, val2))
+ calc_l1ss_pwron(link->downstream, scale2, val2)) {
link->l1ss.ctl2 |= scale1 | (val1 << 3);
- else
+ t_power_on = calc_l1ss_pwron(link->pdev, scale1, val1);
+ } else {
link->l1ss.ctl2 |= scale2 | (val2 << 3);
+ t_power_on = calc_l1ss_pwron(link->downstream, scale2, val2);
+ }
+
+ /*
+ * Set LTR_L1.2_THRESHOLD to the time required to transition the
+ * Link from L0 to L1.2 and back to L0 so we enter L1.2 only if
+ * downstream devices report (via LTR) that they can tolerate at
+ * least that much latency.
+ *
+ * Based on PCIe r3.1, sec 5.5.3.3.1, Figures 5-16 and 5-17, and
+ * Table 5-11. T(POWER_OFF) is at most 2us and T(L1.2) is at
+ * least 4us.
+ */
+ l1_2_threshold = 2 + 4 + t_common_mode + t_power_on;
+ encode_l12_threshold(l1_2_threshold, &scale, &value);
+ link->l1ss.ctl1 |= t_common_mode << 8 | scale << 29 | value << 16;
}
static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
@@ -786,7 +808,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
*/
pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
- dev_info(&child->dev, "disabling ASPM on pre-1.1 PCIe device. You can enable it with 'pcie_aspm=force'\n");
+ pci_info(child, "disabling ASPM on pre-1.1 PCIe device. You can enable it with 'pcie_aspm=force'\n");
return -EINVAL;
}
}
@@ -1027,7 +1049,7 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
* ignored in this situation.
*/
if (aspm_disabled) {
- dev_warn(&pdev->dev, "can't disable ASPM; OS doesn't have ASPM control\n");
+ pci_warn(pdev, "can't disable ASPM; OS doesn't have ASPM control\n");
return;
}
diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c
index 2d976a623ddc..38e40c6c576f 100644
--- a/drivers/pci/pcie/pcie-dpc.c
+++ b/drivers/pci/pcie/pcie-dpc.c
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCI Express Downstream Port Containment services driver
* Author: Keith Busch <keith.busch@intel.com>
*
* Copyright (C) 2016 Intel Corp.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
*/
#include <linux/delay.h>
@@ -15,34 +12,15 @@
#include <linux/pci.h>
#include <linux/pcieport_if.h>
#include "../pci.h"
-
-struct rp_pio_header_log_regs {
- u32 dw0;
- u32 dw1;
- u32 dw2;
- u32 dw3;
-};
-
-struct dpc_rp_pio_regs {
- u32 status;
- u32 mask;
- u32 severity;
- u32 syserror;
- u32 exception;
-
- struct rp_pio_header_log_regs header_log;
- u32 impspec_log;
- u32 tlp_prefix_log[4];
- u32 log_size;
- u16 first_error;
-};
+#include "aer/aerdrv.h"
struct dpc_dev {
struct pcie_device *dev;
struct work_struct work;
- int cap_pos;
- bool rp;
+ u16 cap_pos;
+ bool rp_extensions;
u32 rp_pio_status;
+ u8 rp_log_size;
};
static const char * const rp_pio_error_string[] = {
@@ -72,13 +50,13 @@ static int dpc_wait_rp_inactive(struct dpc_dev *dpc)
unsigned long timeout = jiffies + HZ;
struct pci_dev *pdev = dpc->dev->port;
struct device *dev = &dpc->dev->device;
- u16 status;
+ u16 cap = dpc->cap_pos, status;
- pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status);
+ pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
while (status & PCI_EXP_DPC_RP_BUSY &&
!time_after(jiffies, timeout)) {
msleep(10);
- pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status);
+ pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
}
if (status & PCI_EXP_DPC_RP_BUSY) {
dev_warn(dev, "DPC root port still busy\n");
@@ -104,11 +82,12 @@ static void dpc_wait_link_inactive(struct dpc_dev *dpc)
dev_warn(dev, "Link state not disabled for DPC event\n");
}
-static void interrupt_event_handler(struct work_struct *work)
+static void dpc_work(struct work_struct *work)
{
struct dpc_dev *dpc = container_of(work, struct dpc_dev, work);
struct pci_dev *dev, *temp, *pdev = dpc->dev->port;
struct pci_bus *parent = pdev->subordinate;
+ u16 cap = dpc->cap_pos, ctl;
pci_lock_rescan_remove();
list_for_each_entry_safe_reverse(dev, temp, &parent->devices,
@@ -124,159 +103,127 @@ static void interrupt_event_handler(struct work_struct *work)
pci_unlock_rescan_remove();
dpc_wait_link_inactive(dpc);
- if (dpc->rp && dpc_wait_rp_inactive(dpc))
+ if (dpc->rp_extensions && dpc_wait_rp_inactive(dpc))
return;
- if (dpc->rp && dpc->rp_pio_status) {
- pci_write_config_dword(pdev,
- dpc->cap_pos + PCI_EXP_DPC_RP_PIO_STATUS,
- dpc->rp_pio_status);
+ if (dpc->rp_extensions && dpc->rp_pio_status) {
+ pci_write_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS,
+ dpc->rp_pio_status);
dpc->rp_pio_status = 0;
}
- pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS,
+ pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
PCI_EXP_DPC_STATUS_TRIGGER | PCI_EXP_DPC_STATUS_INTERRUPT);
-}
-static void dpc_rp_pio_print_tlp_header(struct device *dev,
- struct rp_pio_header_log_regs *t)
-{
- dev_err(dev, "TLP Header: %#010x %#010x %#010x %#010x\n",
- t->dw0, t->dw1, t->dw2, t->dw3);
+ pci_read_config_word(pdev, cap + PCI_EXP_DPC_CTL, &ctl);
+ pci_write_config_word(pdev, cap + PCI_EXP_DPC_CTL,
+ ctl | PCI_EXP_DPC_CTL_INT_EN);
}
-static void dpc_rp_pio_print_error(struct dpc_dev *dpc,
- struct dpc_rp_pio_regs *rp_pio)
+static void dpc_process_rp_pio_error(struct dpc_dev *dpc)
{
struct device *dev = &dpc->dev->device;
+ struct pci_dev *pdev = dpc->dev->port;
+ u16 cap = dpc->cap_pos, dpc_status, first_error;
+ u32 status, mask, sev, syserr, exc, dw0, dw1, dw2, dw3, log, prefix;
int i;
- u32 status;
+ pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_STATUS, &status);
+ pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_MASK, &mask);
dev_err(dev, "rp_pio_status: %#010x, rp_pio_mask: %#010x\n",
- rp_pio->status, rp_pio->mask);
+ status, mask);
+ dpc->rp_pio_status = status;
+
+ pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_SEVERITY, &sev);
+ pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_SYSERROR, &syserr);
+ pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_EXCEPTION, &exc);
dev_err(dev, "RP PIO severity=%#010x, syserror=%#010x, exception=%#010x\n",
- rp_pio->severity, rp_pio->syserror, rp_pio->exception);
+ sev, syserr, exc);
- status = (rp_pio->status & ~rp_pio->mask);
+ /* Get First Error Pointer */
+ pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &dpc_status);
+ first_error = (dpc_status & 0x1f00) >> 8;
+ status &= ~mask;
for (i = 0; i < ARRAY_SIZE(rp_pio_error_string); i++) {
- if (!(status & (1 << i)))
- continue;
-
- dev_err(dev, "[%2d] %s%s\n", i, rp_pio_error_string[i],
- rp_pio->first_error == i ? " (First)" : "");
+ if (status & (1 << i))
+ dev_err(dev, "[%2d] %s%s\n", i, rp_pio_error_string[i],
+ first_error == i ? " (First)" : "");
}
- dpc_rp_pio_print_tlp_header(dev, &rp_pio->header_log);
- if (rp_pio->log_size == 4)
+ if (dpc->rp_log_size < 4)
return;
- dev_err(dev, "RP PIO ImpSpec Log %#010x\n", rp_pio->impspec_log);
+ pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
+ &dw0);
+ pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 4,
+ &dw1);
+ pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 8,
+ &dw2);
+ pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 12,
+ &dw3);
+ dev_err(dev, "TLP Header: %#010x %#010x %#010x %#010x\n",
+ dw0, dw1, dw2, dw3);
+
+ if (dpc->rp_log_size < 5)
+ return;
+ pci_read_config_dword(pdev, cap + PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG, &log);
+ dev_err(dev, "RP PIO ImpSpec Log %#010x\n", log);
- for (i = 0; i < rp_pio->log_size - 5; i++)
- dev_err(dev, "TLP Prefix Header: dw%d, %#010x\n", i,
- rp_pio->tlp_prefix_log[i]);
+ for (i = 0; i < dpc->rp_log_size - 5; i++) {
+ pci_read_config_dword(pdev,
+ cap + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG, &prefix);
+ dev_err(dev, "TLP Prefix Header: dw%d, %#010x\n", i, prefix);
+ }
}
-static void dpc_rp_pio_get_info(struct dpc_dev *dpc,
- struct dpc_rp_pio_regs *rp_pio)
+static irqreturn_t dpc_irq(int irq, void *context)
{
+ struct dpc_dev *dpc = (struct dpc_dev *)context;
struct pci_dev *pdev = dpc->dev->port;
struct device *dev = &dpc->dev->device;
- int i;
- u16 cap;
- u16 status;
-
- pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_STATUS,
- &rp_pio->status);
- pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_MASK,
- &rp_pio->mask);
-
- pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_SEVERITY,
- &rp_pio->severity);
- pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_SYSERROR,
- &rp_pio->syserror);
- pci_read_config_dword(pdev, dpc->cap_pos + PCI_EXP_DPC_RP_PIO_EXCEPTION,
- &rp_pio->exception);
-
- /* Get First Error Pointer */
- pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status);
- rp_pio->first_error = (status & 0x1f00) >> 8;
+ u16 cap = dpc->cap_pos, ctl, status, source, reason, ext_reason;
- pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap);
- rp_pio->log_size = (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
- if (rp_pio->log_size < 4 || rp_pio->log_size > 9) {
- dev_err(dev, "RP PIO log size %u is invalid\n",
- rp_pio->log_size);
- return;
- }
+ pci_read_config_word(pdev, cap + PCI_EXP_DPC_CTL, &ctl);
- pci_read_config_dword(pdev,
- dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG,
- &rp_pio->header_log.dw0);
- pci_read_config_dword(pdev,
- dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 4,
- &rp_pio->header_log.dw1);
- pci_read_config_dword(pdev,
- dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 8,
- &rp_pio->header_log.dw2);
- pci_read_config_dword(pdev,
- dpc->cap_pos + PCI_EXP_DPC_RP_PIO_HEADER_LOG + 12,
- &rp_pio->header_log.dw3);
- if (rp_pio->log_size == 4)
- return;
+ if (!(ctl & PCI_EXP_DPC_CTL_INT_EN) || ctl == (u16)(~0))
+ return IRQ_NONE;
- pci_read_config_dword(pdev,
- dpc->cap_pos + PCI_EXP_DPC_RP_PIO_IMPSPEC_LOG,
- &rp_pio->impspec_log);
- for (i = 0; i < rp_pio->log_size - 5; i++)
- pci_read_config_dword(pdev,
- dpc->cap_pos + PCI_EXP_DPC_RP_PIO_TLPPREFIX_LOG,
- &rp_pio->tlp_prefix_log[i]);
-}
+ pci_read_config_word(pdev, cap + PCI_EXP_DPC_STATUS, &status);
-static void dpc_process_rp_pio_error(struct dpc_dev *dpc)
-{
- struct dpc_rp_pio_regs rp_pio_regs;
+ if (!(status & PCI_EXP_DPC_STATUS_INTERRUPT))
+ return IRQ_NONE;
- dpc_rp_pio_get_info(dpc, &rp_pio_regs);
- dpc_rp_pio_print_error(dpc, &rp_pio_regs);
+ if (!(status & PCI_EXP_DPC_STATUS_TRIGGER)) {
+ pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
+ PCI_EXP_DPC_STATUS_INTERRUPT);
+ return IRQ_HANDLED;
+ }
- dpc->rp_pio_status = rp_pio_regs.status;
-}
+ pci_write_config_word(pdev, cap + PCI_EXP_DPC_CTL,
+ ctl & ~PCI_EXP_DPC_CTL_INT_EN);
-static irqreturn_t dpc_irq(int irq, void *context)
-{
- struct dpc_dev *dpc = (struct dpc_dev *)context;
- struct pci_dev *pdev = dpc->dev->port;
- struct device *dev = &dpc->dev->device;
- u16 status, source;
-
- pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_STATUS, &status);
- pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_SOURCE_ID,
+ pci_read_config_word(pdev, cap + PCI_EXP_DPC_SOURCE_ID,
&source);
- if (!status || status == (u16)(~0))
- return IRQ_NONE;
dev_info(dev, "DPC containment event, status:%#06x source:%#06x\n",
status, source);
- if (status & PCI_EXP_DPC_STATUS_TRIGGER) {
- u16 reason = (status >> 1) & 0x3;
- u16 ext_reason = (status >> 5) & 0x3;
-
- dev_warn(dev, "DPC %s detected, remove downstream devices\n",
- (reason == 0) ? "unmasked uncorrectable error" :
- (reason == 1) ? "ERR_NONFATAL" :
- (reason == 2) ? "ERR_FATAL" :
- (ext_reason == 0) ? "RP PIO error" :
- (ext_reason == 1) ? "software trigger" :
- "reserved error");
- /* show RP PIO error detail information */
- if (reason == 3 && ext_reason == 0)
- dpc_process_rp_pio_error(dpc);
-
- schedule_work(&dpc->work);
- }
+ reason = (status & PCI_EXP_DPC_STATUS_TRIGGER_RSN) >> 1;
+ ext_reason = (status & PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT) >> 5;
+
+ dev_warn(dev, "DPC %s detected, remove downstream devices\n",
+ (reason == 0) ? "unmasked uncorrectable error" :
+ (reason == 1) ? "ERR_NONFATAL" :
+ (reason == 2) ? "ERR_FATAL" :
+ (ext_reason == 0) ? "RP PIO error" :
+ (ext_reason == 1) ? "software trigger" :
+ "reserved error");
+ /* show RP PIO error detail information */
+ if (dpc->rp_extensions && reason == 3 && ext_reason == 0)
+ dpc_process_rp_pio_error(dpc);
+
+ schedule_work(&dpc->work);
+
return IRQ_HANDLED;
}
@@ -289,13 +236,16 @@ static int dpc_probe(struct pcie_device *dev)
int status;
u16 ctl, cap;
+ if (pcie_aer_get_firmware_first(pdev))
+ return -ENOTSUPP;
+
dpc = devm_kzalloc(device, sizeof(*dpc), GFP_KERNEL);
if (!dpc)
return -ENOMEM;
dpc->cap_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DPC);
dpc->dev = dev;
- INIT_WORK(&dpc->work, interrupt_event_handler);
+ INIT_WORK(&dpc->work, dpc_work);
set_service_data(dev, dpc);
status = devm_request_irq(device, dev->irq, dpc_irq, IRQF_SHARED,
@@ -309,15 +259,23 @@ static int dpc_probe(struct pcie_device *dev)
pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CAP, &cap);
pci_read_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, &ctl);
- dpc->rp = (cap & PCI_EXP_DPC_CAP_RP_EXT);
+ dpc->rp_extensions = (cap & PCI_EXP_DPC_CAP_RP_EXT);
+ if (dpc->rp_extensions) {
+ dpc->rp_log_size = (cap & PCI_EXP_DPC_RP_PIO_LOG_SIZE) >> 8;
+ if (dpc->rp_log_size < 4 || dpc->rp_log_size > 9) {
+ dev_err(device, "RP PIO log size %u is invalid\n",
+ dpc->rp_log_size);
+ dpc->rp_log_size = 0;
+ }
+ }
ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_NONFATAL | PCI_EXP_DPC_CTL_INT_EN;
pci_write_config_word(pdev, dpc->cap_pos + PCI_EXP_DPC_CTL, ctl);
dev_info(device, "DPC error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n",
- cap & 0xf, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT),
+ cap & PCI_EXP_DPC_IRQ, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT),
FLAG(cap, PCI_EXP_DPC_CAP_POISONED_TLP),
- FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), (cap >> 8) & 0xf,
+ FLAG(cap, PCI_EXP_DPC_CAP_SW_TRIGGER), dpc->rp_log_size,
FLAG(cap, PCI_EXP_DPC_CAP_DL_ACTIVE));
return status;
}
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index df290aa58dce..5480f54f7612 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe Native PME support
*
* Copyright (C) 2007 - 2009 Intel Corp
* Copyright (C) 2007 - 2009 Shaohua Li <shaohua.li@intel.com>
* Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License V2. See the file "COPYING" in the main directory of this archive
- * for more details.
*/
#include <linux/pci.h>
@@ -198,14 +195,14 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id)
* assuming that the PME was reported by a PCIe-PCI bridge that
* used devfn different from zero.
*/
- dev_dbg(&port->dev, "PME interrupt generated for non-existent device %02x:%02x.%d\n",
+ pci_dbg(port, "PME interrupt generated for non-existent device %02x:%02x.%d\n",
busnr, PCI_SLOT(devfn), PCI_FUNC(devfn));
found = pcie_pme_from_pci_bridge(bus, 0);
}
out:
if (!found)
- dev_dbg(&port->dev, "Spurious native PME interrupt!\n");
+ pci_dbg(port, "Spurious native PME interrupt!\n");
}
/**
@@ -345,7 +342,7 @@ static int pcie_pme_probe(struct pcie_device *srv)
return ret;
}
- dev_info(&port->dev, "Signaling PME with IRQ %d\n", srv->irq);
+ pci_info(port, "Signaling PME with IRQ %d\n", srv->irq);
pcie_pme_mark_devices(port);
pcie_pme_interrupt_enable(port, true);
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c
index 6b8c2f1d0e71..319c94976873 100644
--- a/drivers/pci/pcie/portdrv_acpi.c
+++ b/drivers/pci/pcie/portdrv_acpi.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCIe Port Native Services Support, ACPI-Related Part
*
* Copyright (C) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License V2. See the file "COPYING" in the main directory of this archive
- * for more details.
*/
#include <linux/pci.h>
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
index 87e79a6ffb5a..f0fba552a0e2 100644
--- a/drivers/pci/pcie/portdrv_bus.c
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* File: portdrv_bus.c
* Purpose: PCI Express Port Bus Driver's Bus Overloading Functions
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index a59210350c44..ef3bad4ad010 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -216,9 +216,9 @@ static int get_port_device_capability(struct pci_dev *dev)
return 0;
cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
- | PCIE_PORT_SERVICE_VC | PCIE_PORT_SERVICE_DPC;
+ | PCIE_PORT_SERVICE_VC;
if (pci_aer_available())
- cap_mask |= PCIE_PORT_SERVICE_AER;
+ cap_mask |= PCIE_PORT_SERVICE_AER | PCIE_PORT_SERVICE_DPC;
if (pcie_ports_auto)
pcie_port_platform_notify(dev, &cap_mask);
diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c
index bab8ac63c4f3..98cfa30f3fae 100644
--- a/drivers/pci/pcie/ptm.c
+++ b/drivers/pci/pcie/ptm.c
@@ -1,15 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCI Express Precision Time Measurement
* Copyright (c) 2016, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
*/
#include <linux/module.h>
@@ -33,7 +25,7 @@ static void pci_ptm_info(struct pci_dev *dev)
dev->ptm_granularity);
break;
}
- dev_info(&dev->dev, "PTM enabled%s, %s granularity\n",
+ pci_info(dev, "PTM enabled%s, %s granularity\n",
dev->ptm_root ? " (root)" : "", clock_desc);
}
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 14e0ea1ff38b..ef5377438a1e 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* probe.c - PCI detection and setup code
*/
@@ -69,8 +70,8 @@ static int find_anything(struct device *dev, void *data)
}
/*
- * Some device drivers need know if pci is initiated.
- * Basically, we think pci is not initiated when there
+ * Some device drivers need know if PCI is initiated.
+ * Basically, we think PCI is not initiated when there
* is no device to be found on the pci_bus_type.
*/
int no_pci_devices(void)
@@ -116,12 +117,16 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask)
if (!size)
return 0;
- /* Get the lowest of them to find the decode size, and
- from that the extent. */
+ /*
+ * Get the lowest of them to find the decode size, and from that
+ * the extent.
+ */
size = (size & ~(size-1)) - 1;
- /* base == maxbase can be valid only if the BAR has
- already been programmed with all 1s. */
+ /*
+ * base == maxbase can be valid only if the BAR has already been
+ * programmed with all 1s.
+ */
if (base == maxbase && ((base | size) & mask) != mask)
return 0;
@@ -164,7 +169,7 @@ static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)
#define PCI_COMMAND_DECODE_ENABLE (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)
/**
- * pci_read_base - read a PCI BAR
+ * pci_read_base - Read a PCI BAR
* @dev: the PCI device
* @type: type of the BAR
* @res: resource buffer to be filled in
@@ -253,7 +258,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
sz64 = pci_size(l64, sz64, mask64);
if (!sz64) {
- dev_info(&dev->dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n",
+ pci_info(dev, FW_BUG "reg 0x%x: invalid BAR (can't size)\n",
pos);
goto fail;
}
@@ -264,7 +269,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
res->flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED;
res->start = 0;
res->end = 0;
- dev_err(&dev->dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
+ pci_err(dev, "reg 0x%x: can't handle BAR larger than 4GB (size %#010llx)\n",
pos, (unsigned long long)sz64);
goto out;
}
@@ -274,7 +279,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
res->flags |= IORESOURCE_UNSET;
res->start = 0;
res->end = sz64;
- dev_info(&dev->dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n",
+ pci_info(dev, "reg 0x%x: can't handle BAR above 4GB (bus address %#010llx)\n",
pos, (unsigned long long)l64);
goto out;
}
@@ -301,7 +306,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
res->flags |= IORESOURCE_UNSET;
res->start = 0;
res->end = region.end - region.start;
- dev_info(&dev->dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
+ pci_info(dev, "reg 0x%x: initial BAR value %#010llx invalid\n",
pos, (unsigned long long)region.start);
}
@@ -312,7 +317,7 @@ fail:
res->flags = 0;
out:
if (res->flags)
- dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x: %pR\n", pos, res);
+ pci_printk(KERN_DEBUG, dev, "reg 0x%x: %pR\n", pos, res);
return (res->flags & IORESOURCE_MEM_64) ? 1 : 0;
}
@@ -375,7 +380,7 @@ static void pci_read_bridge_io(struct pci_bus *child)
region.start = base;
region.end = limit + io_granularity - 1;
pcibios_bus_to_resource(dev->bus, res, &region);
- dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
+ pci_printk(KERN_DEBUG, dev, " bridge window %pR\n", res);
}
}
@@ -397,7 +402,7 @@ static void pci_read_bridge_mmio(struct pci_bus *child)
region.start = base;
region.end = limit + 0xfffff;
pcibios_bus_to_resource(dev->bus, res, &region);
- dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
+ pci_printk(KERN_DEBUG, dev, " bridge window %pR\n", res);
}
}
@@ -437,7 +442,7 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
limit = (pci_bus_addr_t) limit64;
if (base != base64) {
- dev_err(&dev->dev, "can't handle bridge window above 4GB (bus address %#010llx)\n",
+ pci_err(dev, "can't handle bridge window above 4GB (bus address %#010llx)\n",
(unsigned long long) base64);
return;
}
@@ -450,7 +455,7 @@ static void pci_read_bridge_mmio_pref(struct pci_bus *child)
region.start = base;
region.end = limit + 0xfffff;
pcibios_bus_to_resource(dev->bus, res, &region);
- dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
+ pci_printk(KERN_DEBUG, dev, " bridge window %pR\n", res);
}
}
@@ -463,7 +468,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
if (pci_is_root_bus(child)) /* It's a host bus, nothing to read */
return;
- dev_info(&dev->dev, "PCI bridge to %pR%s\n",
+ pci_info(dev, "PCI bridge to %pR%s\n",
&child->busn_res,
dev->transparent ? " (subtractive decode)" : "");
@@ -480,7 +485,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
if (res && res->flags) {
pci_bus_add_resource(child, res,
PCI_SUBTRACTIVE_DECODE);
- dev_printk(KERN_DEBUG, &dev->dev,
+ pci_printk(KERN_DEBUG, dev,
" bridge window %pR (subtractive decode)\n",
res);
}
@@ -764,7 +769,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
bridge->bus = bus;
- /* temporarily move resources off the list */
+ /* Temporarily move resources off the list */
list_splice_init(&bridge->windows, &resources);
bus->sysdata = bridge->sysdata;
bus->msi = bridge->msi;
@@ -776,7 +781,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
b = pci_find_bus(pci_domain_nr(bus), bridge->busnr);
if (b) {
- /* If we already got to this bus through a different bridge, ignore it */
+ /* Ignore it if we already got here via a different bridge */
dev_dbg(&b->dev, "bus already known\n");
err = -EEXIST;
goto free;
@@ -869,9 +874,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
int i;
int ret;
- /*
- * Allocate a new bus, and inherit stuff from the parent..
- */
+ /* Allocate a new bus and inherit stuff from the parent */
child = pci_alloc_bus(parent);
if (!child)
return NULL;
@@ -882,16 +885,14 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
child->sysdata = parent->sysdata;
child->bus_flags = parent->bus_flags;
- /* initialize some portions of the bus device, but don't register it
- * now as the parent is not properly set up yet.
+ /*
+ * Initialize some portions of the bus device, but don't register
+ * it now as the parent is not properly set up yet.
*/
child->dev.class = &pcibus_class;
dev_set_name(&child->dev, "%04x:%02x", pci_domain_nr(child), busnr);
- /*
- * Set up the primary, secondary and subordinate
- * bus numbers.
- */
+ /* Set up the primary, secondary and subordinate bus numbers */
child->number = child->busn_res.start = busnr;
child->primary = parent->busn_res.start;
child->busn_res.end = 0xff;
@@ -907,7 +908,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
pci_set_bus_of_node(child);
pci_set_bus_speed(child);
- /* Set up default resource pointers and names.. */
+ /* Set up default resource pointers and names */
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i];
child->resource[i]->name = child->name;
@@ -1005,11 +1006,11 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
secondary = (buses >> 8) & 0xFF;
subordinate = (buses >> 16) & 0xFF;
- dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
+ pci_dbg(dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n",
secondary, subordinate, pass);
if (!primary && (primary != bus->number) && secondary && subordinate) {
- dev_warn(&dev->dev, "Primary bus is hard wired to 0\n");
+ pci_warn(dev, "Primary bus is hard wired to 0\n");
primary = bus->number;
}
@@ -1017,13 +1018,15 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
if (!pass &&
(primary != bus->number || secondary <= bus->number ||
secondary > subordinate)) {
- dev_info(&dev->dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n",
+ pci_info(dev, "bridge configuration invalid ([bus %02x-%02x]), reconfiguring\n",
secondary, subordinate);
broken = 1;
}
- /* Disable MasterAbortMode during probing to avoid reporting
- of bus errors (in some architectures) */
+ /*
+ * Disable Master-Abort Mode during probing to avoid reporting of
+ * bus errors in some architectures.
+ */
pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &bctl);
pci_write_config_word(dev, PCI_BRIDGE_CONTROL,
bctl & ~PCI_BRIDGE_CTL_MASTER_ABORT);
@@ -1033,18 +1036,19 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
if ((secondary || subordinate) && !pcibios_assign_all_busses() &&
!is_cardbus && !broken) {
unsigned int cmax;
+
/*
- * Bus already configured by firmware, process it in the first
- * pass and just note the configuration.
+ * Bus already configured by firmware, process it in the
+ * first pass and just note the configuration.
*/
if (pass)
goto out;
/*
- * The bus might already exist for two reasons: Either we are
- * rescanning the bus or the bus is reachable through more than
- * one bridge. The second case can happen with the i450NX
- * chipset.
+ * The bus might already exist for two reasons: Either we
+ * are rescanning the bus or the bus is reachable through
+ * more than one bridge. The second case can happen with
+ * the i450NX chipset.
*/
child = pci_find_bus(pci_domain_nr(bus), secondary);
if (!child) {
@@ -1058,24 +1062,29 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
cmax = pci_scan_child_bus(child);
if (cmax > subordinate)
- dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n",
+ pci_warn(dev, "bridge has subordinate %02x but max busn %02x\n",
subordinate, cmax);
- /* subordinate should equal child->busn_res.end */
+
+ /* Subordinate should equal child->busn_res.end */
if (subordinate > max)
max = subordinate;
} else {
+
/*
* We need to assign a number to this bus which we always
* do in the second pass.
*/
if (!pass) {
if (pcibios_assign_all_busses() || broken || is_cardbus)
- /* Temporarily disable forwarding of the
- configuration cycles on all bridges in
- this bus segment to avoid possible
- conflicts in the second pass between two
- bridges programmed with overlapping
- bus ranges. */
+
+ /*
+ * Temporarily disable forwarding of the
+ * configuration cycles on all bridges in
+ * this bus segment to avoid possible
+ * conflicts in the second pass between two
+ * bridges programmed with overlapping bus
+ * ranges.
+ */
pci_write_config_dword(dev, PCI_PRIMARY_BUS,
buses & ~0xffffff);
goto out;
@@ -1084,9 +1093,11 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
/* Clear errors */
pci_write_config_word(dev, PCI_STATUS, 0xffff);
- /* Prevent assigning a bus number that already exists.
- * This can happen when a bridge is hot-plugged, so in
- * this case we only re-scan this bus. */
+ /*
+ * Prevent assigning a bus number that already exists.
+ * This can happen when a bridge is hot-plugged, so in this
+ * case we only re-scan this bus.
+ */
child = pci_find_bus(pci_domain_nr(bus), max+1);
if (!child) {
child = pci_add_new_bus(bus, dev, max+1);
@@ -1113,19 +1124,18 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
buses |= CARDBUS_LATENCY_TIMER << 24;
}
- /*
- * We need to blast all three values with a single write.
- */
+ /* We need to blast all three values with a single write */
pci_write_config_dword(dev, PCI_PRIMARY_BUS, buses);
if (!is_cardbus) {
child->bridge_ctl = bctl;
max = pci_scan_child_bus_extend(child, available_buses);
} else {
+
/*
- * For CardBus bridges, we leave 4 bus numbers
- * as cards with a PCI-to-PCI bridge can be
- * inserted later.
+ * For CardBus bridges, we leave 4 bus numbers as
+ * cards with a PCI-to-PCI bridge can be inserted
+ * later.
*/
for (i = 0; i < CARDBUS_RESERVE_BUSNR; i++) {
struct pci_bus *parent = bus;
@@ -1141,10 +1151,11 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
parent = parent->parent;
}
if (j) {
+
/*
- * Often, there are two cardbus bridges
- * -- try to leave one valid bus number
- * for each one.
+ * Often, there are two CardBus
+ * bridges -- try to leave one
+ * valid bus number for each one.
*/
i /= 2;
break;
@@ -1152,9 +1163,8 @@ static int pci_scan_bridge_extend(struct pci_bus *bus, struct pci_dev *dev,
}
max += i;
}
- /*
- * Set the subordinate bus number to its real value.
- */
+
+ /* Set subordinate bus number to its real value */
pci_bus_update_busn_res_end(child, max);
pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
}
@@ -1295,7 +1305,7 @@ static void set_pcie_thunderbolt(struct pci_dev *dev)
}
/**
- * pci_ext_cfg_is_aliased - is ext config space just an alias of std config?
+ * pci_ext_cfg_is_aliased - Is ext config space just an alias of std config?
* @dev: PCI device
*
* PCI Express to PCI/PCI-X Bridge Specification, rev 1.0, 4.1.4 says that
@@ -1332,7 +1342,7 @@ static bool pci_ext_cfg_is_aliased(struct pci_dev *dev)
}
/**
- * pci_cfg_space_size - get the configuration space size of the PCI device.
+ * pci_cfg_space_size - Get the configuration space size of the PCI device
* @dev: PCI device
*
* Regular PCI devices have 256 bytes, but PCI-X 2 and PCI Express devices
@@ -1398,7 +1408,7 @@ static void pci_msi_setup_pci_dev(struct pci_dev *dev)
}
/**
- * pci_intx_mask_broken - test PCI_COMMAND_INTX_DISABLE writability
+ * pci_intx_mask_broken - Test PCI_COMMAND_INTX_DISABLE writability
* @dev: PCI device
*
* Test whether PCI_COMMAND_INTX_DISABLE is writable for @dev. Check this
@@ -1426,11 +1436,11 @@ static int pci_intx_mask_broken(struct pci_dev *dev)
}
/**
- * pci_setup_device - fill in class and map information of a device
+ * pci_setup_device - Fill in class and map information of a device
* @dev: the device structure to fill
*
* Initialize the device structure with information about the device's
- * vendor,class,memory and IO-space addresses,IRQ lines etc.
+ * vendor,class,memory and IO-space addresses, IRQ lines etc.
* Called at initialisation of the PCI subsystem and by CardBus services.
* Returns 0 on success and negative if unknown type of device (not normal,
* bridge or CardBus).
@@ -1456,8 +1466,11 @@ int pci_setup_device(struct pci_dev *dev)
set_pcie_port_type(dev);
pci_dev_assign_slot(dev);
- /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
- set this higher, assuming the system even supports it. */
+
+ /*
+ * Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
+ * set this higher, assuming the system even supports it.
+ */
dev->dma_mask = 0xffffffff;
dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
@@ -1468,13 +1481,13 @@ int pci_setup_device(struct pci_dev *dev)
dev->revision = class & 0xff;
dev->class = class >> 8; /* upper 3 bytes */
- dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %02x class %#08x\n",
+ pci_printk(KERN_DEBUG, dev, "[%04x:%04x] type %02x class %#08x\n",
dev->vendor, dev->device, dev->hdr_type, dev->class);
- /* need to have dev->class ready */
+ /* Need to have dev->class ready */
dev->cfg_size = pci_cfg_space_size(dev);
- /* need to have dev->cfg_size ready */
+ /* Need to have dev->cfg_size ready */
set_pcie_thunderbolt(dev);
/* "Unknown power state" */
@@ -1482,13 +1495,14 @@ int pci_setup_device(struct pci_dev *dev)
/* Early fixups, before probing the BARs */
pci_fixup_device(pci_fixup_early, dev);
- /* device class may be changed after fixup */
+
+ /* Device class may be changed after fixup */
class = dev->class >> 8;
if (dev->non_compliant_bars) {
pci_read_config_word(dev, PCI_COMMAND, &cmd);
if (cmd & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) {
- dev_info(&dev->dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
+ pci_info(dev, "device has non-compliant BARs; disabling IO/MEM decoding\n");
cmd &= ~PCI_COMMAND_IO;
cmd &= ~PCI_COMMAND_MEMORY;
pci_write_config_word(dev, PCI_COMMAND, cmd);
@@ -1521,14 +1535,14 @@ int pci_setup_device(struct pci_dev *dev)
res = &dev->resource[0];
res->flags = LEGACY_IO_RESOURCE;
pcibios_bus_to_resource(dev->bus, res, &region);
- dev_info(&dev->dev, "legacy IDE quirk: reg 0x10: %pR\n",
+ pci_info(dev, "legacy IDE quirk: reg 0x10: %pR\n",
res);
region.start = 0x3F6;
region.end = 0x3F6;
res = &dev->resource[1];
res->flags = LEGACY_IO_RESOURCE;
pcibios_bus_to_resource(dev->bus, res, &region);
- dev_info(&dev->dev, "legacy IDE quirk: reg 0x14: %pR\n",
+ pci_info(dev, "legacy IDE quirk: reg 0x14: %pR\n",
res);
}
if ((progif & 4) == 0) {
@@ -1537,14 +1551,14 @@ int pci_setup_device(struct pci_dev *dev)
res = &dev->resource[2];
res->flags = LEGACY_IO_RESOURCE;
pcibios_bus_to_resource(dev->bus, res, &region);
- dev_info(&dev->dev, "legacy IDE quirk: reg 0x18: %pR\n",
+ pci_info(dev, "legacy IDE quirk: reg 0x18: %pR\n",
res);
region.start = 0x376;
region.end = 0x376;
res = &dev->resource[3];
res->flags = LEGACY_IO_RESOURCE;
pcibios_bus_to_resource(dev->bus, res, &region);
- dev_info(&dev->dev, "legacy IDE quirk: reg 0x1c: %pR\n",
+ pci_info(dev, "legacy IDE quirk: reg 0x1c: %pR\n",
res);
}
}
@@ -1553,9 +1567,12 @@ int pci_setup_device(struct pci_dev *dev)
case PCI_HEADER_TYPE_BRIDGE: /* bridge header */
if (class != PCI_CLASS_BRIDGE_PCI)
goto bad;
- /* The PCI-to-PCI bridge spec requires that subtractive
- decoding (i.e. transparent) bridge must have programming
- interface code of 0x01. */
+
+ /*
+ * The PCI-to-PCI bridge spec requires that subtractive
+ * decoding (i.e. transparent) bridge must have programming
+ * interface code of 0x01.
+ */
pci_read_irq(dev);
dev->transparent = ((dev->class & 0xff) == 1);
pci_read_bases(dev, 2, PCI_ROM_ADDRESS1);
@@ -1577,12 +1594,12 @@ int pci_setup_device(struct pci_dev *dev)
break;
default: /* unknown header */
- dev_err(&dev->dev, "unknown header type %02x, ignoring device\n",
+ pci_err(dev, "unknown header type %02x, ignoring device\n",
dev->hdr_type);
return -EIO;
bad:
- dev_err(&dev->dev, "ignoring class %#08x (doesn't match header type %02x)\n",
+ pci_err(dev, "ignoring class %#08x (doesn't match header type %02x)\n",
dev->class, dev->hdr_type);
dev->class = PCI_CLASS_NOT_DEFINED << 8;
}
@@ -1606,7 +1623,7 @@ static void pci_configure_mps(struct pci_dev *dev)
return;
if (pcie_bus_config == PCIE_BUS_TUNE_OFF) {
- dev_warn(&dev->dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
+ pci_warn(dev, "Max Payload Size %d, but upstream %s set to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
mps, pci_name(bridge), p_mps);
return;
}
@@ -1620,12 +1637,12 @@ static void pci_configure_mps(struct pci_dev *dev)
rc = pcie_set_mps(dev, p_mps);
if (rc) {
- dev_warn(&dev->dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
+ pci_warn(dev, "can't set Max Payload Size to %d; if necessary, use \"pci=pcie_bus_safe\" and report a bug\n",
p_mps);
return;
}
- dev_info(&dev->dev, "Max Payload Size set to %d (was %d, max %d)\n",
+ pci_info(dev, "Max Payload Size set to %d (was %d, max %d)\n",
p_mps, mps, 128 << dev->pcie_mpss);
}
@@ -1645,8 +1662,7 @@ static void program_hpp_type0(struct pci_dev *dev, struct hpp_type0 *hpp)
hpp = &pci_default_type0;
if (hpp->revision > 1) {
- dev_warn(&dev->dev,
- "PCI settings rev %d not supported; using defaults\n",
+ pci_warn(dev, "PCI settings rev %d not supported; using defaults\n",
hpp->revision);
hpp = &pci_default_type0;
}
@@ -1684,7 +1700,7 @@ static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
if (!pos)
return;
- dev_warn(&dev->dev, "PCI-X settings not supported\n");
+ pci_warn(dev, "PCI-X settings not supported\n");
}
static bool pcie_root_rcb_set(struct pci_dev *dev)
@@ -1714,7 +1730,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
return;
if (hpp->revision > 1) {
- dev_warn(&dev->dev, "PCIe settings rev %d not supported\n",
+ pci_warn(dev, "PCIe settings rev %d not supported\n",
hpp->revision);
return;
}
@@ -1772,6 +1788,7 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
/* Initialize Advanced Error Capabilities and Control Register */
pci_read_config_dword(dev, pos + PCI_ERR_CAP, &reg32);
reg32 = (reg32 & hpp->adv_err_cap_and) | hpp->adv_err_cap_or;
+
/* Don't enable ECRC generation or checking if unsupported */
if (!(reg32 & PCI_ERR_CAP_ECRC_GENC))
reg32 &= ~PCI_ERR_CAP_ECRC_GENE;
@@ -1818,7 +1835,7 @@ int pci_configure_extended_tags(struct pci_dev *dev, void *ign)
*/
if (host->no_ext_tags) {
if (ctl & PCI_EXP_DEVCTL_EXT_TAG) {
- dev_info(&dev->dev, "disabling Extended Tags\n");
+ pci_info(dev, "disabling Extended Tags\n");
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_EXT_TAG);
}
@@ -1826,7 +1843,7 @@ int pci_configure_extended_tags(struct pci_dev *dev, void *ign)
}
if (!(ctl & PCI_EXP_DEVCTL_EXT_TAG)) {
- dev_info(&dev->dev, "enabling Extended Tags\n");
+ pci_info(dev, "enabling Extended Tags\n");
pcie_capability_set_word(dev, PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_EXT_TAG);
}
@@ -1871,10 +1888,42 @@ static void pci_configure_relaxed_ordering(struct pci_dev *dev)
if (root->dev_flags & PCI_DEV_FLAGS_NO_RELAXED_ORDERING) {
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_RELAX_EN);
- dev_info(&dev->dev, "Disable Relaxed Ordering because the Root Port didn't support it\n");
+ pci_info(dev, "Relaxed Ordering disabled because the Root Port didn't support it\n");
}
}
+static void pci_configure_ltr(struct pci_dev *dev)
+{
+#ifdef CONFIG_PCIEASPM
+ u32 cap;
+ struct pci_dev *bridge;
+
+ if (!pci_is_pcie(dev))
+ return;
+
+ pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
+ if (!(cap & PCI_EXP_DEVCAP2_LTR))
+ return;
+
+ /*
+ * Software must not enable LTR in an Endpoint unless the Root
+ * Complex and all intermediate Switches indicate support for LTR.
+ * PCIe r3.1, sec 6.18.
+ */
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+ dev->ltr_path = 1;
+ else {
+ bridge = pci_upstream_bridge(dev);
+ if (bridge && bridge->ltr_path)
+ dev->ltr_path = 1;
+ }
+
+ if (dev->ltr_path)
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
+ PCI_EXP_DEVCTL2_LTR_EN);
+#endif
+}
+
static void pci_configure_device(struct pci_dev *dev)
{
struct hotplug_params hpp;
@@ -1883,6 +1932,7 @@ static void pci_configure_device(struct pci_dev *dev)
pci_configure_mps(dev);
pci_configure_extended_tags(dev, NULL);
pci_configure_relaxed_ordering(dev);
+ pci_configure_ltr(dev);
memset(&hpp, 0, sizeof(hpp));
ret = pci_get_hp_params(dev, &hpp);
@@ -1902,10 +1952,11 @@ static void pci_release_capabilities(struct pci_dev *dev)
}
/**
- * pci_release_dev - free a pci device structure when all users of it are finished.
+ * pci_release_dev - Free a PCI device structure when all users of it are
+ * finished
* @dev: device that's been disconnected
*
- * Will be called only by the device core when all users of this pci device are
+ * Will be called only by the device core when all users of this PCI device are
* done.
*/
static void pci_release_dev(struct device *dev)
@@ -1993,7 +2044,7 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l))
return false;
- /* some broken boards return 0 or ~0 if a slot is empty: */
+ /* Some broken boards return 0 or ~0 if a slot is empty: */
if (*l == 0xffffffff || *l == 0x00000000 ||
*l == 0x0000ffff || *l == 0xffff0000)
return false;
@@ -2006,8 +2057,8 @@ bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l,
EXPORT_SYMBOL(pci_bus_read_dev_vendor_id);
/*
- * Read the config data for a PCI device, sanity-check it
- * and fill in the dev structure...
+ * Read the config data for a PCI device, sanity-check it,
+ * and fill in the dev structure.
*/
static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
{
@@ -2073,7 +2124,7 @@ static void pci_init_capabilities(struct pci_dev *dev)
}
/*
- * This is the equivalent of pci_host_bridge_msi_domain that acts on
+ * This is the equivalent of pci_host_bridge_msi_domain() that acts on
* devices. Firmware interfaces that can select the MSI domain on a
* per-device basis should be called from here.
*/
@@ -2082,7 +2133,7 @@ static struct irq_domain *pci_dev_msi_domain(struct pci_dev *dev)
struct irq_domain *d;
/*
- * If a domain has been set through the pcibios_add_device
+ * If a domain has been set through the pcibios_add_device()
* callback, then this is the one (platform code knows best).
*/
d = dev_get_msi_domain(&dev->dev);
@@ -2136,10 +2187,10 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
/* Fix up broken headers */
pci_fixup_device(pci_fixup_header, dev);
- /* moved out from quirk header fixup code */
+ /* Moved out from quirk header fixup code */
pci_reassigndev_resource_alignment(dev);
- /* Clear the state_saved flag. */
+ /* Clear the state_saved flag */
dev->state_saved = false;
/* Initialize various capabilities */
@@ -2156,7 +2207,7 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
ret = pcibios_add_device(dev);
WARN_ON(ret < 0);
- /* Setup MSI irq domain */
+ /* Set up MSI IRQ domain */
pci_set_msi_domain(dev);
/* Notifier could use PCI capabilities */
@@ -2215,29 +2266,34 @@ static unsigned next_fn(struct pci_bus *bus, struct pci_dev *dev, unsigned fn)
static int only_one_child(struct pci_bus *bus)
{
- struct pci_dev *parent = bus->self;
+ struct pci_dev *bridge = bus->self;
- if (!parent || !pci_is_pcie(parent))
+ /*
+ * Systems with unusual topologies set PCI_SCAN_ALL_PCIE_DEVS so
+ * we scan for all possible devices, not just Device 0.
+ */
+ if (pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
return 0;
- if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT)
- return 1;
/*
- * PCIe downstream ports are bridges that normally lead to only a
- * device 0, but if PCI_SCAN_ALL_PCIE_DEVS is set, scan all
- * possible devices, not just device 0. See PCIe spec r3.0,
- * sec 7.3.1.
+ * A PCIe Downstream Port normally leads to a Link with only Device
+ * 0 on it (PCIe spec r3.1, sec 7.3.1). As an optimization, scan
+ * only for Device 0 in that situation.
+ *
+ * Checking has_secondary_link is a hack to identify Downstream
+ * Ports because sometimes Switches are configured such that the
+ * PCIe Port Type labels are backwards.
*/
- if (parent->has_secondary_link &&
- !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS))
+ if (bridge && pci_is_pcie(bridge) && bridge->has_secondary_link)
return 1;
+
return 0;
}
/**
- * pci_scan_slot - scan a PCI slot on a bus for devices.
+ * pci_scan_slot - Scan a PCI slot on a bus for devices
* @bus: PCI bus to scan
- * @devfn: slot number to scan (must have zero function.)
+ * @devfn: slot number to scan (must have zero function)
*
* Scan a PCI slot on the specified PCI bus for devices, adding
* discovered devices to the @bus->devices list. New devices
@@ -2268,7 +2324,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn)
}
}
- /* only one slot has pcie device */
+ /* Only one slot has PCIe device */
if (bus->self && nr)
pcie_aspm_init_link_state(bus->self);
@@ -2317,7 +2373,9 @@ static void pcie_write_mps(struct pci_dev *dev, int mps)
if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT &&
dev->bus->self)
- /* For "Performance", the assumption is made that
+
+ /*
+ * For "Performance", the assumption is made that
* downstream communication will never be larger than
* the MRRS. So, the MPS only needs to be configured
* for the upstream communication. This being the case,
@@ -2334,27 +2392,30 @@ static void pcie_write_mps(struct pci_dev *dev, int mps)
rc = pcie_set_mps(dev, mps);
if (rc)
- dev_err(&dev->dev, "Failed attempting to set the MPS\n");
+ pci_err(dev, "Failed attempting to set the MPS\n");
}
static void pcie_write_mrrs(struct pci_dev *dev)
{
int rc, mrrs;
- /* In the "safe" case, do not configure the MRRS. There appear to be
+ /*
+ * In the "safe" case, do not configure the MRRS. There appear to be
* issues with setting MRRS to 0 on a number of devices.
*/
if (pcie_bus_config != PCIE_BUS_PERFORMANCE)
return;
- /* For Max performance, the MRRS must be set to the largest supported
+ /*
+ * For max performance, the MRRS must be set to the largest supported
* value. However, it cannot be configured larger than the MPS the
* device or the bus can support. This should already be properly
- * configured by a prior call to pcie_write_mps.
+ * configured by a prior call to pcie_write_mps().
*/
mrrs = pcie_get_mps(dev);
- /* MRRS is a R/W register. Invalid values can be written, but a
+ /*
+ * MRRS is a R/W register. Invalid values can be written, but a
* subsequent read will verify if the value is acceptable or not.
* If the MRRS value provided is not acceptable (e.g., too large),
* shrink the value until it is acceptable to the HW.
@@ -2364,12 +2425,12 @@ static void pcie_write_mrrs(struct pci_dev *dev)
if (!rc)
break;
- dev_warn(&dev->dev, "Failed attempting to set the MRRS\n");
+ pci_warn(dev, "Failed attempting to set the MRRS\n");
mrrs /= 2;
}
if (mrrs < 128)
- dev_err(&dev->dev, "MRRS was unable to be configured with a safe value. If problems are experienced, try running with pci=pcie_bus_safe\n");
+ pci_err(dev, "MRRS was unable to be configured with a safe value. If problems are experienced, try running with pci=pcie_bus_safe\n");
}
static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
@@ -2389,14 +2450,15 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
pcie_write_mps(dev, mps);
pcie_write_mrrs(dev);
- dev_info(&dev->dev, "Max Payload Size set to %4d/%4d (was %4d), Max Read Rq %4d\n",
+ pci_info(dev, "Max Payload Size set to %4d/%4d (was %4d), Max Read Rq %4d\n",
pcie_get_mps(dev), 128 << dev->pcie_mpss,
orig_mps, pcie_get_readrq(dev));
return 0;
}
-/* pcie_bus_configure_settings requires that pci_walk_bus work in a top-down,
+/*
+ * pcie_bus_configure_settings() requires that pci_walk_bus work in a top-down,
* parents then children fashion. If this changes, then this code will not
* work as designed.
*/
@@ -2410,7 +2472,8 @@ void pcie_bus_configure_settings(struct pci_bus *bus)
if (!pci_is_pcie(bus->self))
return;
- /* FIXME - Peer to peer DMA is possible, though the endpoint would need
+ /*
+ * FIXME - Peer to peer DMA is possible, though the endpoint would need
* to be aware of the MPS of the destination. To work around this,
* simply force the MPS of the entire system to the smallest possible.
*/
@@ -2464,7 +2527,7 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
for (devfn = 0; devfn < 0x100; devfn += 8)
pci_scan_slot(bus, devfn);
- /* Reserve buses for SR-IOV capability. */
+ /* Reserve buses for SR-IOV capability */
used_buses = pci_iov_bus_range(bus);
max += used_buses;
@@ -2506,6 +2569,7 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
unsigned int buses = 0;
if (!hotplug_bridges && normal_bridges == 1) {
+
/*
* There is only one bridge on the bus (upstream
* port) so it gets all available buses which it
@@ -2514,6 +2578,7 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
*/
buses = available_buses;
} else if (dev->is_hotplug_bridge) {
+
/*
* Distribute the extra buses between hotplug
* bridges if any.
@@ -2572,8 +2637,8 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus)
EXPORT_SYMBOL_GPL(pci_scan_child_bus);
/**
- * pcibios_root_bridge_prepare - Platform-specific host bridge setup.
- * @bridge: Host bridge to set up.
+ * pcibios_root_bridge_prepare - Platform-specific host bridge setup
+ * @bridge: Host bridge to set up
*
* Default empty implementation. Replace with an architecture-specific setup
* routine, if necessary.
@@ -2620,6 +2685,39 @@ err_out:
}
EXPORT_SYMBOL_GPL(pci_create_root_bus);
+int pci_host_probe(struct pci_host_bridge *bridge)
+{
+ struct pci_bus *bus, *child;
+ int ret;
+
+ ret = pci_scan_root_bus_bridge(bridge);
+ if (ret < 0) {
+ dev_err(bridge->dev.parent, "Scanning root bridge failed");
+ return ret;
+ }
+
+ bus = bridge->bus;
+
+ /*
+ * We insert PCI resources into the iomem_resource and
+ * ioport_resource trees in either pci_bus_claim_resources()
+ * or pci_bus_assign_resources().
+ */
+ if (pci_has_flag(PCI_PROBE_ONLY)) {
+ pci_bus_claim_resources(bus);
+ } else {
+ pci_bus_size_bridges(bus);
+ pci_bus_assign_resources(bus);
+
+ list_for_each_entry(child, &bus->children, node)
+ pcie_bus_configure_settings(child);
+ }
+
+ pci_bus_add_devices(bus);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pci_host_probe);
+
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
{
struct resource *res = &b->busn_res;
@@ -2776,7 +2874,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
EXPORT_SYMBOL(pci_scan_bus);
/**
- * pci_rescan_bus_bridge_resize - scan a PCI bus for devices.
+ * pci_rescan_bus_bridge_resize - Scan a PCI bus for devices
* @bridge: PCI bridge for the bus to scan
*
* Scan a PCI bus and child buses for new devices, add them,
@@ -2801,11 +2899,11 @@ unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge)
}
/**
- * pci_rescan_bus - scan a PCI bus for devices.
+ * pci_rescan_bus - Scan a PCI bus for devices
* @bus: PCI bus to scan
*
- * Scan a PCI bus and child buses for new devices, adds them,
- * and enables them.
+ * Scan a PCI bus and child buses for new devices, add them,
+ * and enable them.
*
* Returns the max number of subordinate bus discovered.
*/
@@ -2874,7 +2972,7 @@ int pci_hp_add_bridge(struct pci_dev *dev)
break;
}
if (busnr-- > end) {
- dev_err(&dev->dev, "No bus number available for hot-added bridge\n");
+ pci_err(dev, "No bus number available for hot-added bridge\n");
return -1;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 10684b17d0bd..fc734014206f 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -19,7 +19,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/acpi.h>
-#include <linux/kallsyms.h>
#include <linux/dmi.h>
#include <linux/pci-aspm.h>
#include <linux/ioport.h>
@@ -66,7 +65,7 @@ static void quirk_passive_release(struct pci_dev *dev)
while ((d = pci_get_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, d))) {
pci_read_config_byte(d, 0x82, &dlc);
if (!(dlc & 1<<1)) {
- dev_info(&d->dev, "PIIX3: Enabling Passive Release\n");
+ pci_info(d, "PIIX3: Enabling Passive Release\n");
dlc |= 1<<1;
pci_write_config_byte(d, 0x82, dlc);
}
@@ -86,7 +85,7 @@ static void quirk_isa_dma_hangs(struct pci_dev *dev)
{
if (!isa_dma_bridge_buggy) {
isa_dma_bridge_buggy = 1;
- dev_info(&dev->dev, "Activating ISA DMA hang workarounds\n");
+ pci_info(dev, "Activating ISA DMA hang workarounds\n");
}
}
/*
@@ -115,7 +114,7 @@ static void quirk_tigerpoint_bm_sts(struct pci_dev *dev)
pm1a = inw(pmbase);
if (pm1a & 0x10) {
- dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n");
+ pci_info(dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n");
outw(0x10, pmbase);
}
}
@@ -127,7 +126,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TGP_LPC, quirk
static void quirk_nopcipci(struct pci_dev *dev)
{
if ((pci_pci_problems & PCIPCI_FAIL) == 0) {
- dev_info(&dev->dev, "Disabling direct PCI/PCI transfers\n");
+ pci_info(dev, "Disabling direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_FAIL;
}
}
@@ -140,7 +139,7 @@ static void quirk_nopciamd(struct pci_dev *dev)
pci_read_config_byte(dev, 0x08, &rev);
if (rev == 0x13) {
/* Erratum 24 */
- dev_info(&dev->dev, "Chipset erratum: Disabling direct PCI/AGP transfers\n");
+ pci_info(dev, "Chipset erratum: Disabling direct PCI/AGP transfers\n");
pci_pci_problems |= PCIAGP_FAIL;
}
}
@@ -152,7 +151,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8151_0, quirk_nopci
static void quirk_triton(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_TRITON) == 0) {
- dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
+ pci_info(dev, "Limiting direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_TRITON;
}
}
@@ -212,7 +211,7 @@ static void quirk_vialatency(struct pci_dev *dev)
busarb &= ~(1<<5);
busarb |= (1<<4);
pci_write_config_byte(dev, 0x76, busarb);
- dev_info(&dev->dev, "Applying VIA southbridge workaround\n");
+ pci_info(dev, "Applying VIA southbridge workaround\n");
exit:
pci_dev_put(p);
}
@@ -230,7 +229,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_viala
static void quirk_viaetbf(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_VIAETBF) == 0) {
- dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
+ pci_info(dev, "Limiting direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_VIAETBF;
}
}
@@ -239,7 +238,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_via
static void quirk_vsfx(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_VSFX) == 0) {
- dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
+ pci_info(dev, "Limiting direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_VSFX;
}
}
@@ -254,7 +253,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C576, quirk_vsfx)
static void quirk_alimagik(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_ALIMAGIK) == 0) {
- dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
+ pci_info(dev, "Limiting direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_ALIMAGIK|PCIPCI_TRITON;
}
}
@@ -268,7 +267,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1651, quirk_alimagi
static void quirk_natoma(struct pci_dev *dev)
{
if ((pci_pci_problems&PCIPCI_NATOMA) == 0) {
- dev_info(&dev->dev, "Limiting direct PCI/PCI transfers\n");
+ pci_info(dev, "Limiting direct PCI/PCI transfers\n");
pci_pci_problems |= PCIPCI_NATOMA;
}
}
@@ -313,7 +312,7 @@ static void quirk_extend_bar_to_page(struct pci_dev *dev)
r->end = PAGE_SIZE - 1;
r->start = 0;
r->flags |= IORESOURCE_UNSET;
- dev_info(&dev->dev, "expanded BAR %d to page size: %pR\n",
+ pci_info(dev, "expanded BAR %d to page size: %pR\n",
i, r);
}
}
@@ -360,7 +359,7 @@ static void quirk_io(struct pci_dev *dev, int pos, unsigned size,
bus_region.end = region + size - 1;
pcibios_bus_to_resource(dev->bus, res, &bus_region);
- dev_info(&dev->dev, FW_BUG "%s quirk: reg 0x%x: %pR\n",
+ pci_info(dev, FW_BUG "%s quirk: reg 0x%x: %pR\n",
name, PCI_BASE_ADDRESS_0 + (pos << 2), res);
}
@@ -381,7 +380,7 @@ static void quirk_cs5536_vsa(struct pci_dev *dev)
quirk_io(dev, 0, 8, name); /* SMB */
quirk_io(dev, 1, 256, name); /* GPIO */
quirk_io(dev, 2, 64, name); /* MFGPT */
- dev_info(&dev->dev, "%s bug detected (incorrect header); workaround applied\n",
+ pci_info(dev, "%s bug detected (incorrect header); workaround applied\n",
name);
}
}
@@ -409,7 +408,7 @@ static void quirk_io_region(struct pci_dev *dev, int port,
pcibios_bus_to_resource(dev->bus, res, &bus_region);
if (!pci_claim_resource(dev, nr))
- dev_info(&dev->dev, "quirk: %pR claimed by %s\n", res, name);
+ pci_info(dev, "quirk: %pR claimed by %s\n", res, name);
}
/*
@@ -418,7 +417,7 @@ static void quirk_io_region(struct pci_dev *dev, int port,
*/
static void quirk_ati_exploding_mce(struct pci_dev *dev)
{
- dev_info(&dev->dev, "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb\n");
+ pci_info(dev, "ATI Northbridge, reserving I/O ports 0x3b0 to 0x3bb\n");
/* Mae rhaid i ni beidio ag edrych ar y lleoliadiau I/O hyn */
request_region(0x3b0, 0x0C, "RadeonIGP");
request_region(0x3d3, 0x01, "RadeonIGP");
@@ -441,7 +440,7 @@ static void quirk_amd_nl_class(struct pci_dev *pdev)
/* Use "USB Device (not host controller)" class */
pdev->class = PCI_CLASS_SERIAL_USB_DEVICE;
- dev_info(&pdev->dev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n",
+ pci_info(pdev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n",
class, pdev->class);
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB,
@@ -488,8 +487,7 @@ static void piix4_io_quirk(struct pci_dev *dev, const char *name, unsigned int p
* let's get enough confirmation reports first.
*/
base &= -size;
- dev_info(&dev->dev, "%s PIO at %04x-%04x\n", name, base,
- base + size - 1);
+ pci_info(dev, "%s PIO at %04x-%04x\n", name, base, base + size - 1);
}
static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int port, unsigned int enable)
@@ -514,8 +512,7 @@ static void piix4_mem_quirk(struct pci_dev *dev, const char *name, unsigned int
* reserve it, but let's get enough confirmation reports first.
*/
base &= -size;
- dev_info(&dev->dev, "%s MMIO at %04x-%04x\n", name, base,
- base + size - 1);
+ pci_info(dev, "%s MMIO at %04x-%04x\n", name, base, base + size - 1);
}
/*
@@ -644,7 +641,7 @@ static void ich6_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const cha
base &= ~(size-1);
/* Just print it out for now. We should reserve it after more debugging */
- dev_info(&dev->dev, "%s PIO at %04x-%04x\n", name, base, base+size-1);
+ pci_info(dev, "%s PIO at %04x-%04x\n", name, base, base+size-1);
}
static void quirk_ich6_lpc(struct pci_dev *dev)
@@ -679,7 +676,7 @@ static void ich7_lpc_generic_decode(struct pci_dev *dev, unsigned reg, const cha
mask |= 3;
/* Just print it out for now. We should reserve it after more debugging */
- dev_info(&dev->dev, "%s PIO at %04x (mask %04x)\n", name, base, mask);
+ pci_info(dev, "%s PIO at %04x (mask %04x)\n", name, base, mask);
}
/* ICH7-10 has the same common LPC generic IO decode registers */
@@ -758,7 +755,7 @@ static void quirk_xio2000a(struct pci_dev *dev)
struct pci_dev *pdev;
u16 command;
- dev_warn(&dev->dev, "TI XIO2000a quirk detected; secondary bus fast back-to-back transfers disabled\n");
+ pci_warn(dev, "TI XIO2000a quirk detected; secondary bus fast back-to-back transfers disabled\n");
list_for_each_entry(pdev, &dev->subordinate->devices, bus_list) {
pci_read_config_word(pdev, PCI_COMMAND, &command);
if (command & PCI_COMMAND_FAST_BACK)
@@ -788,7 +785,7 @@ static void quirk_via_ioapic(struct pci_dev *dev)
else
tmp = 0x1f; /* all known bits (4-0) routed to external APIC */
- dev_info(&dev->dev, "%sbling VIA external APIC routing\n",
+ pci_info(dev, "%sbling VIA external APIC routing\n",
tmp == 0 ? "Disa" : "Ena");
/* Offset 0x58: External APIC IRQ output control */
@@ -810,7 +807,7 @@ static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
pci_read_config_byte(dev, 0x5B, &misc_control2);
if (!(misc_control2 & BYPASS_APIC_DEASSERT)) {
- dev_info(&dev->dev, "Bypassing VIA 8237 APIC De-Assert Message\n");
+ pci_info(dev, "Bypassing VIA 8237 APIC De-Assert Message\n");
pci_write_config_byte(dev, 0x5B, misc_control2|BYPASS_APIC_DEASSERT);
}
}
@@ -829,8 +826,8 @@ DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk
static void quirk_amd_ioapic(struct pci_dev *dev)
{
if (dev->revision >= 0x02) {
- dev_warn(&dev->dev, "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n");
- dev_warn(&dev->dev, " : booting with the \"noapic\" option\n");
+ pci_warn(dev, "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n");
+ pci_warn(dev, " : booting with the \"noapic\" option\n");
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7410, quirk_amd_ioapic);
@@ -854,7 +851,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CAVIUM, 0xa018, quirk_cavium_sriov_rnm_lin
static void quirk_amd_8131_mmrbc(struct pci_dev *dev)
{
if (dev->subordinate && dev->revision <= 0x12) {
- dev_info(&dev->dev, "AMD8131 rev %x detected; disabling PCI-X MMRBC\n",
+ pci_info(dev, "AMD8131 rev %x detected; disabling PCI-X MMRBC\n",
dev->revision);
dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC;
}
@@ -962,7 +959,7 @@ static void quirk_via_vlink(struct pci_dev *dev)
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
if (new_irq != irq) {
- dev_info(&dev->dev, "VIA VLink IRQ fixup, from %d to %d\n",
+ pci_info(dev, "VIA VLink IRQ fixup, from %d to %d\n",
irq, new_irq);
udelay(15); /* unknown if delay really needed */
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
@@ -1011,7 +1008,7 @@ static void quirk_amd_ordering(struct pci_dev *dev)
pci_read_config_dword(dev, 0x4C, &pcic);
if ((pcic & 6) != 6) {
pcic |= 6;
- dev_warn(&dev->dev, "BIOS failed to enable PCI standards compliance; fixing this error\n");
+ pci_warn(dev, "BIOS failed to enable PCI standards compliance; fixing this error\n");
pci_write_config_dword(dev, 0x4C, pcic);
pci_read_config_dword(dev, 0x84, &pcic);
pcic |= (1 << 23); /* Required in this mode */
@@ -1064,7 +1061,7 @@ static void quirk_mediagx_master(struct pci_dev *dev)
pci_read_config_byte(dev, 0x41, &reg);
if (reg & 2) {
reg &= ~2;
- dev_info(&dev->dev, "Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n",
+ pci_info(dev, "Fixup for MediaGX/Geode Slave Disconnect Boundary (0x41=0x%02x)\n",
reg);
pci_write_config_byte(dev, 0x41, reg);
}
@@ -1087,7 +1084,7 @@ static void quirk_disable_pxb(struct pci_dev *pdev)
if (config & (1<<6)) {
config &= ~(1<<6);
pci_write_config_word(pdev, 0x40, config);
- dev_info(&pdev->dev, "C0 revision 450NX. Disabling PCI restreaming\n");
+ pci_info(pdev, "C0 revision 450NX. Disabling PCI restreaming\n");
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb);
@@ -1107,7 +1104,7 @@ static void quirk_amd_ide_mode(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x40, tmp);
pdev->class = PCI_CLASS_STORAGE_SATA_AHCI;
- dev_info(&pdev->dev, "set SATA to AHCI mode\n");
+ pci_info(pdev, "set SATA to AHCI mode\n");
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_amd_ide_mode);
@@ -1145,7 +1142,7 @@ static void quirk_ide_samemode(struct pci_dev *pdev)
pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog);
if (((prog & 1) && !(prog & 4)) || ((prog & 4) && !(prog & 1))) {
- dev_info(&pdev->dev, "IDE mode mismatch; forcing legacy mode\n");
+ pci_info(pdev, "IDE mode mismatch; forcing legacy mode\n");
prog &= ~5;
pdev->class &= ~5;
pci_write_config_byte(pdev, PCI_CLASS_PROG, prog);
@@ -1356,10 +1353,10 @@ static void asus_hides_smbus_lpc(struct pci_dev *dev)
pci_write_config_word(dev, 0xF2, val & (~0x8));
pci_read_config_word(dev, 0xF2, &val);
if (val & 0x8)
- dev_info(&dev->dev, "i801 SMBus device continues to play 'hide and seek'! 0x%x\n",
+ pci_info(dev, "i801 SMBus device continues to play 'hide and seek'! 0x%x\n",
val);
else
- dev_info(&dev->dev, "Enabled i801 SMBus device\n");
+ pci_info(dev, "Enabled i801 SMBus device\n");
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, asus_hides_smbus_lpc);
@@ -1411,7 +1408,7 @@ static void asus_hides_smbus_lpc_ich6_resume(struct pci_dev *dev)
return;
iounmap(asus_rcba_base);
asus_rcba_base = NULL;
- dev_info(&dev->dev, "Enabled ICH6/i801 SMBus device\n");
+ pci_info(dev, "Enabled ICH6/i801 SMBus device\n");
}
static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
@@ -1433,7 +1430,7 @@ static void quirk_sis_96x_smbus(struct pci_dev *dev)
u8 val = 0;
pci_read_config_byte(dev, 0x77, &val);
if (val & 0x10) {
- dev_info(&dev->dev, "Enabling SiS 96x SMBus\n");
+ pci_info(dev, "Enabling SiS 96x SMBus\n");
pci_write_config_byte(dev, 0x77, val & ~0x10);
}
}
@@ -1505,10 +1502,10 @@ static void asus_hides_ac97_lpc(struct pci_dev *dev)
pci_write_config_byte(dev, 0x50, val & (~0xc0));
pci_read_config_byte(dev, 0x50, &val);
if (val & 0xc0)
- dev_info(&dev->dev, "Onboard AC97/MC97 devices continue to play 'hide and seek'! 0x%x\n",
+ pci_info(dev, "Onboard AC97/MC97 devices continue to play 'hide and seek'! 0x%x\n",
val);
else
- dev_info(&dev->dev, "Enabled onboard AC97/MC97 devices\n");
+ pci_info(dev, "Enabled onboard AC97/MC97 devices\n");
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc);
@@ -1599,7 +1596,7 @@ static void quirk_jmicron_async_suspend(struct pci_dev *dev)
{
if (dev->multifunction) {
device_disable_async_suspend(&dev->dev);
- dev_info(&dev->dev, "async suspend disabled to avoid multi-function power-on ordering issue\n");
+ pci_info(dev, "async suspend disabled to avoid multi-function power-on ordering issue\n");
}
}
DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, 8, quirk_jmicron_async_suspend);
@@ -1636,8 +1633,8 @@ static void quirk_pcie_mch(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_pcie_mch);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_pcie_mch);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_pcie_mch);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1610, quirk_pcie_mch);
+DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1610, PCI_CLASS_BRIDGE_PCI, 8, quirk_pcie_mch);
/*
* It's possible for the MSI to get corrupted if shpc and acpi
@@ -1646,7 +1643,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_HUAWEI, 0x1610, quirk_pcie_mch);
static void quirk_pcie_pxh(struct pci_dev *dev)
{
dev->no_msi = 1;
- dev_warn(&dev->dev, "PXH quirk detected; SHPC device MSI disabled\n");
+ pci_warn(dev, "PXH quirk detected; SHPC device MSI disabled\n");
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHD_0, quirk_pcie_pxh);
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHD_1, quirk_pcie_pxh);
@@ -1692,7 +1689,7 @@ static void quirk_radeon_pm(struct pci_dev *dev)
dev->subsystem_device == 0x00e2) {
if (dev->d3_delay < 20) {
dev->d3_delay = 20;
- dev_info(&dev->dev, "extending delay after power-on from D3 to %d msec\n",
+ pci_info(dev, "extending delay after power-on from D3 to %d msec\n",
dev->d3_delay);
}
}
@@ -1736,7 +1733,7 @@ static void quirk_reroute_to_boot_interrupts_intel(struct pci_dev *dev)
return;
dev->irq_reroute_variant = INTEL_IRQ_REROUTE_VARIANT;
- dev_info(&dev->dev, "rerouting interrupts for [%04x:%04x]\n",
+ pci_info(dev, "rerouting interrupts for [%04x:%04x]\n",
dev->vendor, dev->device);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_80333_0, quirk_reroute_to_boot_interrupts_intel);
@@ -1779,7 +1776,7 @@ static void quirk_disable_intel_boot_interrupt(struct pci_dev *dev)
pci_config_word |= INTEL_6300_DISABLE_BOOT_IRQ;
pci_write_config_word(dev, INTEL_6300_IOAPIC_ABAR, pci_config_word);
- dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+ pci_info(dev, "disabled boot interrupts on device [%04x:%04x]\n",
dev->vendor, dev->device);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_10, quirk_disable_intel_boot_interrupt);
@@ -1812,7 +1809,7 @@ static void quirk_disable_broadcom_boot_interrupt(struct pci_dev *dev)
pci_write_config_dword(dev, BC_HT1000_FEATURE_REG, pci_config_dword);
- dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+ pci_info(dev, "disabled boot interrupts on device [%04x:%04x]\n",
dev->vendor, dev->device);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000SB, quirk_disable_broadcom_boot_interrupt);
@@ -1845,7 +1842,7 @@ static void quirk_disable_amd_813x_boot_interrupt(struct pci_dev *dev)
pci_config_dword &= ~AMD_813X_NOIOAMODE;
pci_write_config_dword(dev, AMD_813X_MISC, pci_config_dword);
- dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+ pci_info(dev, "disabled boot interrupts on device [%04x:%04x]\n",
dev->vendor, dev->device);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_amd_813x_boot_interrupt);
@@ -1864,12 +1861,12 @@ static void quirk_disable_amd_8111_boot_interrupt(struct pci_dev *dev)
pci_read_config_word(dev, AMD_8111_PCI_IRQ_ROUTING, &pci_config_word);
if (!pci_config_word) {
- dev_info(&dev->dev, "boot interrupts on device [%04x:%04x] already disabled\n",
+ pci_info(dev, "boot interrupts on device [%04x:%04x] already disabled\n",
dev->vendor, dev->device);
return;
}
pci_write_config_word(dev, AMD_8111_PCI_IRQ_ROUTING, 0);
- dev_info(&dev->dev, "disabled boot interrupts on device [%04x:%04x]\n",
+ pci_info(dev, "disabled boot interrupts on device [%04x:%04x]\n",
dev->vendor, dev->device);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS, quirk_disable_amd_8111_boot_interrupt);
@@ -1913,7 +1910,7 @@ static void quirk_plx_pci9050(struct pci_dev *dev)
if (pci_resource_len(dev, bar) == 0x80 &&
(pci_resource_start(dev, bar) & 0x80)) {
struct resource *r = &dev->resource[bar];
- dev_info(&dev->dev, "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n",
+ pci_info(dev, "Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n",
bar);
r->flags |= IORESOURCE_UNSET;
r->start = 0;
@@ -1960,7 +1957,7 @@ static void quirk_netmos(struct pci_dev *dev)
case PCI_DEVICE_ID_NETMOS_9845:
case PCI_DEVICE_ID_NETMOS_9855:
if (num_parallel) {
- dev_info(&dev->dev, "Netmos %04x (%u parallel, %u serial); changing class SERIAL to OTHER (use parport_serial)\n",
+ pci_info(dev, "Netmos %04x (%u parallel, %u serial); changing class SERIAL to OTHER (use parport_serial)\n",
dev->device, num_parallel, num_serial);
dev->class = (PCI_CLASS_COMMUNICATION_OTHER << 8) |
(dev->class & 0xff);
@@ -2046,13 +2043,13 @@ static void quirk_e100_interrupt(struct pci_dev *dev)
/* Convert from PCI bus to resource space. */
csr = ioremap(pci_resource_start(dev, 0), 8);
if (!csr) {
- dev_warn(&dev->dev, "Can't map e100 registers\n");
+ pci_warn(dev, "Can't map e100 registers\n");
return;
}
cmd_hi = readb(csr + 3);
if (cmd_hi == 0) {
- dev_warn(&dev->dev, "Firmware left e100 interrupts enabled; disabling\n");
+ pci_warn(dev, "Firmware left e100 interrupts enabled; disabling\n");
writeb(1, csr + 3);
}
@@ -2067,7 +2064,7 @@ DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID,
*/
static void quirk_disable_aspm_l0s(struct pci_dev *dev)
{
- dev_info(&dev->dev, "Disabling L0s\n");
+ pci_info(dev, "Disabling L0s\n");
pci_disable_link_state(dev, PCIE_LINK_STATE_L0S);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x10a7, quirk_disable_aspm_l0s);
@@ -2097,7 +2094,7 @@ static void fixup_rev1_53c810(struct pci_dev *dev)
return;
dev->class = PCI_CLASS_STORAGE_SCSI << 8;
- dev_info(&dev->dev, "NCR 53c810 rev 1 PCI class overridden (%#08x -> %#08x)\n",
+ pci_info(dev, "NCR 53c810 rev 1 PCI class overridden (%#08x -> %#08x)\n",
class, dev->class);
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
@@ -2110,7 +2107,7 @@ static void quirk_p64h2_1k_io(struct pci_dev *dev)
pci_read_config_word(dev, 0x40, &en1k);
if (en1k & 0x200) {
- dev_info(&dev->dev, "Enable I/O Space to 1KB granularity\n");
+ pci_info(dev, "Enable I/O Space to 1KB granularity\n");
dev->io_window_1k = 1;
}
}
@@ -2126,7 +2123,7 @@ static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
if (pci_read_config_byte(dev, 0xf41, &b) == 0) {
if (!(b & 0x20)) {
pci_write_config_byte(dev, 0xf41, b | 0x20);
- dev_info(&dev->dev, "Linking AER extended capability\n");
+ pci_info(dev, "Linking AER extended capability\n");
}
}
}
@@ -2164,7 +2161,7 @@ static void quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
/* Turn off PCI Bus Parking */
pci_write_config_byte(dev, 0x76, b ^ 0x40);
- dev_info(&dev->dev, "Disabling VIA CX700 PCI parking\n");
+ pci_info(dev, "Disabling VIA CX700 PCI parking\n");
}
}
@@ -2179,7 +2176,7 @@ static void quirk_via_cx700_pci_parking_caching(struct pci_dev *dev)
/* Disable "Read FIFO Timer" */
pci_write_config_byte(dev, 0x77, 0x0);
- dev_info(&dev->dev, "Disabling VIA CX700 PCI caching\n");
+ pci_info(dev, "Disabling VIA CX700 PCI caching\n");
}
}
}
@@ -2196,7 +2193,7 @@ static void quirk_blacklist_vpd(struct pci_dev *dev)
{
if (dev->vpd) {
dev->vpd->len = 0;
- dev_warn(&dev->dev, FW_BUG "disabling VPD access (can't determine size of non-standard VPD format)\n");
+ pci_warn(dev, FW_BUG "disabling VPD access (can't determine size of non-standard VPD format)\n");
}
}
@@ -2312,7 +2309,7 @@ static void quirk_unhide_mch_dev6(struct pci_dev *dev)
u8 reg;
if (pci_read_config_byte(dev, 0xF4, &reg) == 0 && !(reg & 0x02)) {
- dev_info(&dev->dev, "Enabling MCH 'Overflow' Device\n");
+ pci_info(dev, "Enabling MCH 'Overflow' Device\n");
pci_write_config_byte(dev, 0xF4, reg | 0x02);
}
}
@@ -2351,7 +2348,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1);
static void quirk_disable_all_msi(struct pci_dev *dev)
{
pci_no_msi();
- dev_warn(&dev->dev, "MSI quirk detected; MSI disabled\n");
+ pci_warn(dev, "MSI quirk detected; MSI disabled\n");
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_disable_all_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi);
@@ -2366,7 +2363,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, 0x0761, quirk_disable_all_msi);
static void quirk_disable_msi(struct pci_dev *dev)
{
if (dev->subordinate) {
- dev_warn(&dev->dev, "MSI quirk detected; subordinate MSI disabled\n");
+ pci_warn(dev, "MSI quirk detected; subordinate MSI disabled\n");
dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
}
}
@@ -2406,7 +2403,7 @@ static int msi_ht_cap_enabled(struct pci_dev *dev)
if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
&flags) == 0) {
- dev_info(&dev->dev, "Found %s HT MSI Mapping\n",
+ pci_info(dev, "Found %s HT MSI Mapping\n",
flags & HT_MSI_FLAGS_ENABLE ?
"enabled" : "disabled");
return (flags & HT_MSI_FLAGS_ENABLE) != 0;
@@ -2422,7 +2419,7 @@ static int msi_ht_cap_enabled(struct pci_dev *dev)
static void quirk_msi_ht_cap(struct pci_dev *dev)
{
if (dev->subordinate && !msi_ht_cap_enabled(dev)) {
- dev_warn(&dev->dev, "MSI quirk detected; subordinate MSI disabled\n");
+ pci_warn(dev, "MSI quirk detected; subordinate MSI disabled\n");
dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
}
}
@@ -2446,7 +2443,7 @@ static void quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
if (!pdev)
return;
if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
- dev_warn(&dev->dev, "MSI quirk detected; subordinate MSI disabled\n");
+ pci_warn(dev, "MSI quirk detected; subordinate MSI disabled\n");
dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
}
pci_dev_put(pdev);
@@ -2465,7 +2462,7 @@ static void ht_enable_msi_mapping(struct pci_dev *dev)
if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
&flags) == 0) {
- dev_info(&dev->dev, "Enabling HT MSI Mapping\n");
+ pci_info(dev, "Enabling HT MSI Mapping\n");
pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
flags | HT_MSI_FLAGS_ENABLE);
@@ -2492,7 +2489,7 @@ static void nvenet_msi_disable(struct pci_dev *dev)
if (board_name &&
(strstr(board_name, "P5N32-SLI PREMIUM") ||
strstr(board_name, "P5N32-E SLI"))) {
- dev_info(&dev->dev, "Disabling msi for MCP55 NIC on P5N32-SLI\n");
+ pci_info(dev, "Disabling MSI for MCP55 NIC on P5N32-SLI\n");
dev->no_msi = 1;
}
}
@@ -2669,7 +2666,7 @@ static void ht_disable_msi_mapping(struct pci_dev *dev)
if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
&flags) == 0) {
- dev_info(&dev->dev, "Disabling HT MSI Mapping\n");
+ pci_info(dev, "Disabling HT MSI Mapping\n");
pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
flags & ~HT_MSI_FLAGS_ENABLE);
@@ -2699,9 +2696,10 @@ static void __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all)
* HT MSI mapping should be disabled on devices that are below
* a non-Hypertransport host bridge. Locate the host bridge...
*/
- host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0));
+ host_bridge = pci_get_domain_bus_and_slot(pci_domain_nr(dev->bus), 0,
+ PCI_DEVFN(0, 0));
if (host_bridge == NULL) {
- dev_warn(&dev->dev, "nv_msi_ht_cap_quirk didn't locate host bridge\n");
+ pci_warn(dev, "nv_msi_ht_cap_quirk didn't locate host bridge\n");
return;
}
@@ -2770,7 +2768,7 @@ static void quirk_msi_intx_disable_qca_bug(struct pci_dev *dev)
{
/* AR816X/AR817X/E210X MSI is fixed at HW level from revision 0x18 */
if (dev->revision < 0x18) {
- dev_info(&dev->dev, "set MSI_INTX_DISABLE_BUG flag\n");
+ pci_info(dev, "set MSI_INTX_DISABLE_BUG flag\n");
dev->dev_flags |= PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG;
}
}
@@ -2899,8 +2897,8 @@ static void ricoh_mmc_fixup_rl5c476(struct pci_dev *dev)
pci_write_config_byte(dev, 0x8E, write_enable);
pci_write_config_byte(dev, 0x8D, write_target);
- dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n");
- dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+ pci_notice(dev, "proprietary Ricoh MMC controller disabled (via cardbus function)\n");
+ pci_notice(dev, "MMC cards are now supported by standard SDHCI controller\n");
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476);
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, ricoh_mmc_fixup_rl5c476);
@@ -2935,7 +2933,7 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev)
pci_write_config_byte(dev, 0xe1, 0x32);
pci_write_config_byte(dev, 0xfc, 0x00);
- dev_notice(&dev->dev, "MMC controller base frequency changed to 50Mhz.\n");
+ pci_notice(dev, "MMC controller base frequency changed to 50Mhz.\n");
}
pci_read_config_byte(dev, 0xCB, &disable);
@@ -2948,8 +2946,8 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev)
pci_write_config_byte(dev, 0xCB, disable | 0x02);
pci_write_config_byte(dev, 0xCA, write_enable);
- dev_notice(&dev->dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
- dev_notice(&dev->dev, "MMC cards are now supported by standard SDHCI controller\n");
+ pci_notice(dev, "proprietary Ricoh MMC controller disabled (via firewire function)\n");
+ pci_notice(dev, "MMC cards are now supported by standard SDHCI controller\n");
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
@@ -2990,7 +2988,7 @@ static void fixup_ti816x_class(struct pci_dev *dev)
/* TI 816x devices do not have class code set when in PCIe boot mode */
dev->class = PCI_CLASS_MULTIMEDIA_VIDEO << 8;
- dev_info(&dev->dev, "PCI class overridden (%#08x -> %#08x)\n",
+ pci_info(dev, "PCI class overridden (%#08x -> %#08x)\n",
class, dev->class);
}
DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_TI, 0xb800,
@@ -3032,7 +3030,7 @@ static void quirk_intel_mc_errata(struct pci_dev *dev)
*/
err = pci_read_config_word(dev, 0x48, &rcc);
if (err) {
- dev_err(&dev->dev, "Error attempting to read the read completion coalescing register\n");
+ pci_err(dev, "Error attempting to read the read completion coalescing register\n");
return;
}
@@ -3043,7 +3041,7 @@ static void quirk_intel_mc_errata(struct pci_dev *dev)
err = pci_write_config_word(dev, 0x48, rcc);
if (err) {
- dev_err(&dev->dev, "Error attempting to write the read completion coalescing register\n");
+ pci_err(dev, "Error attempting to write the read completion coalescing register\n");
return;
}
@@ -3108,7 +3106,7 @@ static ktime_t fixup_debug_start(struct pci_dev *dev,
{
ktime_t calltime = 0;
- dev_dbg(&dev->dev, "calling %pF\n", fn);
+ pci_dbg(dev, "calling %pF\n", fn);
if (initcall_debug) {
pr_debug("calling %pF @ %i for %s\n",
fn, task_pid_nr(current), dev_name(&dev->dev));
@@ -3150,13 +3148,13 @@ static void disable_igfx_irq(struct pci_dev *dev)
{
void __iomem *regs = pci_iomap(dev, 0, 0);
if (regs == NULL) {
- dev_warn(&dev->dev, "igfx quirk: Can't iomap PCI device\n");
+ pci_warn(dev, "igfx quirk: Can't iomap PCI device\n");
return;
}
/* Check if any interrupt line is still enabled */
if (readl(regs + I915_DEIER_REG) != 0) {
- dev_warn(&dev->dev, "BIOS left Intel GPU interrupts enabled; disabling\n");
+ pci_warn(dev, "BIOS left Intel GPU interrupts enabled; disabling\n");
writel(0, regs + I915_DEIER_REG);
}
@@ -3215,6 +3213,8 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x0030,
quirk_broken_intx_masking);
DECLARE_PCI_FIXUP_FINAL(0x1814, 0x0601, /* Ralink RT2800 802.11n PCI */
quirk_broken_intx_masking);
+DECLARE_PCI_FIXUP_FINAL(0x1b7c, 0x0004, /* Ceton InfiniTV4 */
+ quirk_broken_intx_masking);
/*
* Realtek RTL8169 PCI Gigabit Ethernet Controller (rev 10)
@@ -3317,13 +3317,13 @@ static void mellanox_check_broken_intx_masking(struct pci_dev *pdev)
/* For ConnectX-4 and ConnectX-4LX, need to check FW support */
if (pci_enable_device_mem(pdev)) {
- dev_warn(&pdev->dev, "Can't enable device memory\n");
+ pci_warn(pdev, "Can't enable device memory\n");
return;
}
fw_ver = ioremap(pci_resource_start(pdev, 0), 4);
if (!fw_ver) {
- dev_warn(&pdev->dev, "Can't map ConnectX-4 initialization segment\n");
+ pci_warn(pdev, "Can't map ConnectX-4 initialization segment\n");
goto out;
}
@@ -3335,7 +3335,7 @@ static void mellanox_check_broken_intx_masking(struct pci_dev *pdev)
fw_subminor = fw_sub_min & 0xffff;
if (fw_minor > CONNECTX_4_CURR_MAX_MINOR ||
fw_minor < CONNECTX_4_INTX_SUPPORT_MINOR) {
- dev_warn(&pdev->dev, "ConnectX-4: FW %u.%u.%u doesn't support INTx masking, disabling. Please upgrade FW to %d.14.1100 and up for INTx support\n",
+ pci_warn(pdev, "ConnectX-4: FW %u.%u.%u doesn't support INTx masking, disabling. Please upgrade FW to %d.14.1100 and up for INTx support\n",
fw_major, fw_minor, fw_subminor, pdev->device ==
PCI_DEVICE_ID_MELLANOX_CONNECTX4 ? 12 : 14);
pdev->broken_intx_masking = 1;
@@ -3473,7 +3473,7 @@ static void quirk_apple_poweroff_thunderbolt(struct pci_dev *dev)
|| ACPI_FAILURE(acpi_get_handle(bridge, "DSB0.NHI0.SXFP", &SXFP))
|| ACPI_FAILURE(acpi_get_handle(bridge, "DSB0.NHI0.SXLV", &SXLV)))
return;
- dev_info(&dev->dev, "quirk: cutting power to thunderbolt controller...\n");
+ pci_info(dev, "quirk: cutting power to thunderbolt controller...\n");
/* magic sequence */
acpi_execute_simple_method(SXIO, NULL, 1);
@@ -3524,7 +3524,7 @@ static void quirk_apple_wait_for_thunderbolt(struct pci_dev *dev)
nhi->device != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI)
|| nhi->class != PCI_CLASS_SYSTEM_OTHER << 8)
goto out;
- dev_info(&dev->dev, "quirk: waiting for thunderbolt to reestablish PCI tunnels...\n");
+ pci_info(dev, "quirk: waiting for thunderbolt to reestablish PCI tunnels...\n");
device_pm_wait_for_dev(&dev->dev, &nhi->dev);
out:
pci_dev_put(nhi);
@@ -3740,7 +3740,7 @@ static int reset_ivb_igd(struct pci_dev *dev, int probe)
goto reset_complete;
msleep(10);
} while (time_before(jiffies, timeout));
- dev_warn(&dev->dev, "timeout during reset\n");
+ pci_warn(dev, "timeout during reset\n");
reset_complete:
iowrite32(0x00000002, mmio_base + NSDE_PWR_STATE);
@@ -3879,6 +3879,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9120,
quirk_dma_func1_alias);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9123,
quirk_dma_func1_alias);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9128,
+ quirk_dma_func1_alias);
/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9130,
quirk_dma_func1_alias);
@@ -4012,7 +4014,7 @@ static void quirk_tw686x_class(struct pci_dev *pdev)
/* Use "Multimedia controller" class */
pdev->class = (PCI_CLASS_MULTIMEDIA_OTHER << 8) | 0x01;
- dev_info(&pdev->dev, "TW686x PCI class overridden (%#08x -> %#08x)\n",
+ pci_info(pdev, "TW686x PCI class overridden (%#08x -> %#08x)\n",
class, pdev->class);
}
DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6864, PCI_CLASS_NOT_DEFINED, 8,
@@ -4032,7 +4034,7 @@ DECLARE_PCI_FIXUP_CLASS_EARLY(0x1797, 0x6869, PCI_CLASS_NOT_DEFINED, 8,
static void quirk_relaxedordering_disable(struct pci_dev *dev)
{
dev->dev_flags |= PCI_DEV_FLAGS_NO_RELAXED_ORDERING;
- dev_info(&dev->dev, "Disable Relaxed Ordering Attributes to avoid PCIe Completion erratum\n");
+ pci_info(dev, "Disable Relaxed Ordering Attributes to avoid PCIe Completion erratum\n");
}
/*
@@ -4141,11 +4143,11 @@ static void quirk_disable_root_port_attributes(struct pci_dev *pdev)
struct pci_dev *root_port = pci_find_pcie_root_port(pdev);
if (!root_port) {
- dev_warn(&pdev->dev, "PCIe Completion erratum may cause device errors\n");
+ pci_warn(pdev, "PCIe Completion erratum may cause device errors\n");
return;
}
- dev_info(&root_port->dev, "Disabling No Snoop/Relaxed Ordering Attributes to avoid PCIe Completion erratum in %s\n",
+ pci_info(root_port, "Disabling No Snoop/Relaxed Ordering Attributes to avoid PCIe Completion erratum in %s\n",
dev_name(&pdev->dev));
pcie_capability_clear_and_set_word(root_port, PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_RELAX_EN |
@@ -4339,7 +4341,7 @@ static int pci_quirk_qcom_rp_acs(struct pci_dev *dev, u16 acs_flags)
u16 flags = (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF | PCI_ACS_SV);
int ret = acs_flags & ~flags ? 0 : 1;
- dev_info(&dev->dev, "Using QCOM ACS Quirk (%d)\n", ret);
+ pci_info(dev, "Using QCOM ACS Quirk (%d)\n", ret);
return ret;
}
@@ -4591,7 +4593,7 @@ static int pci_quirk_enable_intel_lpc_acs(struct pci_dev *dev)
if (bspr != (INTEL_BSPR_REG_BPNPD | INTEL_BSPR_REG_BPPD)) {
updcr = readl(rcba_mem + INTEL_UPDCR_REG);
if (updcr & INTEL_UPDCR_REG_MASK) {
- dev_info(&dev->dev, "Disabling UPDCR peer decodes\n");
+ pci_info(dev, "Disabling UPDCR peer decodes\n");
updcr &= ~INTEL_UPDCR_REG_MASK;
writel(updcr, rcba_mem + INTEL_UPDCR_REG);
}
@@ -4618,7 +4620,7 @@ static void pci_quirk_enable_intel_rp_mpc_acs(struct pci_dev *dev)
*/
pci_read_config_dword(dev, INTEL_MPC_REG, &mpc);
if (!(mpc & INTEL_MPC_REG_IRBNCE)) {
- dev_info(&dev->dev, "Enabling MPC IRBNCE\n");
+ pci_info(dev, "Enabling MPC IRBNCE\n");
mpc |= INTEL_MPC_REG_IRBNCE;
pci_write_config_word(dev, INTEL_MPC_REG, mpc);
}
@@ -4630,7 +4632,7 @@ static int pci_quirk_enable_intel_pch_acs(struct pci_dev *dev)
return -ENOTTY;
if (pci_quirk_enable_intel_lpc_acs(dev)) {
- dev_warn(&dev->dev, "Failed to enable Intel PCH ACS quirk\n");
+ pci_warn(dev, "Failed to enable Intel PCH ACS quirk\n");
return 0;
}
@@ -4638,7 +4640,7 @@ static int pci_quirk_enable_intel_pch_acs(struct pci_dev *dev)
dev->dev_flags |= PCI_DEV_FLAGS_ACS_ENABLED_QUIRK;
- dev_info(&dev->dev, "Intel PCH root port ACS workaround enabled\n");
+ pci_info(dev, "Intel PCH root port ACS workaround enabled\n");
return 0;
}
@@ -4665,7 +4667,7 @@ static int pci_quirk_enable_intel_spt_pch_acs(struct pci_dev *dev)
pci_write_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, ctrl);
- dev_info(&dev->dev, "Intel SPT PCH root port ACS workaround enabled\n");
+ pci_info(dev, "Intel SPT PCH root port ACS workaround enabled\n");
return 0;
}
@@ -4800,7 +4802,7 @@ static void quirk_no_ext_tags(struct pci_dev *pdev)
return;
bridge->no_ext_tags = 1;
- dev_info(&pdev->dev, "disabling Extended Tags (this device can't handle them)\n");
+ pci_info(pdev, "disabling Extended Tags (this device can't handle them)\n");
pci_walk_bus(bridge->bus, pci_configure_extended_tags, NULL);
}
@@ -4815,7 +4817,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, 0x0144, quirk_no_ext_tags);
*/
static void quirk_no_ats(struct pci_dev *pdev)
{
- dev_info(&pdev->dev, "disabling ATS (broken on this device)\n");
+ pci_info(pdev, "disabling ATS (broken on this device)\n");
pdev->ats_cap = 0;
}
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 2fa0dbde36b7..6f072eae4f7a 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/pci-aspm.h>
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index 1f5e6af96c83..374a33443be9 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/rom.c
*
@@ -92,15 +93,15 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
void __iomem *pds;
/* Standard PCI ROMs start out with these bytes 55 AA */
if (readw(image) != 0xAA55) {
- dev_err(&pdev->dev, "Invalid PCI ROM header signature: expecting 0xaa55, got %#06x\n",
- readw(image));
+ pci_info(pdev, "Invalid PCI ROM header signature: expecting 0xaa55, got %#06x\n",
+ readw(image));
break;
}
/* get the PCI data structure and check its "PCIR" signature */
pds = image + readw(image + 24);
if (readl(pds) != 0x52494350) {
- dev_err(&pdev->dev, "Invalid PCI ROM data signature: expecting 0x52494350, got %#010x\n",
- readl(pds));
+ pci_info(pdev, "Invalid PCI ROM data signature: expecting 0x52494350, got %#010x\n",
+ readl(pds));
break;
}
last_image = readb(pds + 21) & 0x80;
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 4c6044ad7368..bc1e023f1353 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCI searching functions.
*
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index b1ad466199ad..3cce29a069e6 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/setup-bus.c
*
@@ -67,10 +68,8 @@ static int add_to_list(struct list_head *head,
struct pci_dev_resource *tmp;
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
- if (!tmp) {
- pr_warn("add_to_list: kmalloc() failed!\n");
+ if (!tmp)
return -ENOMEM;
- }
tmp->res = res;
tmp->dev = dev;
@@ -152,7 +151,7 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head)
r_align = pci_resource_alignment(dev, r);
if (!r_align) {
- dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n",
+ pci_warn(dev, "BAR %d: %pR has bogus alignment\n",
i, r);
continue;
}
@@ -260,7 +259,7 @@ static void reassign_resources_sorted(struct list_head *realloc_head,
(IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN);
if (pci_reassign_resource(add_res->dev, idx,
add_size, align))
- dev_printk(KERN_DEBUG, &add_res->dev->dev,
+ pci_printk(KERN_DEBUG, add_res->dev,
"failed to add %llx res[%d]=%pR\n",
(unsigned long long)add_size,
idx, res);
@@ -519,7 +518,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
struct resource *res;
struct pci_bus_region region;
- dev_info(&bridge->dev, "CardBus bridge to %pR\n",
+ pci_info(bridge, "CardBus bridge to %pR\n",
&bus->busn_res);
res = bus->resource[0];
@@ -529,7 +528,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
* The IO resource is allocated a range twice as large as it
* would normally need. This allows us to set both IO regs.
*/
- dev_info(&bridge->dev, " bridge window %pR\n", res);
+ pci_info(bridge, " bridge window %pR\n", res);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_0,
region.start);
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0,
@@ -539,7 +538,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
res = bus->resource[1];
pcibios_resource_to_bus(bridge->bus, &region, res);
if (res->flags & IORESOURCE_IO) {
- dev_info(&bridge->dev, " bridge window %pR\n", res);
+ pci_info(bridge, " bridge window %pR\n", res);
pci_write_config_dword(bridge, PCI_CB_IO_BASE_1,
region.start);
pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1,
@@ -549,7 +548,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
res = bus->resource[2];
pcibios_resource_to_bus(bridge->bus, &region, res);
if (res->flags & IORESOURCE_MEM) {
- dev_info(&bridge->dev, " bridge window %pR\n", res);
+ pci_info(bridge, " bridge window %pR\n", res);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0,
region.start);
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0,
@@ -559,7 +558,7 @@ void pci_setup_cardbus(struct pci_bus *bus)
res = bus->resource[3];
pcibios_resource_to_bus(bridge->bus, &region, res);
if (res->flags & IORESOURCE_MEM) {
- dev_info(&bridge->dev, " bridge window %pR\n", res);
+ pci_info(bridge, " bridge window %pR\n", res);
pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1,
region.start);
pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1,
@@ -602,7 +601,7 @@ static void pci_setup_bridge_io(struct pci_dev *bridge)
l = ((u16) io_limit_lo << 8) | io_base_lo;
/* Set up upper 16 bits of I/O base/limit. */
io_upper16 = (region.end & 0xffff0000) | (region.start >> 16);
- dev_info(&bridge->dev, " bridge window %pR\n", res);
+ pci_info(bridge, " bridge window %pR\n", res);
} else {
/* Clear upper 16 bits of I/O base/limit. */
io_upper16 = 0;
@@ -628,7 +627,7 @@ static void pci_setup_bridge_mmio(struct pci_dev *bridge)
if (res->flags & IORESOURCE_MEM) {
l = (region.start >> 16) & 0xfff0;
l |= region.end & 0xfff00000;
- dev_info(&bridge->dev, " bridge window %pR\n", res);
+ pci_info(bridge, " bridge window %pR\n", res);
} else {
l = 0x0000fff0;
}
@@ -657,7 +656,7 @@ static void pci_setup_bridge_mmio_pref(struct pci_dev *bridge)
bu = upper_32_bits(region.start);
lu = upper_32_bits(region.end);
}
- dev_info(&bridge->dev, " bridge window %pR\n", res);
+ pci_info(bridge, " bridge window %pR\n", res);
} else {
l = 0x0000fff0;
}
@@ -672,7 +671,7 @@ static void __pci_setup_bridge(struct pci_bus *bus, unsigned long type)
{
struct pci_dev *bridge = bus->self;
- dev_info(&bridge->dev, "PCI bridge to %pR\n",
+ pci_info(bridge, "PCI bridge to %pR\n",
&bus->busn_res);
if (type & IORESOURCE_IO)
@@ -944,7 +943,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
resource_size(b_res), min_align);
if (!size0 && !size1) {
if (b_res->start || b_res->end)
- dev_info(&bus->self->dev, "disabling bridge window %pR to %pR (unused)\n",
+ pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n",
b_res, &bus->busn_res);
b_res->flags = 0;
return;
@@ -956,7 +955,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size,
if (size1 > size0 && realloc_head) {
add_to_list(realloc_head, bus->self, b_res, size1-size0,
min_align);
- dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window %pR to %pR add_size %llx\n",
+ pci_printk(KERN_DEBUG, bus->self, "bridge window %pR to %pR add_size %llx\n",
b_res, &bus->busn_res,
(unsigned long long)size1-size0);
}
@@ -1061,7 +1060,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
if (order < 0)
order = 0;
if (order >= ARRAY_SIZE(aligns)) {
- dev_warn(&dev->dev, "disabling BAR %d: %pR (bad alignment %#llx)\n",
+ pci_warn(dev, "disabling BAR %d: %pR (bad alignment %#llx)\n",
i, r, (unsigned long long) align);
r->flags = 0;
continue;
@@ -1093,7 +1092,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
resource_size(b_res), add_align);
if (!size0 && !size1) {
if (b_res->start || b_res->end)
- dev_info(&bus->self->dev, "disabling bridge window %pR to %pR (unused)\n",
+ pci_info(bus->self, "disabling bridge window %pR to %pR (unused)\n",
b_res, &bus->busn_res);
b_res->flags = 0;
return 0;
@@ -1103,7 +1102,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
b_res->flags |= IORESOURCE_STARTALIGN;
if (size1 > size0 && realloc_head) {
add_to_list(realloc_head, bus->self, b_res, size1-size0, add_align);
- dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window %pR to %pR add_size %llx add_align %llx\n",
+ pci_printk(KERN_DEBUG, bus->self, "bridge window %pR to %pR add_size %llx add_align %llx\n",
b_res, &bus->busn_res,
(unsigned long long) (size1 - size0),
(unsigned long long) add_align);
@@ -1407,7 +1406,7 @@ void __pci_bus_assign_resources(const struct pci_bus *bus,
break;
default:
- dev_info(&dev->dev, "not setting up bridge for bus %04x:%02x\n",
+ pci_info(dev, "not setting up bridge for bus %04x:%02x\n",
pci_domain_nr(b), b->number);
break;
}
@@ -1513,7 +1512,7 @@ static void __pci_bridge_assign_resources(const struct pci_dev *bridge,
break;
default:
- dev_info(&bridge->dev, "not setting up bridge for bus %04x:%02x\n",
+ pci_info(bridge, "not setting up bridge for bus %04x:%02x\n",
pci_domain_nr(b), b->number);
break;
}
@@ -1571,7 +1570,7 @@ static void pci_bridge_release_resources(struct pci_bus *bus,
release_child_resources(r);
if (!release_resource(r)) {
type = old_flags = r->flags & PCI_RES_TYPE_MASK;
- dev_printk(KERN_DEBUG, &dev->dev, "resource %d %pR released\n",
+ pci_printk(KERN_DEBUG, dev, "resource %d %pR released\n",
PCI_BRIDGE_RESOURCES + idx, r);
/* keep the old size */
r->end = resource_size(r) - 1;
@@ -1874,7 +1873,7 @@ static void extend_bridge_window(struct pci_dev *bridge, struct resource *res,
return;
dev_res->add_size = available - resource_size(res);
- dev_dbg(&bridge->dev, "bridge window %pR extended by %pa\n", res,
+ pci_dbg(bridge, "bridge window %pR extended by %pa\n", res,
&dev_res->add_size);
}
@@ -2085,7 +2084,7 @@ again:
enable_all:
retval = pci_reenable_device(bridge);
if (retval)
- dev_err(&bridge->dev, "Error reenabling bridge (%d)\n", retval);
+ pci_err(bridge, "Error reenabling bridge (%d)\n", retval);
pci_set_master(bridge);
}
EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
@@ -2119,7 +2118,7 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
if (ret)
goto cleanup;
- dev_info(&bridge->dev, "BAR %d: releasing %pR\n",
+ pci_info(bridge, "BAR %d: releasing %pR\n",
i, res);
if (res->parent)
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index 86106c44ce94..5ad4ee7d7b1e 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/setup-irq.c
*
@@ -25,7 +26,7 @@ void pci_assign_irq(struct pci_dev *dev)
struct pci_host_bridge *hbrg = pci_find_host_bridge(dev->bus);
if (!(hbrg->map_irq)) {
- dev_dbg(&dev->dev, "runtime IRQ mapping not provided by arch\n");
+ pci_dbg(dev, "runtime IRQ mapping not provided by arch\n");
return;
}
@@ -55,7 +56,7 @@ void pci_assign_irq(struct pci_dev *dev)
}
dev->irq = irq;
- dev_dbg(&dev->dev, "assign IRQ: got %d\n", dev->irq);
+ pci_dbg(dev, "assign IRQ: got %d\n", dev->irq);
/* Always tell the device, so the driver knows what is
the real IRQ to use; the device does not use it. */
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index e815111f3f81..369d48d6c6f1 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -103,7 +103,7 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno)
pci_read_config_dword(dev, reg, &check);
if ((new ^ check) & mask) {
- dev_err(&dev->dev, "BAR %d: error updating (%#08x != %#08x)\n",
+ pci_err(dev, "BAR %d: error updating (%#08x != %#08x)\n",
resno, new, check);
}
@@ -112,7 +112,7 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno)
pci_write_config_dword(dev, reg + 4, new);
pci_read_config_dword(dev, reg + 4, &check);
if (check != new) {
- dev_err(&dev->dev, "BAR %d: error updating (high %#08x != %#08x)\n",
+ pci_err(dev, "BAR %d: error updating (high %#08x != %#08x)\n",
resno, new, check);
}
}
@@ -137,7 +137,7 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
struct resource *root, *conflict;
if (res->flags & IORESOURCE_UNSET) {
- dev_info(&dev->dev, "can't claim BAR %d %pR: no address assigned\n",
+ pci_info(dev, "can't claim BAR %d %pR: no address assigned\n",
resource, res);
return -EINVAL;
}
@@ -152,7 +152,7 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
root = pci_find_parent_resource(dev, res);
if (!root) {
- dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n",
+ pci_info(dev, "can't claim BAR %d %pR: no compatible bridge window\n",
resource, res);
res->flags |= IORESOURCE_UNSET;
return -EINVAL;
@@ -160,7 +160,7 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
conflict = request_resource_conflict(root, res);
if (conflict) {
- dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
+ pci_info(dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
resource, res, conflict->name, conflict);
res->flags |= IORESOURCE_UNSET;
return -EBUSY;
@@ -172,7 +172,7 @@ EXPORT_SYMBOL(pci_claim_resource);
void pci_disable_bridge_window(struct pci_dev *dev)
{
- dev_info(&dev->dev, "disabling bridge mem windows\n");
+ pci_info(dev, "disabling bridge mem windows\n");
/* MMIO Base/Limit */
pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
@@ -221,11 +221,11 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
root = &iomem_resource;
}
- dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n",
+ pci_info(dev, "BAR %d: trying firmware assignment %pR\n",
resno, res);
conflict = request_resource_conflict(root, res);
if (conflict) {
- dev_info(&dev->dev, "BAR %d: %pR conflicts with %s %pR\n",
+ pci_info(dev, "BAR %d: %pR conflicts with %s %pR\n",
resno, res, conflict->name, conflict);
res->start = start;
res->end = end;
@@ -324,7 +324,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
res->flags |= IORESOURCE_UNSET;
align = pci_resource_alignment(dev, res);
if (!align) {
- dev_info(&dev->dev, "BAR %d: can't assign %pR (bogus alignment)\n",
+ pci_info(dev, "BAR %d: can't assign %pR (bogus alignment)\n",
resno, res);
return -EINVAL;
}
@@ -338,19 +338,18 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
* working, which is better than just leaving it disabled.
*/
if (ret < 0) {
- dev_info(&dev->dev, "BAR %d: no space for %pR\n", resno, res);
+ pci_info(dev, "BAR %d: no space for %pR\n", resno, res);
ret = pci_revert_fw_address(res, dev, resno, size);
}
if (ret < 0) {
- dev_info(&dev->dev, "BAR %d: failed to assign %pR\n", resno,
- res);
+ pci_info(dev, "BAR %d: failed to assign %pR\n", resno, res);
return ret;
}
res->flags &= ~IORESOURCE_UNSET;
res->flags &= ~IORESOURCE_STARTALIGN;
- dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res);
+ pci_info(dev, "BAR %d: assigned %pR\n", resno, res);
if (resno < PCI_BRIDGE_RESOURCES)
pci_update_resource(dev, resno);
@@ -372,7 +371,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
flags = res->flags;
res->flags |= IORESOURCE_UNSET;
if (!res->parent) {
- dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR\n",
+ pci_info(dev, "BAR %d: can't reassign an unassigned resource %pR\n",
resno, res);
return -EINVAL;
}
@@ -382,14 +381,14 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
ret = _pci_assign_resource(dev, resno, new_size, min_align);
if (ret) {
res->flags = flags;
- dev_info(&dev->dev, "BAR %d: %pR (failed to expand by %#llx)\n",
+ pci_info(dev, "BAR %d: %pR (failed to expand by %#llx)\n",
resno, res, (unsigned long long) addsize);
return ret;
}
res->flags &= ~IORESOURCE_UNSET;
res->flags &= ~IORESOURCE_STARTALIGN;
- dev_info(&dev->dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
+ pci_info(dev, "BAR %d: reassigned %pR (expanded by %#llx)\n",
resno, res, (unsigned long long) addsize);
if (resno < PCI_BRIDGE_RESOURCES)
pci_update_resource(dev, resno);
@@ -401,7 +400,7 @@ void pci_release_resource(struct pci_dev *dev, int resno)
{
struct resource *res = dev->resource + resno;
- dev_info(&dev->dev, "BAR %d: releasing %pR\n", resno, res);
+ pci_info(dev, "BAR %d: releasing %pR\n", resno, res);
release_resource(res);
res->end = resource_size(res) - 1;
res->start = 0;
@@ -477,13 +476,13 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
continue;
if (r->flags & IORESOURCE_UNSET) {
- dev_err(&dev->dev, "can't enable device: BAR %d %pR not assigned\n",
+ pci_err(dev, "can't enable device: BAR %d %pR not assigned\n",
i, r);
return -EINVAL;
}
if (!r->parent) {
- dev_err(&dev->dev, "can't enable device: BAR %d %pR not claimed\n",
+ pci_err(dev, "can't enable device: BAR %d %pR not claimed\n",
i, r);
return -EINVAL;
}
@@ -495,8 +494,7 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
}
if (cmd != old_cmd) {
- dev_info(&dev->dev, "enabling device (%04x -> %04x)\n",
- old_cmd, cmd);
+ pci_info(dev, "enabling device (%04x -> %04x)\n", old_cmd, cmd);
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
return 0;
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index e42909524dee..d10f556dc03e 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* drivers/pci/slot.c
* Copyright (C) 2006 Matthew Wilcox <matthew@wil.cx>
diff --git a/drivers/pci/switch/Kconfig b/drivers/pci/switch/Kconfig
index 4c49648e0646..aee28a5bb98f 100644
--- a/drivers/pci/switch/Kconfig
+++ b/drivers/pci/switch/Kconfig
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
menu "PCI switch controller drivers"
depends on PCI
diff --git a/drivers/pci/switch/Makefile b/drivers/pci/switch/Makefile
index 37d8cfb03f3f..acd56d3b4a35 100644
--- a/drivers/pci/switch/Makefile
+++ b/drivers/pci/switch/Makefile
@@ -1 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PCI_SW_SWITCHTEC) += switchtec.o
diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index fab143a17f9c..a60c0ab7883d 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -1,16 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Microsemi Switchtec(tm) PCIe Management Driver
* Copyright (c) 2017, Microsemi Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
*/
#include <linux/switchtec.h>
@@ -707,6 +698,7 @@ static const struct event_reg {
EV_GLB(SWITCHTEC_IOCTL_EVENT_CLI_MRPC_COMP_ASYNC,
cli_mrpc_comp_async_hdr),
EV_GLB(SWITCHTEC_IOCTL_EVENT_GPIO_INT, gpio_interrupt_hdr),
+ EV_GLB(SWITCHTEC_IOCTL_EVENT_GFMS, gfms_event_hdr),
EV_PAR(SWITCHTEC_IOCTL_EVENT_PART_RESET, part_reset_hdr),
EV_PAR(SWITCHTEC_IOCTL_EVENT_MRPC_COMP, mrpc_comp_hdr),
EV_PAR(SWITCHTEC_IOCTL_EVENT_MRPC_COMP_ASYNC, mrpc_comp_async_hdr),
@@ -1352,6 +1344,8 @@ static const struct pci_device_id switchtec_pci_tbl[] = {
SWITCHTEC_PCI_DEVICE(0x8534), //PFX 64xG3
SWITCHTEC_PCI_DEVICE(0x8535), //PFX 80xG3
SWITCHTEC_PCI_DEVICE(0x8536), //PFX 96xG3
+ SWITCHTEC_PCI_DEVICE(0x8541), //PSX 24xG3
+ SWITCHTEC_PCI_DEVICE(0x8542), //PSX 32xG3
SWITCHTEC_PCI_DEVICE(0x8543), //PSX 48xG3
SWITCHTEC_PCI_DEVICE(0x8544), //PSX 64xG3
SWITCHTEC_PCI_DEVICE(0x8545), //PSX 80xG3
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
index 83efa001c2e7..e725f99b5479 100644
--- a/drivers/pci/syscall.c
+++ b/drivers/pci/syscall.c
@@ -28,7 +28,7 @@ SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn,
return -EPERM;
err = -ENODEV;
- dev = pci_get_bus_and_slot(bus, dfn);
+ dev = pci_get_domain_bus_and_slot(0, bus, dfn);
if (!dev)
goto error;
@@ -96,7 +96,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- dev = pci_get_bus_and_slot(bus, dfn);
+ dev = pci_get_domain_bus_and_slot(0, bus, dfn);
if (!dev)
return -ENODEV;
diff --git a/drivers/pci/vc.c b/drivers/pci/vc.c
index 1fa3a3219c45..5acd9c02683a 100644
--- a/drivers/pci/vc.c
+++ b/drivers/pci/vc.c
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCI Virtual Channel support
*
* Copyright (C) 2013 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.
*/
#include <linux/device.h>
@@ -57,7 +54,7 @@ static void pci_vc_load_arb_table(struct pci_dev *dev, int pos)
PCI_VC_PORT_STATUS_TABLE))
return;
- dev_err(&dev->dev, "VC arbitration table failed to load\n");
+ pci_err(dev, "VC arbitration table failed to load\n");
}
/**
@@ -85,7 +82,7 @@ static void pci_vc_load_port_arb_table(struct pci_dev *dev, int pos, int res)
if (pci_wait_for_pending(dev, status_pos, PCI_VC_RES_STATUS_TABLE))
return;
- dev_err(&dev->dev, "VC%d port arbitration table failed to load\n", res);
+ pci_err(dev, "VC%d port arbitration table failed to load\n", res);
}
/**
@@ -161,11 +158,11 @@ enable:
pci_write_config_dword(dev, ctrl_pos, ctrl);
if (!pci_wait_for_pending(dev, status_pos, PCI_VC_RES_STATUS_NEGO))
- dev_err(&dev->dev, "VC%d negotiation stuck pending\n", id);
+ pci_err(dev, "VC%d negotiation stuck pending\n", id);
if (link && !pci_wait_for_pending(link, status_pos2,
PCI_VC_RES_STATUS_NEGO))
- dev_err(&link->dev, "VC%d negotiation stuck pending\n", id);
+ pci_err(link, "VC%d negotiation stuck pending\n", id);
}
/**
@@ -195,8 +192,7 @@ static int pci_vc_do_save_buffer(struct pci_dev *dev, int pos,
/* Sanity check buffer size for save/restore */
if (buf && save_state->cap.size !=
pci_vc_do_save_buffer(dev, pos, NULL, save)) {
- dev_err(&dev->dev,
- "VC save buffer size does not match @0x%x\n", pos);
+ pci_err(dev, "VC save buffer size does not match @0x%x\n", pos);
return -ENOMEM;
}
@@ -366,14 +362,14 @@ int pci_save_vc_state(struct pci_dev *dev)
save_state = pci_find_saved_ext_cap(dev, vc_caps[i].id);
if (!save_state) {
- dev_err(&dev->dev, "%s buffer not found in %s\n",
+ pci_err(dev, "%s buffer not found in %s\n",
vc_caps[i].name, __func__);
return -ENOMEM;
}
ret = pci_vc_do_save_buffer(dev, pos, save_state, true);
if (ret) {
- dev_err(&dev->dev, "%s save unsuccessful %s\n",
+ pci_err(dev, "%s save unsuccessful %s\n",
vc_caps[i].name, __func__);
return ret;
}
@@ -426,8 +422,7 @@ void pci_allocate_vc_save_buffers(struct pci_dev *dev)
len = pci_vc_do_save_buffer(dev, pos, NULL, false);
if (pci_add_ext_cap_save_buffer(dev, vc_caps[i].id, len))
- dev_err(&dev->dev,
- "unable to preallocate %s save buffer\n",
+ pci_err(dev, "unable to preallocate %s save buffer\n",
vc_caps[i].name);
}
}
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
index 39b79070335d..70fba57d6103 100644
--- a/drivers/pci/vpd.c
+++ b/drivers/pci/vpd.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* File: vpd.c
* Purpose: Provide PCI VPD support
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 8fc2e9532575..8785014f656e 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Xen PCI Frontend.
*
@@ -261,8 +262,8 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
struct msi_desc *entry;
if (nvec > SH_INFO_MAX_VEC) {
- dev_err(&dev->dev, "too much vector for pci frontend: %x."
- " Increase SH_INFO_MAX_VEC.\n", nvec);
+ pci_err(dev, "too many vectors (0x%x) for PCI frontend:"
+ " Increase SH_INFO_MAX_VEC\n", nvec);
return -EINVAL;
}
@@ -281,7 +282,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
/* we get the result */
for (i = 0; i < nvec; i++) {
if (op.msix_entries[i].vector <= 0) {
- dev_warn(&dev->dev, "MSI-X entry %d is invalid: %d!\n",
+ pci_warn(dev, "MSI-X entry %d is invalid: %d!\n",
i, op.msix_entries[i].vector);
err = -EINVAL;
vector[i] = -1;
@@ -295,7 +296,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
err = op.value;
}
} else {
- dev_err(&dev->dev, "enable msix get err %x\n", err);
+ pci_err(dev, "enable msix get err %x\n", err);
}
return err;
}
@@ -316,7 +317,7 @@ static void pci_frontend_disable_msix(struct pci_dev *dev)
/* What should do for error ? */
if (err)
- dev_err(&dev->dev, "pci_disable_msix get err %x\n", err);
+ pci_err(dev, "pci_disable_msix get err %x\n", err);
}
static int pci_frontend_enable_msi(struct pci_dev *dev, int vector[])
@@ -335,13 +336,13 @@ static int pci_frontend_enable_msi(struct pci_dev *dev, int vector[])
if (likely(!err)) {
vector[0] = op.value;
if (op.value <= 0) {
- dev_warn(&dev->dev, "MSI entry is invalid: %d!\n",
+ pci_warn(dev, "MSI entry is invalid: %d!\n",
op.value);
err = -EINVAL;
vector[0] = -1;
}
} else {
- dev_err(&dev->dev, "pci frontend enable msi failed for dev "
+ pci_err(dev, "pci frontend enable msi failed for dev "
"%x:%x\n", op.bus, op.devfn);
err = -EINVAL;
}
@@ -560,7 +561,7 @@ static void free_root_bus_devs(struct pci_bus *bus)
while (!list_empty(&bus->devices)) {
dev = container_of(bus->devices.next, struct pci_dev,
bus_list);
- dev_dbg(&dev->dev, "removing device\n");
+ pci_dbg(dev, "removing device\n");
pci_stop_and_remove_bus_device(dev);
}
}
@@ -595,6 +596,7 @@ static pci_ers_result_t pcifront_common_process(int cmd,
struct pci_driver *pdrv;
int bus = pdev->sh_info->aer_op.bus;
int devfn = pdev->sh_info->aer_op.devfn;
+ int domain = pdev->sh_info->aer_op.domain;
struct pci_dev *pcidev;
int flag = 0;
@@ -603,7 +605,7 @@ static pci_ers_result_t pcifront_common_process(int cmd,
cmd, bus, devfn);
result = PCI_ERS_RESULT_NONE;
- pcidev = pci_get_bus_and_slot(bus, devfn);
+ pcidev = pci_get_domain_bus_and_slot(domain, bus, devfn);
if (!pcidev || !pcidev->driver) {
dev_err(&pdev->xdev->dev, "device or AER driver is NULL\n");
pci_dev_put(pcidev);
@@ -613,8 +615,7 @@ static pci_ers_result_t pcifront_common_process(int cmd,
if (pdrv) {
if (pdrv->err_handler && pdrv->err_handler->error_detected) {
- dev_dbg(&pcidev->dev,
- "trying to call AER service\n");
+ pci_dbg(pcidev, "trying to call AER service\n");
if (pcidev) {
flag = 1;
switch (cmd) {
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
index 93c50e377507..38f2cc2a6c74 100644
--- a/drivers/perf/arm_dsu_pmu.c
+++ b/drivers/perf/arm_dsu_pmu.c
@@ -658,10 +658,8 @@ static void dsu_pmu_probe_pmu(struct dsu_pmu *dsu_pmu)
return;
cpmceid[0] = __dsu_pmu_read_pmceid(0);
cpmceid[1] = __dsu_pmu_read_pmceid(1);
- bitmap_from_u32array(dsu_pmu->cpmceid_bitmap,
- DSU_PMU_MAX_COMMON_EVENTS,
- cpmceid,
- ARRAY_SIZE(cpmceid));
+ bitmap_from_arr32(dsu_pmu->cpmceid_bitmap, cpmceid,
+ DSU_PMU_MAX_COMMON_EVENTS);
}
static void dsu_pmu_set_active_cpu(int cpu, struct dsu_pmu *dsu_pmu)
diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index c11db8bceea1..d4c2e424a700 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -8,3 +8,5 @@ endif
source "drivers/platform/goldfish/Kconfig"
source "drivers/platform/chrome/Kconfig"
+
+source "drivers/platform/mellanox/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index d3a6630266a0..4b2ce58bcd9c 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -4,6 +4,7 @@
#
obj-$(CONFIG_X86) += x86/
+obj-$(CONFIG_MELLANOX_PLATFORM) += mellanox/
obj-$(CONFIG_MIPS) += mips/
obj-$(CONFIG_OLPC) += olpc/
obj-$(CONFIG_GOLDFISH) += goldfish/
diff --git a/drivers/platform/mellanox/Kconfig b/drivers/platform/mellanox/Kconfig
new file mode 100644
index 000000000000..591bccdeaff9
--- /dev/null
+++ b/drivers/platform/mellanox/Kconfig
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Platform support for Mellanox hardware
+#
+
+menuconfig MELLANOX_PLATFORM
+ bool "Platform support for Mellanox hardware"
+ depends on X86 || ARM || COMPILE_TEST
+ ---help---
+ Say Y here to get to see options for platform support for
+ Mellanox systems. This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
+
+if MELLANOX_PLATFORM
+
+config MLXREG_HOTPLUG
+ tristate "Mellanox platform hotplug driver support"
+ depends on REGMAP
+ depends on HWMON
+ depends on I2C
+ ---help---
+ This driver handles hot-plug events for the power suppliers, power
+ cables and fans on the wide range Mellanox IB and Ethernet systems.
+
+endif # MELLANOX_PLATFORM
diff --git a/drivers/platform/mellanox/Makefile b/drivers/platform/mellanox/Makefile
new file mode 100644
index 000000000000..7c8385e497a8
--- /dev/null
+++ b/drivers/platform/mellanox/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for linux/drivers/platform/mellanox
+# Mellanox Platform-Specific Drivers
+#
+obj-$(CONFIG_MLXREG_HOTPLUG) += mlxreg-hotplug.o
diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c
new file mode 100644
index 000000000000..0dfa1ca0d05b
--- /dev/null
+++ b/drivers/platform/mellanox/mlxreg-hotplug.c
@@ -0,0 +1,638 @@
+/*
+ * Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2016-2018 Vadim Pasternak <vadimp@mellanox.com>
+ *
+ * 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 names of the copyright holders 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") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_data/mlxreg.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/regmap.h>
+#include <linux/workqueue.h>
+
+/* Offset of event and mask registers from status register. */
+#define MLXREG_HOTPLUG_EVENT_OFF 1
+#define MLXREG_HOTPLUG_MASK_OFF 2
+#define MLXREG_HOTPLUG_AGGR_MASK_OFF 1
+
+/* ASIC health parameters. */
+#define MLXREG_HOTPLUG_HEALTH_MASK 0x02
+#define MLXREG_HOTPLUG_RST_CNTR 3
+
+#define MLXREG_HOTPLUG_ATTRS_MAX 24
+
+/**
+ * struct mlxreg_hotplug_priv_data - platform private data:
+ * @irq: platform device interrupt number;
+ * @pdev: platform device;
+ * @plat: platform data;
+ * @dwork: delayed work template;
+ * @lock: spin lock;
+ * @hwmon: hwmon device;
+ * @mlxreg_hotplug_attr: sysfs attributes array;
+ * @mlxreg_hotplug_dev_attr: sysfs sensor device attribute array;
+ * @group: sysfs attribute group;
+ * @groups: list of sysfs attribute group for hwmon registration;
+ * @cell: location of top aggregation interrupt register;
+ * @mask: top aggregation interrupt common mask;
+ * @aggr_cache: last value of aggregation register status;
+ */
+struct mlxreg_hotplug_priv_data {
+ int irq;
+ struct device *dev;
+ struct platform_device *pdev;
+ struct mlxreg_hotplug_platform_data *plat;
+ struct regmap *regmap;
+ struct delayed_work dwork_irq;
+ struct delayed_work dwork;
+ spinlock_t lock; /* sync with interrupt */
+ struct device *hwmon;
+ struct attribute *mlxreg_hotplug_attr[MLXREG_HOTPLUG_ATTRS_MAX + 1];
+ struct sensor_device_attribute_2
+ mlxreg_hotplug_dev_attr[MLXREG_HOTPLUG_ATTRS_MAX];
+ struct attribute_group group;
+ const struct attribute_group *groups[2];
+ u32 cell;
+ u32 mask;
+ u32 aggr_cache;
+ bool after_probe;
+};
+
+static int mlxreg_hotplug_device_create(struct device *dev,
+ struct mlxreg_core_data *data)
+{
+ /*
+ * Return if adapter number is negative. It could be in case hotplug
+ * event is not associated with hotplug device.
+ */
+ if (data->hpdev.nr < 0)
+ return 0;
+
+ data->hpdev.adapter = i2c_get_adapter(data->hpdev.nr);
+ if (!data->hpdev.adapter) {
+ dev_err(dev, "Failed to get adapter for bus %d\n",
+ data->hpdev.nr);
+ return -EFAULT;
+ }
+
+ data->hpdev.client = i2c_new_device(data->hpdev.adapter,
+ data->hpdev.brdinfo);
+ if (!data->hpdev.client) {
+ dev_err(dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
+ data->hpdev.brdinfo->type, data->hpdev.nr,
+ data->hpdev.brdinfo->addr);
+
+ i2c_put_adapter(data->hpdev.adapter);
+ data->hpdev.adapter = NULL;
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static void mlxreg_hotplug_device_destroy(struct mlxreg_core_data *data)
+{
+ if (data->hpdev.client) {
+ i2c_unregister_device(data->hpdev.client);
+ data->hpdev.client = NULL;
+ }
+
+ if (data->hpdev.adapter) {
+ i2c_put_adapter(data->hpdev.adapter);
+ data->hpdev.adapter = NULL;
+ }
+}
+
+static ssize_t mlxreg_hotplug_attr_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct mlxreg_hotplug_priv_data *priv = dev_get_drvdata(dev);
+ struct mlxreg_core_hotplug_platform_data *pdata;
+ int index = to_sensor_dev_attr_2(attr)->index;
+ int nr = to_sensor_dev_attr_2(attr)->nr;
+ struct mlxreg_core_item *item;
+ struct mlxreg_core_data *data;
+ u32 regval;
+ int ret;
+
+ pdata = dev_get_platdata(&priv->pdev->dev);
+ item = pdata->items + nr;
+ data = item->data + index;
+
+ ret = regmap_read(priv->regmap, data->reg, &regval);
+ if (ret)
+ return ret;
+
+ if (item->health) {
+ regval &= data->mask;
+ } else {
+ /* Bit = 0 : functional if item->inversed is true. */
+ if (item->inversed)
+ regval = !(regval & data->mask);
+ else
+ regval = !!(regval & data->mask);
+ }
+
+ return sprintf(buf, "%u\n", regval);
+}
+
+#define PRIV_ATTR(i) priv->mlxreg_hotplug_attr[i]
+#define PRIV_DEV_ATTR(i) priv->mlxreg_hotplug_dev_attr[i]
+
+static int mlxreg_hotplug_attr_init(struct mlxreg_hotplug_priv_data *priv)
+{
+ struct mlxreg_core_hotplug_platform_data *pdata;
+ struct mlxreg_core_item *item;
+ struct mlxreg_core_data *data;
+ int num_attrs = 0, id = 0, i, j;
+
+ pdata = dev_get_platdata(&priv->pdev->dev);
+ item = pdata->items;
+
+ /* Go over all kinds of items - psu, pwr, fan. */
+ for (i = 0; i < pdata->counter; i++, item++) {
+ num_attrs += item->count;
+ data = item->data;
+ /* Go over all units within the item. */
+ for (j = 0; j < item->count; j++, data++, id++) {
+ PRIV_ATTR(id) = &PRIV_DEV_ATTR(id).dev_attr.attr;
+ PRIV_ATTR(id)->name = devm_kasprintf(&priv->pdev->dev,
+ GFP_KERNEL,
+ data->label);
+
+ if (!PRIV_ATTR(id)->name) {
+ dev_err(priv->dev, "Memory allocation failed for attr %d.\n",
+ id);
+ return -ENOMEM;
+ }
+
+ PRIV_DEV_ATTR(id).dev_attr.attr.name =
+ PRIV_ATTR(id)->name;
+ PRIV_DEV_ATTR(id).dev_attr.attr.mode = 0444;
+ PRIV_DEV_ATTR(id).dev_attr.show =
+ mlxreg_hotplug_attr_show;
+ PRIV_DEV_ATTR(id).nr = i;
+ PRIV_DEV_ATTR(id).index = j;
+ sysfs_attr_init(&PRIV_DEV_ATTR(id).dev_attr.attr);
+ }
+ }
+
+ priv->group.attrs = devm_kzalloc(&priv->pdev->dev, num_attrs *
+ sizeof(struct attribute *),
+ GFP_KERNEL);
+ if (!priv->group.attrs)
+ return -ENOMEM;
+
+ priv->group.attrs = priv->mlxreg_hotplug_attr;
+ priv->groups[0] = &priv->group;
+ priv->groups[1] = NULL;
+
+ return 0;
+}
+
+static void
+mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
+ struct mlxreg_core_item *item)
+{
+ struct mlxreg_core_data *data;
+ u32 asserted, regval, bit;
+ int ret;
+
+ /*
+ * Validate if item related to received signal type is valid.
+ * It should never happen, excepted the situation when some
+ * piece of hardware is broken. In such situation just produce
+ * error message and return. Caller must continue to handle the
+ * signals from other devices if any.
+ */
+ if (unlikely(!item)) {
+ dev_err(priv->dev, "False signal: at offset:mask 0x%02x:0x%02x.\n",
+ item->reg, item->mask);
+
+ return;
+ }
+
+ /* Mask event. */
+ ret = regmap_write(priv->regmap, item->reg + MLXREG_HOTPLUG_MASK_OFF,
+ 0);
+ if (ret)
+ goto out;
+
+ /* Read status. */
+ ret = regmap_read(priv->regmap, item->reg, &regval);
+ if (ret)
+ goto out;
+
+ /* Set asserted bits and save last status. */
+ regval &= item->mask;
+ asserted = item->cache ^ regval;
+ item->cache = regval;
+
+ for_each_set_bit(bit, (unsigned long *)&asserted, 8) {
+ data = item->data + bit;
+ if (regval & BIT(bit)) {
+ if (item->inversed)
+ mlxreg_hotplug_device_destroy(data);
+ else
+ mlxreg_hotplug_device_create(priv->dev, data);
+ } else {
+ if (item->inversed)
+ mlxreg_hotplug_device_create(priv->dev, data);
+ else
+ mlxreg_hotplug_device_destroy(data);
+ }
+ }
+
+ /* Acknowledge event. */
+ ret = regmap_write(priv->regmap, item->reg + MLXREG_HOTPLUG_EVENT_OFF,
+ 0);
+ if (ret)
+ goto out;
+
+ /* Unmask event. */
+ ret = regmap_write(priv->regmap, item->reg + MLXREG_HOTPLUG_MASK_OFF,
+ item->mask);
+
+ out:
+ if (ret)
+ dev_err(priv->dev, "Failed to complete workqueue.\n");
+}
+
+static void
+mlxreg_hotplug_health_work_helper(struct mlxreg_hotplug_priv_data *priv,
+ struct mlxreg_core_item *item)
+{
+ struct mlxreg_core_data *data = item->data;
+ u32 regval;
+ int i, ret;
+
+ for (i = 0; i < item->count; i++, data++) {
+ /* Mask event. */
+ ret = regmap_write(priv->regmap, data->reg +
+ MLXREG_HOTPLUG_MASK_OFF, 0);
+ if (ret)
+ goto out;
+
+ /* Read status. */
+ ret = regmap_read(priv->regmap, data->reg, &regval);
+ if (ret)
+ goto out;
+
+ regval &= data->mask;
+ item->cache = regval;
+ if (regval == MLXREG_HOTPLUG_HEALTH_MASK) {
+ if ((data->health_cntr++ == MLXREG_HOTPLUG_RST_CNTR) ||
+ !priv->after_probe) {
+ mlxreg_hotplug_device_create(priv->dev, data);
+ data->attached = true;
+ }
+ } else {
+ if (data->attached) {
+ mlxreg_hotplug_device_destroy(data);
+ data->attached = false;
+ data->health_cntr = 0;
+ }
+ }
+
+ /* Acknowledge event. */
+ ret = regmap_write(priv->regmap, data->reg +
+ MLXREG_HOTPLUG_EVENT_OFF, 0);
+ if (ret)
+ goto out;
+
+ /* Unmask event. */
+ ret = regmap_write(priv->regmap, data->reg +
+ MLXREG_HOTPLUG_MASK_OFF, data->mask);
+ if (ret)
+ goto out;
+ }
+
+ out:
+ if (ret)
+ dev_err(priv->dev, "Failed to complete workqueue.\n");
+}
+
+/*
+ * mlxreg_hotplug_work_handler - performs traversing of device interrupt
+ * registers according to the below hierarchy schema:
+ *
+ * Aggregation registers (status/mask)
+ * PSU registers: *---*
+ * *-----------------* | |
+ * |status/event/mask|-----> | * |
+ * *-----------------* | |
+ * Power registers: | |
+ * *-----------------* | |
+ * |status/event/mask|-----> | * |
+ * *-----------------* | |
+ * FAN registers: | |--> CPU
+ * *-----------------* | |
+ * |status/event/mask|-----> | * |
+ * *-----------------* | |
+ * ASIC registers: | |
+ * *-----------------* | |
+ * |status/event/mask|-----> | * |
+ * *-----------------* | |
+ * *---*
+ *
+ * In case some system changed are detected: FAN in/out, PSU in/out, power
+ * cable attached/detached, ASIC health good/bad, relevant device is created
+ * or destroyed.
+ */
+static void mlxreg_hotplug_work_handler(struct work_struct *work)
+{
+ struct mlxreg_core_hotplug_platform_data *pdata;
+ struct mlxreg_hotplug_priv_data *priv;
+ struct mlxreg_core_item *item;
+ u32 regval, aggr_asserted;
+ unsigned long flags;
+ int i, ret;
+
+ priv = container_of(work, struct mlxreg_hotplug_priv_data,
+ dwork_irq.work);
+ pdata = dev_get_platdata(&priv->pdev->dev);
+ item = pdata->items;
+
+ /* Mask aggregation event. */
+ ret = regmap_write(priv->regmap, pdata->cell +
+ MLXREG_HOTPLUG_AGGR_MASK_OFF, 0);
+ if (ret < 0)
+ goto out;
+
+ /* Read aggregation status. */
+ ret = regmap_read(priv->regmap, pdata->cell, &regval);
+ if (ret)
+ goto out;
+
+ regval &= pdata->mask;
+ aggr_asserted = priv->aggr_cache ^ regval;
+ priv->aggr_cache = regval;
+
+ /* Handle topology and health configuration changes. */
+ for (i = 0; i < pdata->counter; i++, item++) {
+ if (aggr_asserted & item->aggr_mask) {
+ if (item->health)
+ mlxreg_hotplug_health_work_helper(priv, item);
+ else
+ mlxreg_hotplug_work_helper(priv, item);
+ }
+ }
+
+ if (aggr_asserted) {
+ spin_lock_irqsave(&priv->lock, flags);
+
+ /*
+ * It is possible, that some signals have been inserted, while
+ * interrupt has been masked by mlxreg_hotplug_work_handler.
+ * In this case such signals will be missed. In order to handle
+ * these signals delayed work is canceled and work task
+ * re-scheduled for immediate execution. It allows to handle
+ * missed signals, if any. In other case work handler just
+ * validates that no new signals have been received during
+ * masking.
+ */
+ cancel_delayed_work(&priv->dwork_irq);
+ schedule_delayed_work(&priv->dwork_irq, 0);
+
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return;
+ }
+
+ /* Unmask aggregation event (no need acknowledge). */
+ ret = regmap_write(priv->regmap, pdata->cell +
+ MLXREG_HOTPLUG_AGGR_MASK_OFF, pdata->mask);
+
+ out:
+ if (ret)
+ dev_err(priv->dev, "Failed to complete workqueue.\n");
+}
+
+static int mlxreg_hotplug_set_irq(struct mlxreg_hotplug_priv_data *priv)
+{
+ struct mlxreg_core_hotplug_platform_data *pdata;
+ struct mlxreg_core_item *item;
+ int i, ret;
+
+ pdata = dev_get_platdata(&priv->pdev->dev);
+ item = pdata->items;
+
+ for (i = 0; i < pdata->counter; i++, item++) {
+ /* Clear group presense event. */
+ ret = regmap_write(priv->regmap, item->reg +
+ MLXREG_HOTPLUG_EVENT_OFF, 0);
+ if (ret)
+ goto out;
+
+ /* Set group initial status as mask and unmask group event. */
+ if (item->inversed) {
+ item->cache = item->mask;
+ ret = regmap_write(priv->regmap, item->reg +
+ MLXREG_HOTPLUG_MASK_OFF,
+ item->mask);
+ if (ret)
+ goto out;
+ }
+ }
+
+ /* Keep aggregation initial status as zero and unmask events. */
+ ret = regmap_write(priv->regmap, pdata->cell +
+ MLXREG_HOTPLUG_AGGR_MASK_OFF, pdata->mask);
+ if (ret)
+ goto out;
+
+ /* Keep low aggregation initial status as zero and unmask events. */
+ if (pdata->cell_low) {
+ ret = regmap_write(priv->regmap, pdata->cell_low +
+ MLXREG_HOTPLUG_AGGR_MASK_OFF,
+ pdata->mask_low);
+ if (ret)
+ goto out;
+ }
+
+ /* Invoke work handler for initializing hot plug devices setting. */
+ mlxreg_hotplug_work_handler(&priv->dwork_irq.work);
+
+ out:
+ if (ret)
+ dev_err(priv->dev, "Failed to set interrupts.\n");
+ enable_irq(priv->irq);
+ return ret;
+}
+
+static void mlxreg_hotplug_unset_irq(struct mlxreg_hotplug_priv_data *priv)
+{
+ struct mlxreg_core_hotplug_platform_data *pdata;
+ struct mlxreg_core_item *item;
+ struct mlxreg_core_data *data;
+ int count, i, j;
+
+ pdata = dev_get_platdata(&priv->pdev->dev);
+ item = pdata->items;
+ disable_irq(priv->irq);
+ cancel_delayed_work_sync(&priv->dwork_irq);
+
+ /* Mask low aggregation event, if defined. */
+ if (pdata->cell_low)
+ regmap_write(priv->regmap, pdata->cell_low +
+ MLXREG_HOTPLUG_AGGR_MASK_OFF, 0);
+
+ /* Mask aggregation event. */
+ regmap_write(priv->regmap, pdata->cell + MLXREG_HOTPLUG_AGGR_MASK_OFF,
+ 0);
+
+ /* Clear topology configurations. */
+ for (i = 0; i < pdata->counter; i++, item++) {
+ data = item->data;
+ /* Mask group presense event. */
+ regmap_write(priv->regmap, data->reg + MLXREG_HOTPLUG_MASK_OFF,
+ 0);
+ /* Clear group presense event. */
+ regmap_write(priv->regmap, data->reg +
+ MLXREG_HOTPLUG_EVENT_OFF, 0);
+
+ /* Remove all the attached devices in group. */
+ count = item->count;
+ for (j = 0; j < count; j++, data++)
+ mlxreg_hotplug_device_destroy(data);
+ }
+}
+
+static irqreturn_t mlxreg_hotplug_irq_handler(int irq, void *dev)
+{
+ struct mlxreg_hotplug_priv_data *priv;
+
+ priv = (struct mlxreg_hotplug_priv_data *)dev;
+
+ /* Schedule work task for immediate execution.*/
+ schedule_delayed_work(&priv->dwork_irq, 0);
+
+ return IRQ_HANDLED;
+}
+
+static int mlxreg_hotplug_probe(struct platform_device *pdev)
+{
+ struct mlxreg_core_hotplug_platform_data *pdata;
+ struct mlxreg_hotplug_priv_data *priv;
+ int err;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata) {
+ dev_err(&pdev->dev, "Failed to get platform data.\n");
+ return -EINVAL;
+ }
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ if (pdata->irq) {
+ priv->irq = pdata->irq;
+ } else {
+ priv->irq = platform_get_irq(pdev, 0);
+ if (priv->irq < 0) {
+ dev_err(&pdev->dev, "Failed to get platform irq: %d\n",
+ priv->irq);
+ return priv->irq;
+ }
+ }
+
+ priv->regmap = pdata->regmap;
+ priv->dev = pdev->dev.parent;
+ priv->pdev = pdev;
+
+ err = devm_request_irq(&pdev->dev, priv->irq,
+ mlxreg_hotplug_irq_handler, IRQF_TRIGGER_FALLING
+ | IRQF_SHARED, "mlxreg-hotplug", priv);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to request irq: %d\n", err);
+ return err;
+ }
+
+ disable_irq(priv->irq);
+ spin_lock_init(&priv->lock);
+ INIT_DELAYED_WORK(&priv->dwork_irq, mlxreg_hotplug_work_handler);
+ /* Perform initial interrupts setup. */
+ mlxreg_hotplug_set_irq(priv);
+
+ priv->after_probe = true;
+ dev_set_drvdata(&pdev->dev, priv);
+
+ err = mlxreg_hotplug_attr_init(priv);
+ if (err) {
+ dev_err(&pdev->dev, "Failed to allocate attributes: %d\n",
+ err);
+ return err;
+ }
+
+ priv->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
+ "mlxreg_hotplug", priv, priv->groups);
+ if (IS_ERR(priv->hwmon)) {
+ dev_err(&pdev->dev, "Failed to register hwmon device %ld\n",
+ PTR_ERR(priv->hwmon));
+ return PTR_ERR(priv->hwmon);
+ }
+
+ return 0;
+}
+
+static int mlxreg_hotplug_remove(struct platform_device *pdev)
+{
+ struct mlxreg_hotplug_priv_data *priv = dev_get_drvdata(&pdev->dev);
+
+ /* Clean interrupts setup. */
+ mlxreg_hotplug_unset_irq(priv);
+
+ return 0;
+}
+
+static struct platform_driver mlxreg_hotplug_driver = {
+ .driver = {
+ .name = "mlxreg-hotplug",
+ },
+ .probe = mlxreg_hotplug_probe,
+ .remove = mlxreg_hotplug_remove,
+};
+
+module_platform_driver(mlxreg_hotplug_driver);
+
+MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
+MODULE_DESCRIPTION("Mellanox regmap hotplug platform driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_ALIAS("platform:mlxreg-hotplug");
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 2c745e8ccad6..9a8f96465cdc 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -36,6 +36,20 @@ config ACER_WMI
If you have an ACPI-WMI compatible Acer/ Wistron laptop, say Y or M
here.
+config ACER_WIRELESS
+ tristate "Acer Wireless Radio Control Driver"
+ depends on ACPI
+ depends on INPUT
+ ---help---
+ The Acer Wireless Radio Control handles the airplane mode hotkey
+ present on new Acer laptops.
+
+ Say Y or M here if you have an Acer notebook with an airplane mode
+ hotkey.
+
+ If you choose to compile this driver as a module the module will be
+ called acer-wireless.
+
config ACERHDF
tristate "Acer Aspire One temperature and fan driver"
depends on ACPI && THERMAL
@@ -244,6 +258,18 @@ config AMILO_RFKILL
This is a driver for enabling wifi on some Fujitsu-Siemens Amilo
laptops.
+config GPD_POCKET_FAN
+ tristate "GPD Pocket Fan Controller support"
+ depends on ACPI
+ depends on THERMAL
+ ---help---
+ Driver for the GPD Pocket vendor specific FAN02501 ACPI device
+ which controls the fan speed on the GPD Pocket.
+
+ Without this driver the fan on the Pocket will stay off independent
+ of the CPU temperature. Say Y or M if the kernel may be used on a
+ GPD pocket.
+
config TC1100_WMI
tristate "HP Compaq TC1100 Tablet WMI Extras"
depends on !X86_64
@@ -812,9 +838,8 @@ config TOSHIBA_WMI
config ACPI_CMPC
tristate "CMPC Laptop Extras"
- depends on ACPI
+ depends on ACPI && INPUT
depends on RFKILL || RFKILL=n
- select INPUT
select BACKLIGHT_CLASS_DEVICE
help
Support for Intel Classmate PC ACPI devices, including some
@@ -949,7 +974,7 @@ config INTEL_IMR
If you are running on a Galileo/Quark say Y here.
config INTEL_PMC_CORE
- bool "Intel PMC Core driver"
+ tristate "Intel PMC Core driver"
depends on PCI
---help---
The Intel Platform Controller Hub for Intel Core SoCs provides access
@@ -958,7 +983,10 @@ config INTEL_PMC_CORE
exposed by the Power Management Controller.
Supported features:
- - SLP_S0_RESIDENCY counter.
+ - SLP_S0_RESIDENCY counter
+ - PCH IP Power Gating status
+ - LTR Ignore
+ - MPHY/PLL gating status (Sunrisepoint PCH only)
config IBM_RTL
tristate "Device driver to enable PRTL support"
@@ -1131,7 +1159,6 @@ config INTEL_TELEMETRY
config MLX_PLATFORM
tristate "Mellanox Technologies platform support"
- depends on X86_64
---help---
This option enables system support for the Mellanox Technologies
platform. The Mellanox systems provide data center networking
@@ -1141,14 +1168,6 @@ config MLX_PLATFORM
If you have a Mellanox system, say Y or M here.
-config MLX_CPLD_PLATFORM
- tristate "Mellanox platform hotplug driver support"
- select HWMON
- select I2C
- ---help---
- This driver handles hot-plug events for the power suppliers, power
- cables and fans on the wide range Mellanox IB and Ethernet systems.
-
config INTEL_TURBO_MAX_3
bool "Intel Turbo Boost Max Technology 3.0 enumeration driver"
depends on X86_64 && SCHED_MC_PRIO
@@ -1170,6 +1189,17 @@ config SILEAD_DMI
with the OS-image for the device. This option supplies the missing
information. Enable this for x86 tablets with Silead touchscreens.
+config INTEL_CHTDC_TI_PWRBTN
+ tristate "Intel Cherry Trail Dollar Cove TI power button driver"
+ depends on INTEL_SOC_PMIC_CHTDC_TI
+ depends on INPUT
+ ---help---
+ This option adds a power button driver driver for Dollar Cove TI
+ PMIC on Intel Cherry Trail devices.
+
+ To compile this driver as a module, choose M here: the module
+ will be called intel_chtdc_ti_pwrbtn.
+
endif # X86_PLATFORM_DEVICES
config PMC_ATOM
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index c32b34a72467..c388608ad2a3 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -23,11 +23,13 @@ obj-$(CONFIG_DELL_WMI_LED) += dell-wmi-led.o
obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o
obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
+obj-$(CONFIG_ACER_WIRELESS) += acer-wireless.o
obj-$(CONFIG_ACERHDF) += acerhdf.o
obj-$(CONFIG_HP_ACCEL) += hp_accel.o
obj-$(CONFIG_HP_WIRELESS) += hp-wireless.o
obj-$(CONFIG_HP_WMI) += hp-wmi.o
obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o
+obj-$(CONFIG_GPD_POCKET_FAN) += gpd-pocket-fan.o
obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
obj-$(CONFIG_IDEAPAD_LAPTOP) += ideapad-laptop.o
@@ -86,5 +88,5 @@ obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o
obj-$(CONFIG_PMC_ATOM) += pmc_atom.o
obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
-obj-$(CONFIG_MLX_CPLD_PLATFORM) += mlxcpld-hotplug.o
obj-$(CONFIG_INTEL_TURBO_MAX_3) += intel_turbo_max_3.o
+obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o
diff --git a/drivers/platform/x86/acer-wireless.c b/drivers/platform/x86/acer-wireless.c
new file mode 100644
index 000000000000..858037987b33
--- /dev/null
+++ b/drivers/platform/x86/acer-wireless.c
@@ -0,0 +1,71 @@
+/*
+ * Acer Wireless Radio Control Driver
+ *
+ * Copyright (C) 2017 Endless Mobile, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci_ids.h>
+#include <linux/types.h>
+
+static const struct acpi_device_id acer_wireless_acpi_ids[] = {
+ {"10251229", 0},
+ {"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, acer_wireless_acpi_ids);
+
+static void acer_wireless_notify(struct acpi_device *adev, u32 event)
+{
+ struct input_dev *idev = acpi_driver_data(adev);
+
+ dev_dbg(&adev->dev, "event=%#x\n", event);
+ if (event != 0x80) {
+ dev_notice(&adev->dev, "Unknown SMKB event: %#x\n", event);
+ return;
+ }
+ input_report_key(idev, KEY_RFKILL, 1);
+ input_report_key(idev, KEY_RFKILL, 0);
+ input_sync(idev);
+}
+
+static int acer_wireless_add(struct acpi_device *adev)
+{
+ struct input_dev *idev;
+
+ idev = devm_input_allocate_device(&adev->dev);
+ if (!idev)
+ return -ENOMEM;
+
+ adev->driver_data = idev;
+ idev->name = "Acer Wireless Radio Control";
+ idev->phys = "acer-wireless/input0";
+ idev->id.bustype = BUS_HOST;
+ idev->id.vendor = PCI_VENDOR_ID_AI;
+ idev->id.product = 0x1229;
+ set_bit(EV_KEY, idev->evbit);
+ set_bit(KEY_RFKILL, idev->keybit);
+
+ return input_register_device(idev);
+}
+
+static struct acpi_driver acer_wireless_driver = {
+ .name = "Acer Wireless Radio Control Driver",
+ .class = "hotkey",
+ .ids = acer_wireless_acpi_ids,
+ .ops = {
+ .add = acer_wireless_add,
+ .notify = acer_wireless_notify,
+ },
+};
+module_acpi_driver(acer_wireless_driver);
+
+MODULE_DESCRIPTION("Acer Wireless Radio Control Driver");
+MODULE_AUTHOR("Chris Chiu <chiu@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/alienware-wmi.c b/drivers/platform/x86/alienware-wmi.c
index 4eb8e1a472b2..9d7dbd925065 100644
--- a/drivers/platform/x86/alienware-wmi.c
+++ b/drivers/platform/x86/alienware-wmi.c
@@ -68,6 +68,14 @@ struct quirk_entry {
static struct quirk_entry *quirks;
+
+static struct quirk_entry quirk_inspiron5675 = {
+ .num_zones = 2,
+ .hdmi_mux = 0,
+ .amplifier = 0,
+ .deepslp = 0,
+};
+
static struct quirk_entry quirk_unknown = {
.num_zones = 2,
.hdmi_mux = 0,
@@ -171,6 +179,15 @@ static const struct dmi_system_id alienware_quirks[] __initconst = {
},
.driver_data = &quirk_asm201,
},
+ {
+ .callback = dmi_matched,
+ .ident = "Dell Inc. Inspiron 5675",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5675"),
+ },
+ .driver_data = &quirk_inspiron5675,
+ },
{}
};
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c
index 623d322447a2..7c4eb86c851e 100644
--- a/drivers/platform/x86/apple-gmux.c
+++ b/drivers/platform/x86/apple-gmux.c
@@ -24,7 +24,6 @@
#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/vga_switcheroo.h>
-#include <linux/vgaarb.h>
#include <acpi/video.h>
#include <asm/io.h>
@@ -54,7 +53,6 @@ struct apple_gmux_data {
bool indexed;
struct mutex index_lock;
- struct pci_dev *pdev;
struct backlight_device *bdev;
/* switcheroo data */
@@ -599,23 +597,6 @@ static int gmux_resume(struct device *dev)
return 0;
}
-static struct pci_dev *gmux_get_io_pdev(void)
-{
- struct pci_dev *pdev = NULL;
-
- while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev))) {
- u16 cmd;
-
- pci_read_config_word(pdev, PCI_COMMAND, &cmd);
- if (!(cmd & PCI_COMMAND_IO))
- continue;
-
- return pdev;
- }
-
- return NULL;
-}
-
static int is_thunderbolt(struct device *dev, void *data)
{
return to_pci_dev(dev)->is_thunderbolt;
@@ -631,7 +612,6 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
int ret = -ENXIO;
acpi_status status;
unsigned long long gpe;
- struct pci_dev *pdev = NULL;
if (apple_gmux_data)
return -EBUSY;
@@ -682,7 +662,7 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
ver_minor = (version >> 16) & 0xff;
ver_release = (version >> 8) & 0xff;
} else {
- pr_info("gmux device not present or IO disabled\n");
+ pr_info("gmux device not present\n");
ret = -ENODEV;
goto err_release;
}
@@ -690,23 +670,6 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor,
ver_release, (gmux_data->indexed ? "indexed" : "classic"));
- /*
- * Apple systems with gmux are EFI based and normally don't use
- * VGA. In addition changing IO+MEM ownership between IGP and dGPU
- * disables IO/MEM used for backlight control on some systems.
- * Lock IO+MEM to GPU with active IO to prevent switch.
- */
- pdev = gmux_get_io_pdev();
- if (pdev && vga_tryget(pdev,
- VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM)) {
- pr_err("IO+MEM vgaarb-locking for PCI:%s failed\n",
- pci_name(pdev));
- ret = -EBUSY;
- goto err_release;
- } else if (pdev)
- pr_info("locked IO for PCI:%s\n", pci_name(pdev));
- gmux_data->pdev = pdev;
-
memset(&props, 0, sizeof(props));
props.type = BACKLIGHT_PLATFORM;
props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS);
@@ -822,10 +785,6 @@ err_enable_gpe:
err_notify:
backlight_device_unregister(bdev);
err_release:
- if (gmux_data->pdev)
- vga_put(gmux_data->pdev,
- VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM);
- pci_dev_put(pdev);
release_region(gmux_data->iostart, gmux_data->iolen);
err_free:
kfree(gmux_data);
@@ -845,11 +804,6 @@ static void gmux_remove(struct pnp_dev *pnp)
&gmux_notify_handler);
}
- if (gmux_data->pdev) {
- vga_put(gmux_data->pdev,
- VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM);
- pci_dev_put(gmux_data->pdev);
- }
backlight_device_unregister(gmux_data->bdev);
release_region(gmux_data->iostart, gmux_data->iolen);
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
index 5269a01d9bdd..136ff2b4cce5 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -111,7 +111,7 @@ static struct quirk_entry quirk_asus_x550lb = {
.xusb2pr = 0x01D9,
};
-static struct quirk_entry quirk_asus_ux330uak = {
+static struct quirk_entry quirk_asus_forceals = {
.wmi_force_als_set = true,
};
@@ -387,7 +387,7 @@ static const struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "UX330UAK"),
},
- .driver_data = &quirk_asus_ux330uak,
+ .driver_data = &quirk_asus_forceals,
},
{
.callback = dmi_matched,
@@ -398,6 +398,15 @@ static const struct dmi_system_id asus_quirks[] = {
},
.driver_data = &quirk_asus_x550lb,
},
+ {
+ .callback = dmi_matched,
+ .ident = "ASUSTeK COMPUTER INC. UX430UQ",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "UX430UQ"),
+ },
+ .driver_data = &quirk_asus_forceals,
+ },
{},
};
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index cd4725e7e0b5..2a68f59d2228 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -36,10 +36,10 @@
#include "dell-smbios.h"
struct quirk_entry {
- u8 touchpad_led;
- u8 kbd_led_levels_off_1;
+ bool touchpad_led;
+ bool kbd_led_levels_off_1;
- int needs_kbd_timeouts;
+ bool needs_kbd_timeouts;
/*
* Ordered list of timeouts expressed in seconds.
* The list must end with -1
@@ -50,7 +50,7 @@ struct quirk_entry {
static struct quirk_entry *quirks;
static struct quirk_entry quirk_dell_vostro_v130 = {
- .touchpad_led = 1,
+ .touchpad_led = true,
};
static int __init dmi_matched(const struct dmi_system_id *dmi)
@@ -64,12 +64,12 @@ static int __init dmi_matched(const struct dmi_system_id *dmi)
* is used then BIOS silently set timeout to 0 without any error message.
*/
static struct quirk_entry quirk_dell_xps13_9333 = {
- .needs_kbd_timeouts = 1,
+ .needs_kbd_timeouts = true,
.kbd_timeouts = { 0, 5, 15, 60, 5 * 60, 15 * 60, -1 },
};
static struct quirk_entry quirk_dell_latitude_e6410 = {
- .kbd_led_levels_off_1 = 1,
+ .kbd_led_levels_off_1 = true,
};
static struct platform_driver platform_driver = {
@@ -78,7 +78,6 @@ static struct platform_driver platform_driver = {
}
};
-static struct calling_interface_buffer *buffer;
static struct platform_device *platform_device;
static struct backlight_device *dell_backlight_device;
static struct rfkill *wifi_rfkill;
@@ -110,6 +109,42 @@ static const struct dmi_system_id dell_device_table[] __initconst = {
},
},
{
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_CHASSIS_TYPE, "30"), /*Tablet*/
+ },
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /*Convertible*/
+ },
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_CHASSIS_TYPE, "32"), /*Detachable*/
+ },
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_CHASSIS_TYPE, "30"), /*Tablet*/
+ },
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /*Convertible*/
+ },
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_CHASSIS_TYPE, "32"), /*Detachable*/
+ },
+ },
+ {
.ident = "Dell Computer Corporation",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
@@ -286,7 +321,8 @@ static const struct dmi_system_id dell_quirks[] __initconst = {
{ }
};
-void dell_set_arguments(u32 arg0, u32 arg1, u32 arg2, u32 arg3)
+static void dell_fill_request(struct calling_interface_buffer *buffer,
+ u32 arg0, u32 arg1, u32 arg2, u32 arg3)
{
memset(buffer, 0, sizeof(struct calling_interface_buffer));
buffer->input[0] = arg0;
@@ -295,7 +331,8 @@ void dell_set_arguments(u32 arg0, u32 arg1, u32 arg2, u32 arg3)
buffer->input[3] = arg3;
}
-int dell_send_request(u16 class, u16 select)
+static int dell_send_request(struct calling_interface_buffer *buffer,
+ u16 class, u16 select)
{
int ret;
@@ -432,21 +469,22 @@ static int dell_rfkill_set(void *data, bool blocked)
int disable = blocked ? 1 : 0;
unsigned long radio = (unsigned long)data;
int hwswitch_bit = (unsigned long)data - 1;
+ struct calling_interface_buffer buffer;
int hwswitch;
int status;
int ret;
- dell_set_arguments(0, 0, 0, 0);
- ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+ dell_fill_request(&buffer, 0, 0, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
if (ret)
return ret;
- status = buffer->output[1];
+ status = buffer.output[1];
- dell_set_arguments(0x2, 0, 0, 0);
- ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+ dell_fill_request(&buffer, 0x2, 0, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
if (ret)
return ret;
- hwswitch = buffer->output[1];
+ hwswitch = buffer.output[1];
/* If the hardware switch controls this radio, and the hardware
switch is disabled, always disable the radio */
@@ -454,8 +492,8 @@ static int dell_rfkill_set(void *data, bool blocked)
(status & BIT(0)) && !(status & BIT(16)))
disable = 1;
- dell_set_arguments(1 | (radio<<8) | (disable << 16), 0, 0, 0);
- ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+ dell_fill_request(&buffer, 1 | (radio<<8) | (disable << 16), 0, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
return ret;
}
@@ -464,9 +502,11 @@ static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio,
{
if (status & BIT(0)) {
/* Has hw-switch, sync sw_state to BIOS */
+ struct calling_interface_buffer buffer;
int block = rfkill_blocked(rfkill);
- dell_set_arguments(1 | (radio << 8) | (block << 16), 0, 0, 0);
- dell_send_request(CLASS_INFO, SELECT_RFKILL);
+ dell_fill_request(&buffer,
+ 1 | (radio << 8) | (block << 16), 0, 0, 0);
+ dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
} else {
/* No hw-switch, sync BIOS state to sw_state */
rfkill_set_sw_state(rfkill, !!(status & BIT(radio + 16)));
@@ -483,21 +523,22 @@ static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio,
static void dell_rfkill_query(struct rfkill *rfkill, void *data)
{
int radio = ((unsigned long)data & 0xF);
+ struct calling_interface_buffer buffer;
int hwswitch;
int status;
int ret;
- dell_set_arguments(0, 0, 0, 0);
- ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
- status = buffer->output[1];
+ dell_fill_request(&buffer, 0, 0, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
+ status = buffer.output[1];
if (ret != 0 || !(status & BIT(0))) {
return;
}
- dell_set_arguments(0, 0x2, 0, 0);
- ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
- hwswitch = buffer->output[1];
+ dell_fill_request(&buffer, 0, 0x2, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
+ hwswitch = buffer.output[1];
if (ret != 0)
return;
@@ -514,22 +555,23 @@ static struct dentry *dell_laptop_dir;
static int dell_debugfs_show(struct seq_file *s, void *data)
{
+ struct calling_interface_buffer buffer;
int hwswitch_state;
int hwswitch_ret;
int status;
int ret;
- dell_set_arguments(0, 0, 0, 0);
- ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+ dell_fill_request(&buffer, 0, 0, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
if (ret)
return ret;
- status = buffer->output[1];
+ status = buffer.output[1];
- dell_set_arguments(0, 0x2, 0, 0);
- hwswitch_ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+ dell_fill_request(&buffer, 0, 0x2, 0, 0);
+ hwswitch_ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
if (hwswitch_ret)
return hwswitch_ret;
- hwswitch_state = buffer->output[1];
+ hwswitch_state = buffer.output[1];
seq_printf(s, "return:\t%d\n", ret);
seq_printf(s, "status:\t0x%X\n", status);
@@ -594,38 +636,27 @@ static int dell_debugfs_show(struct seq_file *s, void *data)
return 0;
}
-
-static int dell_debugfs_open(struct inode *inode, struct file *file)
-{
- return single_open(file, dell_debugfs_show, inode->i_private);
-}
-
-static const struct file_operations dell_debugfs_fops = {
- .owner = THIS_MODULE,
- .open = dell_debugfs_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(dell_debugfs);
static void dell_update_rfkill(struct work_struct *ignored)
{
+ struct calling_interface_buffer buffer;
int hwswitch = 0;
int status;
int ret;
- dell_set_arguments(0, 0, 0, 0);
- ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
- status = buffer->output[1];
+ dell_fill_request(&buffer, 0, 0, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
+ status = buffer.output[1];
if (ret != 0)
return;
- dell_set_arguments(0, 0x2, 0, 0);
- ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
+ dell_fill_request(&buffer, 0, 0x2, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
if (ret == 0 && (status & BIT(0)))
- hwswitch = buffer->output[1];
+ hwswitch = buffer.output[1];
if (wifi_rfkill) {
dell_rfkill_update_hw_state(wifi_rfkill, 1, status, hwswitch);
@@ -683,6 +714,7 @@ static struct notifier_block dell_laptop_rbtn_notifier = {
static int __init dell_setup_rfkill(void)
{
+ struct calling_interface_buffer buffer;
int status, ret, whitelisted;
const char *product;
@@ -698,9 +730,9 @@ static int __init dell_setup_rfkill(void)
if (!force_rfkill && !whitelisted)
return 0;
- dell_set_arguments(0, 0, 0, 0);
- ret = dell_send_request(CLASS_INFO, SELECT_RFKILL);
- status = buffer->output[1];
+ dell_fill_request(&buffer, 0, 0, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_INFO, SELECT_RFKILL);
+ status = buffer.output[1];
/* dell wireless info smbios call is not supported */
if (ret != 0)
@@ -853,6 +885,7 @@ static void dell_cleanup_rfkill(void)
static int dell_send_intensity(struct backlight_device *bd)
{
+ struct calling_interface_buffer buffer;
struct calling_interface_token *token;
int ret;
@@ -860,17 +893,21 @@ static int dell_send_intensity(struct backlight_device *bd)
if (!token)
return -ENODEV;
- dell_set_arguments(token->location, bd->props.brightness, 0, 0);
+ dell_fill_request(&buffer,
+ token->location, bd->props.brightness, 0, 0);
if (power_supply_is_system_supplied() > 0)
- ret = dell_send_request(CLASS_TOKEN_WRITE, SELECT_TOKEN_AC);
+ ret = dell_send_request(&buffer,
+ CLASS_TOKEN_WRITE, SELECT_TOKEN_AC);
else
- ret = dell_send_request(CLASS_TOKEN_WRITE, SELECT_TOKEN_BAT);
+ ret = dell_send_request(&buffer,
+ CLASS_TOKEN_WRITE, SELECT_TOKEN_BAT);
return ret;
}
static int dell_get_intensity(struct backlight_device *bd)
{
+ struct calling_interface_buffer buffer;
struct calling_interface_token *token;
int ret;
@@ -878,14 +915,17 @@ static int dell_get_intensity(struct backlight_device *bd)
if (!token)
return -ENODEV;
- dell_set_arguments(token->location, 0, 0, 0);
+ dell_fill_request(&buffer, token->location, 0, 0, 0);
if (power_supply_is_system_supplied() > 0)
- ret = dell_send_request(CLASS_TOKEN_READ, SELECT_TOKEN_AC);
+ ret = dell_send_request(&buffer,
+ CLASS_TOKEN_READ, SELECT_TOKEN_AC);
else
- ret = dell_send_request(CLASS_TOKEN_READ, SELECT_TOKEN_BAT);
+ ret = dell_send_request(&buffer,
+ CLASS_TOKEN_READ, SELECT_TOKEN_BAT);
if (ret == 0)
- ret = buffer->output[1];
+ ret = buffer.output[1];
+
return ret;
}
@@ -1133,6 +1173,7 @@ static u8 kbd_previous_mode_bit;
static bool kbd_led_present;
static DEFINE_MUTEX(kbd_led_mutex);
+static enum led_brightness kbd_led_level;
/*
* NOTE: there are three ways to set the keyboard backlight level.
@@ -1149,31 +1190,33 @@ static DEFINE_MUTEX(kbd_led_mutex);
static int kbd_get_info(struct kbd_info *info)
{
+ struct calling_interface_buffer buffer;
u8 units;
int ret;
- dell_set_arguments(0, 0, 0, 0);
- ret = dell_send_request(CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
+ dell_fill_request(&buffer, 0, 0, 0, 0);
+ ret = dell_send_request(&buffer,
+ CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
if (ret)
return ret;
- info->modes = buffer->output[1] & 0xFFFF;
- info->type = (buffer->output[1] >> 24) & 0xFF;
- info->triggers = buffer->output[2] & 0xFF;
- units = (buffer->output[2] >> 8) & 0xFF;
- info->levels = (buffer->output[2] >> 16) & 0xFF;
+ info->modes = buffer.output[1] & 0xFFFF;
+ info->type = (buffer.output[1] >> 24) & 0xFF;
+ info->triggers = buffer.output[2] & 0xFF;
+ units = (buffer.output[2] >> 8) & 0xFF;
+ info->levels = (buffer.output[2] >> 16) & 0xFF;
if (quirks && quirks->kbd_led_levels_off_1 && info->levels)
info->levels--;
if (units & BIT(0))
- info->seconds = (buffer->output[3] >> 0) & 0xFF;
+ info->seconds = (buffer.output[3] >> 0) & 0xFF;
if (units & BIT(1))
- info->minutes = (buffer->output[3] >> 8) & 0xFF;
+ info->minutes = (buffer.output[3] >> 8) & 0xFF;
if (units & BIT(2))
- info->hours = (buffer->output[3] >> 16) & 0xFF;
+ info->hours = (buffer.output[3] >> 16) & 0xFF;
if (units & BIT(3))
- info->days = (buffer->output[3] >> 24) & 0xFF;
+ info->days = (buffer.output[3] >> 24) & 0xFF;
return ret;
}
@@ -1233,31 +1276,34 @@ static int kbd_set_level(struct kbd_state *state, u8 level)
static int kbd_get_state(struct kbd_state *state)
{
+ struct calling_interface_buffer buffer;
int ret;
- dell_set_arguments(0x1, 0, 0, 0);
- ret = dell_send_request(CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
+ dell_fill_request(&buffer, 0, 0, 0, 0);
+ ret = dell_send_request(&buffer,
+ CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
if (ret)
return ret;
- state->mode_bit = ffs(buffer->output[1] & 0xFFFF);
+ state->mode_bit = ffs(buffer.output[1] & 0xFFFF);
if (state->mode_bit != 0)
state->mode_bit--;
- state->triggers = (buffer->output[1] >> 16) & 0xFF;
- state->timeout_value = (buffer->output[1] >> 24) & 0x3F;
- state->timeout_unit = (buffer->output[1] >> 30) & 0x3;
- state->als_setting = buffer->output[2] & 0xFF;
- state->als_value = (buffer->output[2] >> 8) & 0xFF;
- state->level = (buffer->output[2] >> 16) & 0xFF;
- state->timeout_value_ac = (buffer->output[2] >> 24) & 0x3F;
- state->timeout_unit_ac = (buffer->output[2] >> 30) & 0x3;
+ state->triggers = (buffer.output[1] >> 16) & 0xFF;
+ state->timeout_value = (buffer.output[1] >> 24) & 0x3F;
+ state->timeout_unit = (buffer.output[1] >> 30) & 0x3;
+ state->als_setting = buffer.output[2] & 0xFF;
+ state->als_value = (buffer.output[2] >> 8) & 0xFF;
+ state->level = (buffer.output[2] >> 16) & 0xFF;
+ state->timeout_value_ac = (buffer.output[2] >> 24) & 0x3F;
+ state->timeout_unit_ac = (buffer.output[2] >> 30) & 0x3;
return ret;
}
static int kbd_set_state(struct kbd_state *state)
{
+ struct calling_interface_buffer buffer;
int ret;
u32 input1;
u32 input2;
@@ -1270,8 +1316,9 @@ static int kbd_set_state(struct kbd_state *state)
input2 |= (state->level & 0xFF) << 16;
input2 |= (state->timeout_value_ac & 0x3F) << 24;
input2 |= (state->timeout_unit_ac & 0x3) << 30;
- dell_set_arguments(0x2, input1, input2, 0);
- ret = dell_send_request(CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
+ dell_fill_request(&buffer, 0x2, input1, input2, 0);
+ ret = dell_send_request(&buffer,
+ CLASS_KBD_BACKLIGHT, SELECT_KBD_BACKLIGHT);
return ret;
}
@@ -1298,6 +1345,7 @@ static int kbd_set_state_safe(struct kbd_state *state, struct kbd_state *old)
static int kbd_set_token_bit(u8 bit)
{
+ struct calling_interface_buffer buffer;
struct calling_interface_token *token;
int ret;
@@ -1308,14 +1356,15 @@ static int kbd_set_token_bit(u8 bit)
if (!token)
return -EINVAL;
- dell_set_arguments(token->location, token->value, 0, 0);
- ret = dell_send_request(CLASS_TOKEN_WRITE, SELECT_TOKEN_STD);
+ dell_fill_request(&buffer, token->location, token->value, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_TOKEN_WRITE, SELECT_TOKEN_STD);
return ret;
}
static int kbd_get_token_bit(u8 bit)
{
+ struct calling_interface_buffer buffer;
struct calling_interface_token *token;
int ret;
int val;
@@ -1327,9 +1376,9 @@ static int kbd_get_token_bit(u8 bit)
if (!token)
return -EINVAL;
- dell_set_arguments(token->location, 0, 0, 0);
- ret = dell_send_request(CLASS_TOKEN_READ, SELECT_TOKEN_STD);
- val = buffer->output[1];
+ dell_fill_request(&buffer, token->location, 0, 0, 0);
+ ret = dell_send_request(&buffer, CLASS_TOKEN_READ, SELECT_TOKEN_STD);
+ val = buffer.output[1];
if (ret)
return ret;
@@ -1947,6 +1996,7 @@ static enum led_brightness kbd_led_level_get(struct led_classdev *led_cdev)
static int kbd_led_level_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
+ enum led_brightness new_value = value;
struct kbd_state state;
struct kbd_state new_state;
u16 num;
@@ -1976,6 +2026,9 @@ static int kbd_led_level_set(struct led_classdev *led_cdev,
}
out:
+ if (ret == 0)
+ kbd_led_level = new_value;
+
mutex_unlock(&kbd_led_mutex);
return ret;
}
@@ -2003,6 +2056,9 @@ static int __init kbd_led_init(struct device *dev)
if (kbd_led.max_brightness)
kbd_led.max_brightness--;
}
+
+ kbd_led_level = kbd_led_level_get(NULL);
+
ret = led_classdev_register(dev, &kbd_led);
if (ret)
kbd_led_present = false;
@@ -2027,13 +2083,25 @@ static void kbd_led_exit(void)
static int dell_laptop_notifier_call(struct notifier_block *nb,
unsigned long action, void *data)
{
+ bool changed = false;
+ enum led_brightness new_kbd_led_level;
+
switch (action) {
case DELL_LAPTOP_KBD_BACKLIGHT_BRIGHTNESS_CHANGED:
if (!kbd_led_present)
break;
- led_classdev_notify_brightness_hw_changed(&kbd_led,
- kbd_led_level_get(&kbd_led));
+ mutex_lock(&kbd_led_mutex);
+ new_kbd_led_level = kbd_led_level_get(&kbd_led);
+ if (kbd_led_level != new_kbd_led_level) {
+ kbd_led_level = new_kbd_led_level;
+ changed = true;
+ }
+ mutex_unlock(&kbd_led_mutex);
+
+ if (changed)
+ led_classdev_notify_brightness_hw_changed(&kbd_led,
+ kbd_led_level);
break;
}
@@ -2046,6 +2114,7 @@ static struct notifier_block dell_laptop_notifier = {
int dell_micmute_led_set(int state)
{
+ struct calling_interface_buffer buffer;
struct calling_interface_token *token;
if (state == 0)
@@ -2058,8 +2127,8 @@ int dell_micmute_led_set(int state)
if (!token)
return -ENODEV;
- dell_set_arguments(token->location, token->value, 0, 0);
- dell_send_request(CLASS_TOKEN_WRITE, SELECT_TOKEN_STD);
+ dell_fill_request(&buffer, token->location, token->value, 0, 0);
+ dell_send_request(&buffer, CLASS_TOKEN_WRITE, SELECT_TOKEN_STD);
return state;
}
@@ -2090,13 +2159,6 @@ static int __init dell_init(void)
if (ret)
goto fail_platform_device2;
- buffer = kzalloc(sizeof(struct calling_interface_buffer), GFP_KERNEL);
- if (!buffer) {
- ret = -ENOMEM;
- goto fail_buffer;
- }
-
-
ret = dell_setup_rfkill();
if (ret) {
@@ -2121,10 +2183,13 @@ static int __init dell_init(void)
token = dell_smbios_find_token(BRIGHTNESS_TOKEN);
if (token) {
- dell_set_arguments(token->location, 0, 0, 0);
- ret = dell_send_request(CLASS_TOKEN_READ, SELECT_TOKEN_AC);
+ struct calling_interface_buffer buffer;
+
+ dell_fill_request(&buffer, token->location, 0, 0, 0);
+ ret = dell_send_request(&buffer,
+ CLASS_TOKEN_READ, SELECT_TOKEN_AC);
if (ret)
- max_intensity = buffer->output[3];
+ max_intensity = buffer.output[3];
}
if (max_intensity) {
@@ -2158,8 +2223,6 @@ static int __init dell_init(void)
fail_get_brightness:
backlight_device_unregister(dell_backlight_device);
fail_backlight:
- kfree(buffer);
-fail_buffer:
dell_cleanup_rfkill();
fail_rfkill:
platform_device_del(platform_device);
@@ -2179,7 +2242,6 @@ static void __exit dell_exit(void)
touchpad_led_exit();
kbd_led_exit();
backlight_device_unregister(dell_backlight_device);
- kfree(buffer);
dell_cleanup_rfkill();
if (platform_device) {
platform_device_unregister(platform_device);
diff --git a/drivers/platform/x86/dell-smbios.c b/drivers/platform/x86/dell-smbios.c
index 6a60db515bda..8541cde4cb7d 100644
--- a/drivers/platform/x86/dell-smbios.c
+++ b/drivers/platform/x86/dell-smbios.c
@@ -65,10 +65,10 @@ static struct smbios_call call_whitelist[] = {
/* calls that are explicitly blacklisted */
static struct smbios_call call_blacklist[] = {
- {0x0000, 01, 07}, /* manufacturing use */
- {0x0000, 06, 05}, /* manufacturing use */
- {0x0000, 11, 03}, /* write once */
- {0x0000, 11, 07}, /* write once */
+ {0x0000, 1, 7}, /* manufacturing use */
+ {0x0000, 6, 5}, /* manufacturing use */
+ {0x0000, 11, 3}, /* write once */
+ {0x0000, 11, 7}, /* write once */
{0x0000, 11, 11}, /* write once */
{0x0000, 19, -1}, /* diagnostics */
/* handled by kernel: dell-laptop */
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
index fb25b20df316..2c9927430d85 100644
--- a/drivers/platform/x86/dell-wmi.c
+++ b/drivers/platform/x86/dell-wmi.c
@@ -261,6 +261,9 @@ static const u16 bios_to_linux_keycode[256] = {
* override them.
*/
static const struct key_entry dell_wmi_keymap_type_0010[] = {
+ /* Mic mute */
+ { KE_KEY, 0x150, { KEY_MICMUTE } },
+
/* Fn-lock */
{ KE_IGNORE, 0x151, { KEY_RESERVED } },
diff --git a/drivers/platform/x86/gpd-pocket-fan.c b/drivers/platform/x86/gpd-pocket-fan.c
new file mode 100644
index 000000000000..2d645c505f81
--- /dev/null
+++ b/drivers/platform/x86/gpd-pocket-fan.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * GPD Pocket fan controller driver
+ *
+ * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
+ */
+
+#include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/thermal.h>
+#include <linux/workqueue.h>
+
+#define MAX_SPEED 3
+
+static int temp_limits[3] = { 55000, 60000, 65000 };
+module_param_array(temp_limits, int, NULL, 0444);
+MODULE_PARM_DESC(temp_limits,
+ "Milli-celcius values above which the fan speed increases");
+
+static int hysteresis = 3000;
+module_param(hysteresis, int, 0444);
+MODULE_PARM_DESC(hysteresis,
+ "Hysteresis in milli-celcius before lowering the fan speed");
+
+static int speed_on_ac = 2;
+module_param(speed_on_ac, int, 0444);
+MODULE_PARM_DESC(speed_on_ac,
+ "minimum fan speed to allow when system is powered by AC");
+
+struct gpd_pocket_fan_data {
+ struct device *dev;
+ struct thermal_zone_device *dts0;
+ struct thermal_zone_device *dts1;
+ struct gpio_desc *gpio0;
+ struct gpio_desc *gpio1;
+ struct delayed_work work;
+ int last_speed;
+};
+
+static void gpd_pocket_fan_set_speed(struct gpd_pocket_fan_data *fan, int speed)
+{
+ if (speed == fan->last_speed)
+ return;
+
+ gpiod_direction_output(fan->gpio0, !!(speed & 1));
+ gpiod_direction_output(fan->gpio1, !!(speed & 2));
+
+ fan->last_speed = speed;
+}
+
+static int gpd_pocket_fan_min_speed(void)
+{
+ if (power_supply_is_system_supplied())
+ return speed_on_ac;
+ else
+ return 0;
+}
+
+static void gpd_pocket_fan_worker(struct work_struct *work)
+{
+ struct gpd_pocket_fan_data *fan =
+ container_of(work, struct gpd_pocket_fan_data, work.work);
+ int t0, t1, temp, speed, min_speed, i;
+
+ if (thermal_zone_get_temp(fan->dts0, &t0) ||
+ thermal_zone_get_temp(fan->dts1, &t1)) {
+ dev_warn(fan->dev, "Error getting temperature\n");
+ speed = MAX_SPEED;
+ goto set_speed;
+ }
+
+ temp = max(t0, t1);
+
+ speed = fan->last_speed;
+ min_speed = gpd_pocket_fan_min_speed();
+
+ /* Determine minimum speed */
+ for (i = min_speed; i < ARRAY_SIZE(temp_limits); i++) {
+ if (temp < temp_limits[i])
+ break;
+ }
+ if (speed < i)
+ speed = i;
+
+ /* Use hysteresis before lowering speed again */
+ for (i = min_speed; i < ARRAY_SIZE(temp_limits); i++) {
+ if (temp <= (temp_limits[i] - hysteresis))
+ break;
+ }
+ if (speed > i)
+ speed = i;
+
+ if (fan->last_speed <= 0 && speed)
+ speed = MAX_SPEED; /* kick start motor */
+
+set_speed:
+ gpd_pocket_fan_set_speed(fan, speed);
+
+ /* When mostly idle (low temp/speed), slow down the poll interval. */
+ queue_delayed_work(system_wq, &fan->work,
+ msecs_to_jiffies(4000 / (speed + 1)));
+}
+
+static void gpd_pocket_fan_force_update(struct gpd_pocket_fan_data *fan)
+{
+ fan->last_speed = -1;
+ mod_delayed_work(system_wq, &fan->work, 0);
+}
+
+static int gpd_pocket_fan_probe(struct platform_device *pdev)
+{
+ struct gpd_pocket_fan_data *fan;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(temp_limits); i++) {
+ if (temp_limits[i] < 40000 || temp_limits[i] > 70000) {
+ dev_err(&pdev->dev, "Invalid temp-limit %d (must be between 40000 and 70000)\n",
+ temp_limits[i]);
+ return -EINVAL;
+ }
+ }
+ if (hysteresis < 1000 || hysteresis > 10000) {
+ dev_err(&pdev->dev, "Invalid hysteresis %d (must be between 1000 and 10000)\n",
+ hysteresis);
+ return -EINVAL;
+ }
+ if (speed_on_ac < 0 || speed_on_ac > MAX_SPEED) {
+ dev_err(&pdev->dev, "Invalid speed_on_ac %d (must be between 0 and 3)\n",
+ speed_on_ac);
+ return -EINVAL;
+ }
+
+ fan = devm_kzalloc(&pdev->dev, sizeof(*fan), GFP_KERNEL);
+ if (!fan)
+ return -ENOMEM;
+
+ fan->dev = &pdev->dev;
+ INIT_DELAYED_WORK(&fan->work, gpd_pocket_fan_worker);
+
+ /* Note this returns a "weak" reference which we don't need to free */
+ fan->dts0 = thermal_zone_get_zone_by_name("soc_dts0");
+ if (IS_ERR(fan->dts0))
+ return -EPROBE_DEFER;
+
+ fan->dts1 = thermal_zone_get_zone_by_name("soc_dts1");
+ if (IS_ERR(fan->dts1))
+ return -EPROBE_DEFER;
+
+ fan->gpio0 = devm_gpiod_get_index(fan->dev, NULL, 0, GPIOD_ASIS);
+ if (IS_ERR(fan->gpio0))
+ return PTR_ERR(fan->gpio0);
+
+ fan->gpio1 = devm_gpiod_get_index(fan->dev, NULL, 1, GPIOD_ASIS);
+ if (IS_ERR(fan->gpio1))
+ return PTR_ERR(fan->gpio1);
+
+ gpd_pocket_fan_force_update(fan);
+
+ platform_set_drvdata(pdev, fan);
+ return 0;
+}
+
+static int gpd_pocket_fan_remove(struct platform_device *pdev)
+{
+ struct gpd_pocket_fan_data *fan = platform_get_drvdata(pdev);
+
+ cancel_delayed_work_sync(&fan->work);
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int gpd_pocket_fan_suspend(struct device *dev)
+{
+ struct gpd_pocket_fan_data *fan = dev_get_drvdata(dev);
+
+ cancel_delayed_work_sync(&fan->work);
+ gpd_pocket_fan_set_speed(fan, gpd_pocket_fan_min_speed());
+ return 0;
+}
+
+static int gpd_pocket_fan_resume(struct device *dev)
+{
+ struct gpd_pocket_fan_data *fan = dev_get_drvdata(dev);
+
+ gpd_pocket_fan_force_update(fan);
+ return 0;
+}
+#endif
+static SIMPLE_DEV_PM_OPS(gpd_pocket_fan_pm_ops,
+ gpd_pocket_fan_suspend,
+ gpd_pocket_fan_resume);
+
+static struct acpi_device_id gpd_pocket_fan_acpi_match[] = {
+ { "FAN02501" },
+ {},
+};
+MODULE_DEVICE_TABLE(acpi, gpd_pocket_fan_acpi_match);
+
+static struct platform_driver gpd_pocket_fan_driver = {
+ .probe = gpd_pocket_fan_probe,
+ .remove = gpd_pocket_fan_remove,
+ .driver = {
+ .name = "gpd_pocket_fan",
+ .acpi_match_table = gpd_pocket_fan_acpi_match,
+ .pm = &gpd_pocket_fan_pm_ops,
+ },
+};
+
+module_platform_driver(gpd_pocket_fan_driver);
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com");
+MODULE_DESCRIPTION("GPD pocket fan driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 53ab4e0f8962..5b6f18b18801 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -124,10 +124,10 @@ static int read_method_int(acpi_handle handle, const char *method, int *val)
if (ACPI_FAILURE(status)) {
*val = -1;
return -1;
- } else {
- *val = result;
- return 0;
}
+ *val = result;
+ return 0;
+
}
static int method_gbmd(acpi_handle handle, unsigned long *ret)
@@ -164,10 +164,10 @@ static int method_vpcr(acpi_handle handle, int cmd, int *ret)
if (ACPI_FAILURE(status)) {
*ret = -1;
return -1;
- } else {
- *ret = result;
- return 0;
}
+ *ret = result;
+ return 0;
+
}
static int method_vpcw(acpi_handle handle, int cmd, int data)
@@ -231,7 +231,7 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data)
if (val == 0)
return 0;
}
- pr_err("timeout in write_ec_cmd\n");
+ pr_err("timeout in %s\n", __func__);
return -1;
}
@@ -284,19 +284,7 @@ static int debugfs_status_show(struct seq_file *s, void *data)
return 0;
}
-
-static int debugfs_status_open(struct inode *inode, struct file *file)
-{
- return single_open(file, debugfs_status_show, inode->i_private);
-}
-
-static const struct file_operations debugfs_status_fops = {
- .owner = THIS_MODULE,
- .open = debugfs_status_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(debugfs_status);
static int debugfs_cfg_show(struct seq_file *s, void *data)
{
@@ -337,19 +325,7 @@ static int debugfs_cfg_show(struct seq_file *s, void *data)
}
return 0;
}
-
-static int debugfs_cfg_open(struct inode *inode, struct file *file)
-{
- return single_open(file, debugfs_cfg_show, inode->i_private);
-}
-
-static const struct file_operations debugfs_cfg_fops = {
- .owner = THIS_MODULE,
- .open = debugfs_cfg_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(debugfs_cfg);
static int ideapad_debugfs_init(struct ideapad_private *priv)
{
@@ -964,6 +940,13 @@ static void ideapad_wmi_notify(u32 value, void *context)
*/
static const struct dmi_system_id no_hw_rfkill_list[] = {
{
+ .ident = "Lenovo RESCUER R720-15IKBN",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_BOARD_NAME, "80WW"),
+ },
+ },
+ {
.ident = "Lenovo G40-30",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
@@ -1104,6 +1087,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = {
},
},
{
+ .ident = "Lenovo Legion Y720-15IKB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y720-15IKB"),
+ },
+ },
+ {
.ident = "Lenovo Legion Y720-15IKBN",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
diff --git a/drivers/platform/x86/intel-hid.c b/drivers/platform/x86/intel-hid.c
index f470279c4c10..d1a01311c1a2 100644
--- a/drivers/platform/x86/intel-hid.c
+++ b/drivers/platform/x86/intel-hid.c
@@ -25,6 +25,7 @@
#include <linux/acpi.h>
#include <linux/suspend.h>
#include <acpi/acpi_bus.h>
+#include <linux/dmi.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alex Hung");
@@ -73,6 +74,24 @@ static const struct key_entry intel_array_keymap[] = {
{ KE_END },
};
+static const struct dmi_system_id button_array_table[] = {
+ {
+ .ident = "Wacom MobileStudio Pro 13",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Wacom Co.,Ltd"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Wacom MobileStudio Pro 13"),
+ },
+ },
+ {
+ .ident = "Wacom MobileStudio Pro 16",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Wacom Co.,Ltd"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Wacom MobileStudio Pro 16"),
+ },
+ },
+ { }
+};
+
struct intel_hid_priv {
struct input_dev *input_dev;
struct input_dev *array;
@@ -263,10 +282,27 @@ wakeup:
ev_index);
}
+static bool button_array_present(struct platform_device *device)
+{
+ acpi_handle handle = ACPI_HANDLE(&device->dev);
+ unsigned long long event_cap;
+ acpi_status status;
+ bool supported = false;
+
+ status = acpi_evaluate_integer(handle, "HEBC", NULL, &event_cap);
+ if (ACPI_SUCCESS(status) && (event_cap & 0x20000))
+ supported = true;
+
+ if (dmi_check_system(button_array_table))
+ supported = true;
+
+ return supported;
+}
+
static int intel_hid_probe(struct platform_device *device)
{
acpi_handle handle = ACPI_HANDLE(&device->dev);
- unsigned long long event_cap, mode;
+ unsigned long long mode;
struct intel_hid_priv *priv;
acpi_status status;
int err;
@@ -299,8 +335,7 @@ static int intel_hid_probe(struct platform_device *device)
}
/* Setup 5 button array */
- status = acpi_evaluate_integer(handle, "HEBC", NULL, &event_cap);
- if (ACPI_SUCCESS(status) && (event_cap & 0x20000)) {
+ if (button_array_present(device)) {
dev_info(&device->dev, "platform supports 5 button array\n");
err = intel_button_array_input_setup(device);
if (err)
diff --git a/drivers/platform/x86/intel-vbtn.c b/drivers/platform/x86/intel-vbtn.c
index 58c5ff36523a..b703d6f5b099 100644
--- a/drivers/platform/x86/intel-vbtn.c
+++ b/drivers/platform/x86/intel-vbtn.c
@@ -1,30 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
/*
* Intel Virtual Button driver for Windows 8.1+
*
* Copyright (C) 2016 AceLan Kao <acelan.kao@canonical.com>
* Copyright (C) 2016 Alex Hung <alex.hung@canonical.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
+#include <linux/acpi.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/input.h>
#include <linux/platform_device.h>
-#include <linux/input/sparse-keymap.h>
-#include <linux/acpi.h>
#include <linux/suspend.h>
-#include <acpi/acpi_bus.h>
+
+/* When NOT in tablet mode, VGBS returns with the flag 0x40 */
+#define TABLET_MODE_FLAG 0x40
MODULE_LICENSE("GPL");
MODULE_AUTHOR("AceLan Kao");
@@ -38,10 +29,16 @@ static const struct acpi_device_id intel_vbtn_ids[] = {
static const struct key_entry intel_vbtn_keymap[] = {
{ KE_KEY, 0xC0, { KEY_POWER } }, /* power key press */
{ KE_IGNORE, 0xC1, { KEY_POWER } }, /* power key release */
+ { KE_KEY, 0xC2, { KEY_LEFTMETA } }, /* 'Windows' key press */
+ { KE_KEY, 0xC3, { KEY_LEFTMETA } }, /* 'Windows' key release */
{ KE_KEY, 0xC4, { KEY_VOLUMEUP } }, /* volume-up key press */
{ KE_IGNORE, 0xC5, { KEY_VOLUMEUP } }, /* volume-up key release */
{ KE_KEY, 0xC6, { KEY_VOLUMEDOWN } }, /* volume-down key press */
{ KE_IGNORE, 0xC7, { KEY_VOLUMEDOWN } }, /* volume-down key release */
+ { KE_KEY, 0xC8, { KEY_ROTATE_LOCK_TOGGLE } }, /* rotate-lock key press */
+ { KE_KEY, 0xC9, { KEY_ROTATE_LOCK_TOGGLE } }, /* rotate-lock key release */
+ { KE_SW, 0xCC, { .sw = { SW_TABLET_MODE, 1 } } }, /* Tablet */
+ { KE_SW, 0xCD, { .sw = { SW_TABLET_MODE, 0 } } }, /* Laptop */
{ KE_END },
};
@@ -74,20 +71,35 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
{
struct platform_device *device = context;
struct intel_vbtn_priv *priv = dev_get_drvdata(&device->dev);
+ unsigned int val = !(event & 1); /* Even=press, Odd=release */
+ const struct key_entry *ke_rel;
+ bool autorelease;
if (priv->wakeup_mode) {
if (sparse_keymap_entry_from_scancode(priv->input_dev, event)) {
pm_wakeup_hard_event(&device->dev);
return;
}
- } else if (sparse_keymap_report_event(priv->input_dev, event, 1, true)) {
- return;
+ goto out_unknown;
}
+
+ /*
+ * Even press events are autorelease if there is no corresponding odd
+ * release event, or if the odd event is KE_IGNORE.
+ */
+ ke_rel = sparse_keymap_entry_from_scancode(priv->input_dev, event | 1);
+ autorelease = val && (!ke_rel || ke_rel->type == KE_IGNORE);
+
+ if (sparse_keymap_report_event(priv->input_dev, event, val, autorelease))
+ return;
+
+out_unknown:
dev_dbg(&device->dev, "unknown event index 0x%x\n", event);
}
static int intel_vbtn_probe(struct platform_device *device)
{
+ struct acpi_buffer vgbs_output = { ACPI_ALLOCATE_BUFFER, NULL };
acpi_handle handle = ACPI_HANDLE(&device->dev);
struct intel_vbtn_priv *priv;
acpi_status status;
@@ -110,6 +122,23 @@ static int intel_vbtn_probe(struct platform_device *device)
return err;
}
+ /*
+ * VGBS being present and returning something means we have
+ * a tablet mode switch.
+ */
+ status = acpi_evaluate_object(handle, "VGBS", NULL, &vgbs_output);
+ if (ACPI_SUCCESS(status)) {
+ union acpi_object *obj = vgbs_output.pointer;
+
+ if (obj && obj->type == ACPI_TYPE_INTEGER) {
+ int m = !(obj->integer.value & TABLET_MODE_FLAG);
+
+ input_report_switch(priv->input_dev, SW_TABLET_MODE, m);
+ }
+ }
+
+ kfree(vgbs_output.pointer);
+
status = acpi_install_notify_handler(handle,
ACPI_DEVICE_NOTIFY,
notify_handler,
diff --git a/drivers/platform/x86/intel_chtdc_ti_pwrbtn.c b/drivers/platform/x86/intel_chtdc_ti_pwrbtn.c
new file mode 100644
index 000000000000..38b8e7cfe88c
--- /dev/null
+++ b/drivers/platform/x86/intel_chtdc_ti_pwrbtn.c
@@ -0,0 +1,93 @@
+/*
+ * Power-button driver for Dollar Cove TI PMIC
+ * Copyright (C) 2014 Intel Corp
+ * Copyright (c) 2017 Takashi Iwai <tiwai@suse.de>
+ */
+
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/mfd/intel_soc_pmic.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
+#include <linux/slab.h>
+
+#define CHTDC_TI_SIRQ_REG 0x3
+#define SIRQ_PWRBTN_REL BIT(0)
+
+static irqreturn_t chtdc_ti_pwrbtn_interrupt(int irq, void *dev_id)
+{
+ struct input_dev *input = dev_id;
+ struct device *dev = input->dev.parent;
+ struct regmap *regmap = dev_get_drvdata(dev);
+ int state;
+
+ if (!regmap_read(regmap, CHTDC_TI_SIRQ_REG, &state)) {
+ dev_dbg(dev, "SIRQ_REG=0x%x\n", state);
+ input_report_key(input, KEY_POWER, !(state & SIRQ_PWRBTN_REL));
+ input_sync(input);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int chtdc_ti_pwrbtn_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct intel_soc_pmic *pmic = dev_get_drvdata(dev->parent);
+ struct input_dev *input;
+ int irq, err;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+ input = devm_input_allocate_device(dev);
+ if (!input)
+ return -ENOMEM;
+ input->name = pdev->name;
+ input->phys = "power-button/input0";
+ input->id.bustype = BUS_HOST;
+ input_set_capability(input, EV_KEY, KEY_POWER);
+ err = input_register_device(input);
+ if (err)
+ return err;
+
+ dev_set_drvdata(dev, pmic->regmap);
+
+ err = devm_request_threaded_irq(dev, irq, NULL,
+ chtdc_ti_pwrbtn_interrupt,
+ 0, KBUILD_MODNAME, input);
+ if (err)
+ return err;
+
+ device_init_wakeup(dev, true);
+ dev_pm_set_wake_irq(dev, irq);
+ return 0;
+}
+
+static int chtdc_ti_pwrbtn_remove(struct platform_device *pdev)
+{
+ dev_pm_clear_wake_irq(&pdev->dev);
+ device_init_wakeup(&pdev->dev, false);
+ return 0;
+}
+
+static const struct platform_device_id chtdc_ti_pwrbtn_id_table[] = {
+ { .name = "chtdc_ti_pwrbtn" },
+ {},
+};
+MODULE_DEVICE_TABLE(platform, chtdc_ti_pwrbtn_id_table);
+
+static struct platform_driver chtdc_ti_pwrbtn_driver = {
+ .driver = {
+ .name = KBUILD_MODNAME,
+ },
+ .probe = chtdc_ti_pwrbtn_probe,
+ .remove = chtdc_ti_pwrbtn_remove,
+ .id_table = chtdc_ti_pwrbtn_id_table,
+};
+module_platform_driver(chtdc_ti_pwrbtn_driver);
+
+MODULE_DESCRIPTION("Power-button driver for Dollar Cove TI PMIC");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c
index f7b67e898abc..a473dc51b18d 100644
--- a/drivers/platform/x86/intel_int0002_vgpio.c
+++ b/drivers/platform/x86/intel_int0002_vgpio.c
@@ -180,7 +180,7 @@ static int int0002_probe(struct platform_device *pdev)
* to gpiochip_set_chained_irqchip, because the irq is shared.
*/
ret = devm_request_irq(dev, irq, int0002_irq,
- IRQF_SHARED | IRQF_NO_THREAD, "INT0002", chip);
+ IRQF_SHARED, "INT0002", chip);
if (ret) {
dev_err(dev, "Error requesting IRQ %d: %d\n", irq, ret);
return ret;
diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index 17e08b42b0a9..43bbe74743d9 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -18,20 +18,24 @@
*
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/acpi.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/init.h>
#include <linux/io.h>
+#include <linux/module.h>
#include <linux/pci.h>
#include <linux/uaccess.h>
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
-#include <asm/pmc_core.h>
#include "intel_pmc_core.h"
+#define ICPU(model, data) \
+ { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (kernel_ulong_t)data }
+
static struct pmc_dev pmc;
static const struct pmc_bit_map spt_pll_map[] = {
@@ -119,10 +123,88 @@ static const struct pmc_reg_map spt_reg_map = {
.pm_read_disable_bit = SPT_PMC_READ_DISABLE_BIT,
};
-static const struct pci_device_id pmc_pci_ids[] = {
- { PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID),
- (kernel_ulong_t)&spt_reg_map },
- { 0, },
+/* Cannonlake: PGD PFET Enable Ack Status Register(s) bitmap */
+static const struct pmc_bit_map cnp_pfear_map[] = {
+ {"PMC", BIT(0)},
+ {"OPI-DMI", BIT(1)},
+ {"SPI/eSPI", BIT(2)},
+ {"XHCI", BIT(3)},
+ {"SPA", BIT(4)},
+ {"SPB", BIT(5)},
+ {"SPC", BIT(6)},
+ {"GBE", BIT(7)},
+
+ {"SATA", BIT(0)},
+ {"HDA_PGD0", BIT(1)},
+ {"HDA_PGD1", BIT(2)},
+ {"HDA_PGD2", BIT(3)},
+ {"HDA_PGD3", BIT(4)},
+ {"SPD", BIT(5)},
+ {"LPSS", BIT(6)},
+ {"LPC", BIT(7)},
+
+ {"SMB", BIT(0)},
+ {"ISH", BIT(1)},
+ {"P2SB", BIT(2)},
+ {"NPK_VNN", BIT(3)},
+ {"SDX", BIT(4)},
+ {"SPE", BIT(5)},
+ {"Fuse", BIT(6)},
+ {"Res_23", BIT(7)},
+
+ {"CSME_FSC", BIT(0)},
+ {"USB3_OTG", BIT(1)},
+ {"EXI", BIT(2)},
+ {"CSE", BIT(3)},
+ {"csme_kvm", BIT(4)},
+ {"csme_pmt", BIT(5)},
+ {"csme_clink", BIT(6)},
+ {"csme_ptio", BIT(7)},
+
+ {"csme_usbr", BIT(0)},
+ {"csme_susram", BIT(1)},
+ {"csme_smt1", BIT(2)},
+ {"CSME_SMT4", BIT(3)},
+ {"csme_sms2", BIT(4)},
+ {"csme_sms1", BIT(5)},
+ {"csme_rtc", BIT(6)},
+ {"csme_psf", BIT(7)},
+
+ {"SBR0", BIT(0)},
+ {"SBR1", BIT(1)},
+ {"SBR2", BIT(2)},
+ {"SBR3", BIT(3)},
+ {"SBR4", BIT(4)},
+ {"SBR5", BIT(5)},
+ {"CSME_PECI", BIT(6)},
+ {"PSF1", BIT(7)},
+
+ {"PSF2", BIT(0)},
+ {"PSF3", BIT(1)},
+ {"PSF4", BIT(2)},
+ {"CNVI", BIT(3)},
+ {"UFS0", BIT(4)},
+ {"EMMC", BIT(5)},
+ {"Res_6", BIT(6)},
+ {"SBR6", BIT(7)},
+
+ {"SBR7", BIT(0)},
+ {"NPK_AON", BIT(1)},
+ {"HDA_PGD4", BIT(2)},
+ {"HDA_PGD5", BIT(3)},
+ {"HDA_PGD6", BIT(4)},
+ {}
+};
+
+static const struct pmc_reg_map cnp_reg_map = {
+ .pfear_sts = cnp_pfear_map,
+ .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
+ .ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
+ .regmap_length = CNP_PMC_MMIO_REG_LEN,
+ .ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
+ .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES,
+ .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET,
+ .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT,
};
static inline u8 pmc_core_reg_read_byte(struct pmc_dev *pmcdev, int offset)
@@ -146,37 +228,6 @@ static inline u32 pmc_core_adjust_slp_s0_step(u32 value)
return value * SPT_PMC_SLP_S0_RES_COUNTER_STEP;
}
-/**
- * intel_pmc_slp_s0_counter_read() - Read SLP_S0 residency.
- * @data: Out param that contains current SLP_S0 count.
- *
- * This API currently supports Intel Skylake SoC and Sunrise
- * Point Platform Controller Hub. Future platform support
- * should be added for platforms that support low power modes
- * beyond Package C10 state.
- *
- * SLP_S0_RESIDENCY counter counts in 100 us granularity per
- * step hence function populates the multiplied value in out
- * parameter @data.
- *
- * Return: an error code or 0 on success.
- */
-int intel_pmc_slp_s0_counter_read(u32 *data)
-{
- struct pmc_dev *pmcdev = &pmc;
- const struct pmc_reg_map *map = pmcdev->map;
- u32 value;
-
- if (!pmcdev->has_slp_s0_res)
- return -EACCES;
-
- value = pmc_core_reg_read(pmcdev, map->slp_s0_offset);
- *data = pmc_core_adjust_slp_s0_step(value);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(intel_pmc_slp_s0_counter_read);
-
static int pmc_core_dev_state_get(void *data, u64 *val)
{
struct pmc_dev *pmcdev = data;
@@ -437,47 +488,33 @@ static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev)
static int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
{
- struct dentry *dir, *file;
+ struct dentry *dir;
dir = debugfs_create_dir("pmc_core", NULL);
if (!dir)
return -ENOMEM;
pmcdev->dbgfs_dir = dir;
- file = debugfs_create_file("slp_s0_residency_usec", S_IFREG | S_IRUGO,
- dir, pmcdev, &pmc_core_dev_state);
- if (!file)
- goto err;
-
- file = debugfs_create_file("pch_ip_power_gating_status",
- S_IFREG | S_IRUGO, dir, pmcdev,
- &pmc_core_ppfear_ops);
- if (!file)
- goto err;
-
- file = debugfs_create_file("mphy_core_lanes_power_gating_status",
- S_IFREG | S_IRUGO, dir, pmcdev,
- &pmc_core_mphy_pg_ops);
- if (!file)
- goto err;
-
- file = debugfs_create_file("pll_status",
- S_IFREG | S_IRUGO, dir, pmcdev,
- &pmc_core_pll_ops);
- if (!file)
- goto err;
-
- file = debugfs_create_file("ltr_ignore",
- S_IFREG | S_IRUGO, dir, pmcdev,
- &pmc_core_ltr_ignore_ops);
-
- if (!file)
- goto err;
+
+ debugfs_create_file("slp_s0_residency_usec", 0444, dir, pmcdev,
+ &pmc_core_dev_state);
+
+ debugfs_create_file("pch_ip_power_gating_status", 0444, dir, pmcdev,
+ &pmc_core_ppfear_ops);
+
+ debugfs_create_file("ltr_ignore", 0644, dir, pmcdev,
+ &pmc_core_ltr_ignore_ops);
+
+ if (pmcdev->map->pll_sts)
+ debugfs_create_file("pll_status", 0444, dir, pmcdev,
+ &pmc_core_pll_ops);
+
+ if (pmcdev->map->mphy_sts)
+ debugfs_create_file("mphy_core_lanes_power_gating_status",
+ 0444, dir, pmcdev,
+ &pmc_core_mphy_pg_ops);
return 0;
-err:
- pmc_core_dbgfs_unregister(pmcdev);
- return -ENODEV;
}
#else
static inline int pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
@@ -491,71 +528,76 @@ static inline void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev)
#endif /* CONFIG_DEBUG_FS */
static const struct x86_cpu_id intel_pmc_core_ids[] = {
- { X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_MOBILE, X86_FEATURE_MWAIT,
- (kernel_ulong_t)NULL},
- { X86_VENDOR_INTEL, 6, INTEL_FAM6_SKYLAKE_DESKTOP, X86_FEATURE_MWAIT,
- (kernel_ulong_t)NULL},
- { X86_VENDOR_INTEL, 6, INTEL_FAM6_KABYLAKE_MOBILE, X86_FEATURE_MWAIT,
- (kernel_ulong_t)NULL},
- { X86_VENDOR_INTEL, 6, INTEL_FAM6_KABYLAKE_DESKTOP, X86_FEATURE_MWAIT,
- (kernel_ulong_t)NULL},
+ ICPU(INTEL_FAM6_SKYLAKE_MOBILE, &spt_reg_map),
+ ICPU(INTEL_FAM6_SKYLAKE_DESKTOP, &spt_reg_map),
+ ICPU(INTEL_FAM6_KABYLAKE_MOBILE, &spt_reg_map),
+ ICPU(INTEL_FAM6_KABYLAKE_DESKTOP, &spt_reg_map),
+ ICPU(INTEL_FAM6_CANNONLAKE_MOBILE, &cnp_reg_map),
{}
};
-static int pmc_core_probe(struct pci_dev *dev, const struct pci_device_id *id)
+MODULE_DEVICE_TABLE(x86cpu, intel_pmc_core_ids);
+
+static const struct pci_device_id pmc_pci_ids[] = {
+ { PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID), 0},
+ { 0, },
+};
+
+static int __init pmc_core_probe(void)
{
- struct device *ptr_dev = &dev->dev;
struct pmc_dev *pmcdev = &pmc;
const struct x86_cpu_id *cpu_id;
- const struct pmc_reg_map *map = (struct pmc_reg_map *)id->driver_data;
+ u64 slp_s0_addr;
int err;
cpu_id = x86_match_cpu(intel_pmc_core_ids);
- if (!cpu_id) {
- dev_dbg(&dev->dev, "PMC Core: cpuid mismatch.\n");
- return -EINVAL;
- }
-
- err = pcim_enable_device(dev);
- if (err < 0) {
- dev_dbg(&dev->dev, "PMC Core: failed to enable Power Management Controller.\n");
- return err;
- }
-
- err = pci_read_config_dword(dev,
- SPT_PMC_BASE_ADDR_OFFSET,
- &pmcdev->base_addr);
- if (err < 0) {
- dev_dbg(&dev->dev, "PMC Core: failed to read PCI config space.\n");
- return err;
- }
- pmcdev->base_addr &= PMC_BASE_ADDR_MASK;
- dev_dbg(&dev->dev, "PMC Core: PWRMBASE is %#x\n", pmcdev->base_addr);
-
- pmcdev->regbase = devm_ioremap_nocache(ptr_dev,
- pmcdev->base_addr,
- SPT_PMC_MMIO_REG_LEN);
- if (!pmcdev->regbase) {
- dev_dbg(&dev->dev, "PMC Core: ioremap failed.\n");
+ if (!cpu_id)
+ return -ENODEV;
+
+ pmcdev->map = (struct pmc_reg_map *)cpu_id->driver_data;
+
+ /*
+ * Coffeelake has CPU ID of Kabylake and Cannonlake PCH. So here
+ * Sunrisepoint PCH regmap can't be used. Use Cannonlake PCH regmap
+ * in this case.
+ */
+ if (!pci_dev_present(pmc_pci_ids))
+ pmcdev->map = &cnp_reg_map;
+
+ if (lpit_read_residency_count_address(&slp_s0_addr))
+ pmcdev->base_addr = PMC_BASE_ADDR_DEFAULT;
+ else
+ pmcdev->base_addr = slp_s0_addr - pmcdev->map->slp_s0_offset;
+
+ pmcdev->regbase = ioremap(pmcdev->base_addr,
+ pmcdev->map->regmap_length);
+ if (!pmcdev->regbase)
return -ENOMEM;
- }
mutex_init(&pmcdev->lock);
- pmcdev->map = map;
pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit();
err = pmc_core_dbgfs_register(pmcdev);
- if (err < 0)
- dev_warn(&dev->dev, "PMC Core: debugfs register failed.\n");
+ if (err < 0) {
+ pr_warn(" debugfs register failed.\n");
+ iounmap(pmcdev->regbase);
+ return err;
+ }
- pmc.has_slp_s0_res = true;
+ pr_info(" initialized\n");
return 0;
}
+module_init(pmc_core_probe)
-static struct pci_driver intel_pmc_core_driver = {
- .name = "intel_pmc_core",
- .id_table = pmc_pci_ids,
- .probe = pmc_core_probe,
-};
+static void __exit pmc_core_remove(void)
+{
+ struct pmc_dev *pmcdev = &pmc;
+
+ pmc_core_dbgfs_unregister(pmcdev);
+ mutex_destroy(&pmcdev->lock);
+ iounmap(pmcdev->regbase);
+}
+module_exit(pmc_core_remove)
-builtin_pci_driver(intel_pmc_core_driver);
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Intel PMC Core Driver");
diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h
index 3d225a9cc09f..5fa5f97870aa 100644
--- a/drivers/platform/x86/intel_pmc_core.h
+++ b/drivers/platform/x86/intel_pmc_core.h
@@ -21,9 +21,10 @@
#ifndef PMC_CORE_H
#define PMC_CORE_H
+#define PMC_BASE_ADDR_DEFAULT 0xFE000000
+
/* Sunrise Point Power Management Controller PCI Device ID */
#define SPT_PMC_PCI_DEVICE_ID 0x9d21
-
#define SPT_PMC_BASE_ADDR_OFFSET 0x48
#define SPT_PMC_SLP_S0_RES_COUNTER_OFFSET 0x13c
#define SPT_PMC_PM_CFG_OFFSET 0x18
@@ -122,6 +123,17 @@ enum ppfear_regs {
#define SPT_PMC_BIT_MPHY_CMN_LANE2 BIT(2)
#define SPT_PMC_BIT_MPHY_CMN_LANE3 BIT(3)
+/* Cannonlake Power Management Controller register offsets */
+#define CNP_PMC_SLP_S0_RES_COUNTER_OFFSET 0x193C
+#define CNP_PMC_LTR_IGNORE_OFFSET 0x1B0C
+#define CNP_PMC_PM_CFG_OFFSET 0x1818
+/* Cannonlake: PGD PFET Enable Ack Status Register(s) start */
+#define CNP_PMC_HOST_PPFEAR0A 0x1D90
+
+#define CNP_PMC_MMIO_REG_LEN 0x2000
+#define CNP_PPFEAR_NUM_ENTRIES 8
+#define CNP_PMC_READ_DISABLE_BIT 22
+
struct pmc_bit_map {
const char *name;
u32 bit_mask;
@@ -135,7 +147,6 @@ struct pmc_bit_map {
* @pll_sts: Maps name of PLL to corresponding bit status
* @slp_s0_offset: PWRMBASE offset to read SLP_S0 residency
* @ltr_ignore_offset: PWRMBASE offset to read/write LTR ignore bit
- * @base_address: Base address of PWRMBASE defined in BIOS writer guide
* @regmap_length: Length of memory to map from PWRMBASE address to access
* @ppfear0_offset: PWRMBASE offset to to read PPFEAR*
* @ppfear_buckets: Number of 8 bits blocks to read all IP blocks from
@@ -152,7 +163,6 @@ struct pmc_reg_map {
const struct pmc_bit_map *pll_sts;
const u32 slp_s0_offset;
const u32 ltr_ignore_offset;
- const u32 base_address;
const int regmap_length;
const u32 ppfear0_offset;
const int ppfear_buckets;
@@ -162,12 +172,14 @@ struct pmc_reg_map {
/**
* struct pmc_dev - pmc device structure
- * @base_addr: comtains pmc base address
+ * @base_addr: contains pmc base address
* @regbase: pointer to io-remapped memory location
- * @dbgfs_dir: path to debug fs interface
- * @feature_available: flag to indicate whether
- * the feature is available
- * on a particular platform or not.
+ * @map: pointer to pmc_reg_map struct that contains platform
+ * specific attributes
+ * @dbgfs_dir: path to debugfs interface
+ * @pmc_xram_read_bit: flag to indicate whether PMC XRAM shadow registers
+ * used to read MPHY PG and PLL status are available
+ * @mutex_lock: mutex to complete one transcation
*
* pmc_dev contains info about power management controller device.
*/
@@ -178,7 +190,6 @@ struct pmc_dev {
#if IS_ENABLED(CONFIG_DEBUG_FS)
struct dentry *dbgfs_dir;
#endif /* CONFIG_DEBUG_FS */
- bool has_slp_s0_res;
int pmc_xram_read_bit;
struct mutex lock; /* generic mutex lock for PMC Core */
};
diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/platform/x86/intel_pmc_ipc.c
index e03fa31446ca..e7edc8c63936 100644
--- a/drivers/platform/x86/intel_pmc_ipc.c
+++ b/drivers/platform/x86/intel_pmc_ipc.c
@@ -215,11 +215,11 @@ static inline int is_gcr_valid(u32 offset)
}
/**
- * intel_pmc_gcr_read() - Read PMC GCR register
+ * intel_pmc_gcr_read() - Read a 32-bit PMC GCR register
* @offset: offset of GCR register from GCR address base
* @data: data pointer for storing the register output
*
- * Reads the PMC GCR register of given offset.
+ * Reads the 32-bit PMC GCR register at given offset.
*
* Return: negative value on error or 0 on success.
*/
@@ -244,6 +244,35 @@ int intel_pmc_gcr_read(u32 offset, u32 *data)
EXPORT_SYMBOL_GPL(intel_pmc_gcr_read);
/**
+ * intel_pmc_gcr_read64() - Read a 64-bit PMC GCR register
+ * @offset: offset of GCR register from GCR address base
+ * @data: data pointer for storing the register output
+ *
+ * Reads the 64-bit PMC GCR register at given offset.
+ *
+ * Return: negative value on error or 0 on success.
+ */
+int intel_pmc_gcr_read64(u32 offset, u64 *data)
+{
+ int ret;
+
+ spin_lock(&ipcdev.gcr_lock);
+
+ ret = is_gcr_valid(offset);
+ if (ret < 0) {
+ spin_unlock(&ipcdev.gcr_lock);
+ return ret;
+ }
+
+ *data = readq(ipcdev.gcr_mem_base + offset);
+
+ spin_unlock(&ipcdev.gcr_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(intel_pmc_gcr_read64);
+
+/**
* intel_pmc_gcr_write() - Write PMC GCR register
* @offset: offset of GCR register from GCR address base
* @data: register update value
diff --git a/drivers/platform/x86/intel_telemetry_debugfs.c b/drivers/platform/x86/intel_telemetry_debugfs.c
index 4249e8267bbc..ffd0474b0531 100644
--- a/drivers/platform/x86/intel_telemetry_debugfs.c
+++ b/drivers/platform/x86/intel_telemetry_debugfs.c
@@ -23,7 +23,6 @@
*/
#include <linux/debugfs.h>
#include <linux/device.h>
-#include <linux/io.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/seq_file.h>
@@ -32,11 +31,10 @@
#include <asm/cpu_device_id.h>
#include <asm/intel-family.h>
#include <asm/intel_pmc_ipc.h>
-#include <asm/intel_punit_ipc.h>
#include <asm/intel_telemetry.h>
-#define DRIVER_NAME "telemetry_soc_debugfs"
-#define DRIVER_VERSION "1.0.0"
+#define DRIVER_NAME "telemetry_soc_debugfs"
+#define DRIVER_VERSION "1.0.0"
/* ApolloLake SoC Event-IDs */
#define TELEM_APL_PSS_PSTATES_ID 0x2802
@@ -98,10 +96,6 @@ static u32 suspend_shlw_ctr_temp, suspend_deep_ctr_temp;
static u64 suspend_shlw_res_temp, suspend_deep_res_temp;
struct telemetry_susp_stats {
- u32 shlw_swake_ctr;
- u32 deep_swake_ctr;
- u64 shlw_swake_res;
- u64 deep_swake_res;
u32 shlw_ctr;
u32 deep_ctr;
u64 shlw_res;
@@ -250,7 +244,6 @@ static struct telem_ioss_pg_info telem_apl_ioss_pg_data[] = {
{"PRTC", 25},
};
-
struct telemetry_debugfs_conf {
struct telemetry_susp_stats suspend_stats;
struct dentry *telemetry_dbg_dir;
@@ -385,7 +378,6 @@ static int telem_pss_states_show(struct seq_file *s, void *unused)
TELEM_APL_MASK_PCS_STATE;
}
-
TELEM_CHECK_AND_PARSE_EVTS(conf->pss_idle_id,
conf->pss_idle_evts - 1,
pss_idle, evtlog[index].telem_evtlog,
@@ -405,7 +397,6 @@ static int telem_pss_states_show(struct seq_file *s, void *unused)
conf->pcs_s0ix_blkd_data,
TELEM_MASK_BYTE);
-
TELEM_CHECK_AND_PARSE_EVTS(conf->pss_wakeup_id,
conf->pss_wakeup_evts,
pss_s0ix_wakeup,
@@ -498,7 +489,6 @@ static const struct file_operations telem_pss_ops = {
.release = single_release,
};
-
static int telem_ioss_states_show(struct seq_file *s, void *unused)
{
struct telemetry_evtlog evtlog[TELEM_MAX_OS_ALLOCATED_EVENTS];
@@ -598,19 +588,15 @@ static int telem_soc_states_show(struct seq_file *s, void *unused)
seq_printf(s, "S0IX Shallow\t\t\t %10u\t %10llu\n",
s0ix_shlw_ctr -
- conf->suspend_stats.shlw_ctr -
- conf->suspend_stats.shlw_swake_ctr,
+ conf->suspend_stats.shlw_ctr,
(u64)((s0ix_shlw_res -
- conf->suspend_stats.shlw_res -
- conf->suspend_stats.shlw_swake_res)*10/192));
+ conf->suspend_stats.shlw_res)*10/192));
seq_printf(s, "S0IX Deep\t\t\t %10u\t %10llu\n",
s0ix_deep_ctr -
- conf->suspend_stats.deep_ctr -
- conf->suspend_stats.deep_swake_ctr,
+ conf->suspend_stats.deep_ctr,
(u64)((s0ix_deep_res -
- conf->suspend_stats.deep_res -
- conf->suspend_stats.deep_swake_res)*10/192));
+ conf->suspend_stats.deep_res)*10/192));
seq_printf(s, "Suspend(With S0ixShallow)\t %10u\t %10llu\n",
conf->suspend_stats.shlw_ctr,
@@ -620,14 +606,8 @@ static int telem_soc_states_show(struct seq_file *s, void *unused)
conf->suspend_stats.deep_ctr,
(u64)(conf->suspend_stats.deep_res*10)/192);
- seq_printf(s, "Suspend(With Shallow-Wakes)\t %10u\t %10llu\n",
- conf->suspend_stats.shlw_swake_ctr +
- conf->suspend_stats.deep_swake_ctr,
- (u64)((conf->suspend_stats.shlw_swake_res +
- conf->suspend_stats.deep_swake_res)*10/192));
-
- seq_printf(s, "S0IX+Suspend Total\t\t %10u\t %10llu\n", s0ix_total_ctr,
- (u64)(s0ix_total_res*10/192));
+ seq_printf(s, "TOTAL S0IX\t\t\t %10u\t %10llu\n", s0ix_total_ctr,
+ (u64)(s0ix_total_res*10/192));
seq_puts(s, "\n-------------------------------------------------\n");
seq_puts(s, "\t\tDEVICE STATES\n");
seq_puts(s, "-------------------------------------------------\n");
@@ -772,7 +752,6 @@ static const struct file_operations telem_pss_trc_verb_ops = {
.release = single_release,
};
-
static int telem_ioss_trc_verb_show(struct seq_file *s, void *unused)
{
u32 verbosity;
@@ -890,28 +869,45 @@ static int pm_suspend_exit_cb(void)
goto out;
}
+ /*
+ * Due to some design limitations in the firmware, sometimes the
+ * counters do not get updated by the time we reach here. As a
+ * workaround, we try to see if this was a genuine case of sleep
+ * failure or not by cross-checking from PMC GCR registers directly.
+ */
+ if (suspend_shlw_ctr_exit == suspend_shlw_ctr_temp &&
+ suspend_deep_ctr_exit == suspend_deep_ctr_temp) {
+ ret = intel_pmc_gcr_read64(PMC_GCR_TELEM_SHLW_S0IX_REG,
+ &suspend_shlw_res_exit);
+ if (ret < 0)
+ goto out;
+
+ ret = intel_pmc_gcr_read64(PMC_GCR_TELEM_DEEP_S0IX_REG,
+ &suspend_deep_res_exit);
+ if (ret < 0)
+ goto out;
+
+ if (suspend_shlw_res_exit > suspend_shlw_res_temp)
+ suspend_shlw_ctr_exit++;
+
+ if (suspend_deep_res_exit > suspend_deep_res_temp)
+ suspend_deep_ctr_exit++;
+ }
+
suspend_shlw_ctr_exit -= suspend_shlw_ctr_temp;
suspend_deep_ctr_exit -= suspend_deep_ctr_temp;
suspend_shlw_res_exit -= suspend_shlw_res_temp;
suspend_deep_res_exit -= suspend_deep_res_temp;
- if (suspend_shlw_ctr_exit == 1) {
+ if (suspend_shlw_ctr_exit != 0) {
conf->suspend_stats.shlw_ctr +=
suspend_shlw_ctr_exit;
conf->suspend_stats.shlw_res +=
suspend_shlw_res_exit;
}
- /* Shallow Wakes Case */
- else if (suspend_shlw_ctr_exit > 1) {
- conf->suspend_stats.shlw_swake_ctr +=
- suspend_shlw_ctr_exit;
- conf->suspend_stats.shlw_swake_res +=
- suspend_shlw_res_exit;
- }
-
- if (suspend_deep_ctr_exit == 1) {
+ if (suspend_deep_ctr_exit != 0) {
conf->suspend_stats.deep_ctr +=
suspend_deep_ctr_exit;
@@ -919,15 +915,6 @@ static int pm_suspend_exit_cb(void)
suspend_deep_res_exit;
}
- /* Shallow Wakes Case */
- else if (suspend_deep_ctr_exit > 1) {
- conf->suspend_stats.deep_swake_ctr +=
- suspend_deep_ctr_exit;
-
- conf->suspend_stats.deep_swake_res +=
- suspend_deep_res_exit;
- }
-
out:
suspend_prep_ok = 0;
return NOTIFY_OK;
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
index 504256c3660d..27de29961f5e 100644
--- a/drivers/platform/x86/mlx-platform.c
+++ b/drivers/platform/x86/mlx-platform.c
@@ -35,20 +35,31 @@
#include <linux/dmi.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
+#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/platform_data/i2c-mux-reg.h>
-#include <linux/platform_data/mlxcpld-hotplug.h>
+#include <linux/platform_data/mlxreg.h>
+#include <linux/regmap.h>
#define MLX_PLAT_DEVICE_NAME "mlxplat"
/* LPC bus IO offsets */
#define MLXPLAT_CPLD_LPC_I2C_BASE_ADRR 0x2000
#define MLXPLAT_CPLD_LPC_REG_BASE_ADRR 0x2500
-#define MLXPLAT_CPLD_LPC_REG_AGGR_ADRR 0x253a
-#define MLXPLAT_CPLD_LPC_REG_PSU_ADRR 0x2558
-#define MLXPLAT_CPLD_LPC_REG_PWR_ADRR 0x2564
-#define MLXPLAT_CPLD_LPC_REG_FAN_ADRR 0x2588
+#define MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET 0x3a
+#define MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET 0x3b
+#define MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET 0x40
+#define MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET 0x41
+#define MLXPLAT_CPLD_LPC_REG_PSU_OFFSET 0x58
+#define MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET 0x59
+#define MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET 0x5a
+#define MLXPLAT_CPLD_LPC_REG_PWR_OFFSET 0x64
+#define MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET 0x65
+#define MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET 0x66
+#define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88
+#define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89
+#define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a
#define MLXPLAT_CPLD_LPC_IO_RANGE 0x100
#define MLXPLAT_CPLD_LPC_I2C_CH1_OFF 0xdb
#define MLXPLAT_CPLD_LPC_I2C_CH2_OFF 0xda
@@ -81,6 +92,7 @@
/* mlxplat_priv - platform private data
* @pdev_i2c - i2c controller platform device
* @pdev_mux - array of mux platform devices
+ * @pdev_hotplug - hotplug platform devices
*/
struct mlxplat_priv {
struct platform_device *pdev_i2c;
@@ -138,86 +150,264 @@ static struct i2c_mux_reg_platform_data mlxplat_mux_data[] = {
};
/* Platform hotplug devices */
-static struct mlxcpld_hotplug_device mlxplat_mlxcpld_psu[] = {
+static struct i2c_board_info mlxplat_mlxcpld_psu[] = {
{
- .brdinfo = { I2C_BOARD_INFO("24c02", 0x51) },
- .bus = 10,
+ I2C_BOARD_INFO("24c02", 0x51),
},
{
- .brdinfo = { I2C_BOARD_INFO("24c02", 0x50) },
- .bus = 10,
+ I2C_BOARD_INFO("24c02", 0x50),
},
};
-static struct mlxcpld_hotplug_device mlxplat_mlxcpld_pwr[] = {
+static struct i2c_board_info mlxplat_mlxcpld_pwr[] = {
{
- .brdinfo = { I2C_BOARD_INFO("dps460", 0x59) },
- .bus = 10,
+ I2C_BOARD_INFO("dps460", 0x59),
},
{
- .brdinfo = { I2C_BOARD_INFO("dps460", 0x58) },
- .bus = 10,
+ I2C_BOARD_INFO("dps460", 0x58),
},
};
-static struct mlxcpld_hotplug_device mlxplat_mlxcpld_fan[] = {
+static struct i2c_board_info mlxplat_mlxcpld_fan[] = {
{
- .brdinfo = { I2C_BOARD_INFO("24c32", 0x50) },
- .bus = 11,
+ I2C_BOARD_INFO("24c32", 0x50),
},
{
- .brdinfo = { I2C_BOARD_INFO("24c32", 0x50) },
- .bus = 12,
+ I2C_BOARD_INFO("24c32", 0x50),
},
{
- .brdinfo = { I2C_BOARD_INFO("24c32", 0x50) },
- .bus = 13,
+ I2C_BOARD_INFO("24c32", 0x50),
},
{
- .brdinfo = { I2C_BOARD_INFO("24c32", 0x50) },
- .bus = 14,
+ I2C_BOARD_INFO("24c32", 0x50),
},
};
/* Platform hotplug default data */
+static struct mlxreg_core_data mlxplat_mlxcpld_default_psu_items_data[] = {
+ {
+ .label = "psu1",
+ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+ .mask = BIT(0),
+ .hpdev.brdinfo = &mlxplat_mlxcpld_psu[0],
+ .hpdev.nr = 10,
+ },
+ {
+ .label = "psu2",
+ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+ .mask = BIT(1),
+ .hpdev.brdinfo = &mlxplat_mlxcpld_psu[1],
+ .hpdev.nr = 10,
+ },
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_items_data[] = {
+ {
+ .label = "pwr1",
+ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+ .mask = BIT(0),
+ .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[0],
+ .hpdev.nr = 10,
+ },
+ {
+ .label = "pwr2",
+ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+ .mask = BIT(1),
+ .hpdev.brdinfo = &mlxplat_mlxcpld_pwr[1],
+ .hpdev.nr = 10,
+ },
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = {
+ {
+ .label = "fan1",
+ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+ .mask = BIT(0),
+ .hpdev.brdinfo = &mlxplat_mlxcpld_fan[0],
+ .hpdev.nr = 11,
+ },
+ {
+ .label = "fan2",
+ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+ .mask = BIT(1),
+ .hpdev.brdinfo = &mlxplat_mlxcpld_fan[1],
+ .hpdev.nr = 12,
+ },
+ {
+ .label = "fan3",
+ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+ .mask = BIT(2),
+ .hpdev.brdinfo = &mlxplat_mlxcpld_fan[2],
+ .hpdev.nr = 13,
+ },
+ {
+ .label = "fan4",
+ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+ .mask = BIT(3),
+ .hpdev.brdinfo = &mlxplat_mlxcpld_fan[3],
+ .hpdev.nr = 14,
+ },
+};
+
+static struct mlxreg_core_item mlxplat_mlxcpld_default_items[] = {
+ {
+ .data = mlxplat_mlxcpld_default_psu_items_data,
+ .aggr_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF,
+ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
+ .mask = MLXPLAT_CPLD_PSU_MASK,
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_psu),
+ .inversed = 1,
+ .health = false,
+ },
+ {
+ .data = mlxplat_mlxcpld_default_pwr_items_data,
+ .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
+ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+ .mask = MLXPLAT_CPLD_PWR_MASK,
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
+ .inversed = 0,
+ .health = false,
+ },
+ {
+ .data = mlxplat_mlxcpld_default_fan_items_data,
+ .aggr_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
+ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
+ .mask = MLXPLAT_CPLD_FAN_MASK,
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
+ .inversed = 1,
+ .health = false,
+ },
+};
+
static
-struct mlxcpld_hotplug_platform_data mlxplat_mlxcpld_default_data = {
- .top_aggr_offset = MLXPLAT_CPLD_LPC_REG_AGGR_ADRR,
- .top_aggr_mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
- .top_aggr_psu_mask = MLXPLAT_CPLD_AGGR_PSU_MASK_DEF,
- .psu_reg_offset = MLXPLAT_CPLD_LPC_REG_PSU_ADRR,
- .psu_mask = MLXPLAT_CPLD_PSU_MASK,
- .psu_count = ARRAY_SIZE(mlxplat_mlxcpld_psu),
- .psu = mlxplat_mlxcpld_psu,
- .top_aggr_pwr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
- .pwr_reg_offset = MLXPLAT_CPLD_LPC_REG_PWR_ADRR,
- .pwr_mask = MLXPLAT_CPLD_PWR_MASK,
- .pwr_count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
- .pwr = mlxplat_mlxcpld_pwr,
- .top_aggr_fan_mask = MLXPLAT_CPLD_AGGR_FAN_MASK_DEF,
- .fan_reg_offset = MLXPLAT_CPLD_LPC_REG_FAN_ADRR,
- .fan_mask = MLXPLAT_CPLD_FAN_MASK,
- .fan_count = ARRAY_SIZE(mlxplat_mlxcpld_fan),
- .fan = mlxplat_mlxcpld_fan,
+struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_default_data = {
+ .items = mlxplat_mlxcpld_default_items,
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_default_items),
+ .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
+ .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
};
/* Platform hotplug MSN21xx system family data */
+static struct mlxreg_core_item mlxplat_mlxcpld_msn21xx_items[] = {
+ {
+ .data = mlxplat_mlxcpld_default_pwr_items_data,
+ .aggr_mask = MLXPLAT_CPLD_AGGR_PWR_MASK_DEF,
+ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
+ .mask = MLXPLAT_CPLD_PWR_MASK,
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
+ .inversed = 0,
+ .health = false,
+ },
+};
+
static
-struct mlxcpld_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
- .top_aggr_offset = MLXPLAT_CPLD_LPC_REG_AGGR_ADRR,
- .top_aggr_mask = MLXPLAT_CPLD_AGGR_MASK_MSN21XX,
- .top_aggr_pwr_mask = MLXPLAT_CPLD_AGGR_MASK_MSN21XX,
- .pwr_reg_offset = MLXPLAT_CPLD_LPC_REG_PWR_ADRR,
- .pwr_mask = MLXPLAT_CPLD_PWR_MASK,
- .pwr_count = ARRAY_SIZE(mlxplat_mlxcpld_pwr),
+struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_msn21xx_data = {
+ .items = mlxplat_mlxcpld_msn21xx_items,
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_msn21xx_items),
+ .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
+ .mask = MLXPLAT_CPLD_AGGR_MASK_DEF,
+};
+
+static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+ return true;
+ }
+ return false;
+}
+
+static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+ return true;
+ }
+ return false;
+}
+
+static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_AGGR_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_AGGRLO_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PSU_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PSU_EVENT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PSU_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PWR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PWR_EVENT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
+ return true;
+ }
+ return false;
+}
+
+struct mlxplat_mlxcpld_regmap_context {
+ void __iomem *base;
+};
+
+static struct mlxplat_mlxcpld_regmap_context mlxplat_mlxcpld_regmap_ctx;
+
+static int
+mlxplat_mlxcpld_reg_read(void *context, unsigned int reg, unsigned int *val)
+{
+ struct mlxplat_mlxcpld_regmap_context *ctx = context;
+
+ *val = ioread8(ctx->base + reg);
+ return 0;
+}
+
+static int
+mlxplat_mlxcpld_reg_write(void *context, unsigned int reg, unsigned int val)
+{
+ struct mlxplat_mlxcpld_regmap_context *ctx = context;
+
+ iowrite8(val, ctx->base + reg);
+ return 0;
+}
+
+static const struct regmap_config mlxplat_mlxcpld_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = 255,
+ .cache_type = REGCACHE_FLAT,
+ .writeable_reg = mlxplat_mlxcpld_writeable_reg,
+ .readable_reg = mlxplat_mlxcpld_readable_reg,
+ .volatile_reg = mlxplat_mlxcpld_volatile_reg,
+ .reg_read = mlxplat_mlxcpld_reg_read,
+ .reg_write = mlxplat_mlxcpld_reg_write,
};
static struct resource mlxplat_mlxcpld_resources[] = {
- [0] = DEFINE_RES_IRQ_NAMED(17, "mlxcpld-hotplug"),
+ [0] = DEFINE_RES_IRQ_NAMED(17, "mlxreg-hotplug"),
};
static struct platform_device *mlxplat_dev;
-static struct mlxcpld_hotplug_platform_data *mlxplat_hotplug;
+static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
{
@@ -286,6 +476,8 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
{ }
};
+MODULE_DEVICE_TABLE(dmi, mlxplat_dmi_table);
+
static int __init mlxplat_init(void)
{
struct mlxplat_priv *priv;
@@ -328,8 +520,23 @@ static int __init mlxplat_init(void)
}
}
+ mlxplat_mlxcpld_regmap_ctx.base = devm_ioport_map(&mlxplat_dev->dev,
+ mlxplat_lpc_resources[1].start, 1);
+ if (!mlxplat_mlxcpld_regmap_ctx.base) {
+ err = -ENOMEM;
+ goto fail_platform_mux_register;
+ }
+
+ mlxplat_hotplug->regmap = devm_regmap_init(&mlxplat_dev->dev, NULL,
+ &mlxplat_mlxcpld_regmap_ctx,
+ &mlxplat_mlxcpld_regmap_config);
+ if (IS_ERR(mlxplat_hotplug->regmap)) {
+ err = PTR_ERR(mlxplat_hotplug->regmap);
+ goto fail_platform_mux_register;
+ }
+
priv->pdev_hotplug = platform_device_register_resndata(
- &mlxplat_dev->dev, "mlxcpld-hotplug",
+ &mlxplat_dev->dev, "mlxreg-hotplug",
PLATFORM_DEVID_NONE,
mlxplat_mlxcpld_resources,
ARRAY_SIZE(mlxplat_mlxcpld_resources),
@@ -339,8 +546,16 @@ static int __init mlxplat_init(void)
goto fail_platform_mux_register;
}
+ /* Sync registers with hardware. */
+ regcache_mark_dirty(mlxplat_hotplug->regmap);
+ err = regcache_sync(mlxplat_hotplug->regmap);
+ if (err)
+ goto fail_platform_hotplug_register;
+
return 0;
+fail_platform_hotplug_register:
+ platform_device_unregister(priv->pdev_hotplug);
fail_platform_mux_register:
while (--i >= 0)
platform_device_unregister(priv->pdev_mux[i]);
@@ -370,8 +585,3 @@ module_exit(mlxplat_exit);
MODULE_AUTHOR("Vadim Pasternak (vadimp@mellanox.com)");
MODULE_DESCRIPTION("Mellanox platform driver");
MODULE_LICENSE("Dual BSD/GPL");
-MODULE_ALIAS("dmi:*:*Mellanox*:MSN24*:");
-MODULE_ALIAS("dmi:*:*Mellanox*:MSN27*:");
-MODULE_ALIAS("dmi:*:*Mellanox*:MSB*:");
-MODULE_ALIAS("dmi:*:*Mellanox*:MSX*:");
-MODULE_ALIAS("dmi:*:*Mellanox*:MSN21*:");
diff --git a/drivers/platform/x86/mlxcpld-hotplug.c b/drivers/platform/x86/mlxcpld-hotplug.c
deleted file mode 100644
index aff3686b3b37..000000000000
--- a/drivers/platform/x86/mlxcpld-hotplug.c
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * drivers/platform/x86/mlxcpld-hotplug.c
- * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
- * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
- *
- * 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 names of the copyright holders 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") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/bitops.h>
-#include <linux/device.h>
-#include <linux/hwmon.h>
-#include <linux/hwmon-sysfs.h>
-#include <linux/i2c.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_data/mlxcpld-hotplug.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/workqueue.h>
-
-/* Offset of event and mask registers from status register */
-#define MLXCPLD_HOTPLUG_EVENT_OFF 1
-#define MLXCPLD_HOTPLUG_MASK_OFF 2
-#define MLXCPLD_HOTPLUG_AGGR_MASK_OFF 1
-
-#define MLXCPLD_HOTPLUG_ATTRS_NUM 8
-
-/**
- * enum mlxcpld_hotplug_attr_type - sysfs attributes for hotplug events:
- * @MLXCPLD_HOTPLUG_ATTR_TYPE_PSU: power supply unit attribute;
- * @MLXCPLD_HOTPLUG_ATTR_TYPE_PWR: power cable attribute;
- * @MLXCPLD_HOTPLUG_ATTR_TYPE_FAN: FAN drawer attribute;
- */
-enum mlxcpld_hotplug_attr_type {
- MLXCPLD_HOTPLUG_ATTR_TYPE_PSU,
- MLXCPLD_HOTPLUG_ATTR_TYPE_PWR,
- MLXCPLD_HOTPLUG_ATTR_TYPE_FAN,
-};
-
-/**
- * struct mlxcpld_hotplug_priv_data - platform private data:
- * @irq: platform interrupt number;
- * @pdev: platform device;
- * @plat: platform data;
- * @hwmon: hwmon device;
- * @mlxcpld_hotplug_attr: sysfs attributes array;
- * @mlxcpld_hotplug_dev_attr: sysfs sensor device attribute array;
- * @group: sysfs attribute group;
- * @groups: list of sysfs attribute group for hwmon registration;
- * @dwork: delayed work template;
- * @lock: spin lock;
- * @aggr_cache: last value of aggregation register status;
- * @psu_cache: last value of PSU register status;
- * @pwr_cache: last value of power register status;
- * @fan_cache: last value of FAN register status;
- */
-struct mlxcpld_hotplug_priv_data {
- int irq;
- struct platform_device *pdev;
- struct mlxcpld_hotplug_platform_data *plat;
- struct device *hwmon;
- struct attribute *mlxcpld_hotplug_attr[MLXCPLD_HOTPLUG_ATTRS_NUM + 1];
- struct sensor_device_attribute_2
- mlxcpld_hotplug_dev_attr[MLXCPLD_HOTPLUG_ATTRS_NUM];
- struct attribute_group group;
- const struct attribute_group *groups[2];
- struct delayed_work dwork;
- spinlock_t lock;
- u8 aggr_cache;
- u8 psu_cache;
- u8 pwr_cache;
- u8 fan_cache;
-};
-
-static ssize_t mlxcpld_hotplug_attr_show(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct mlxcpld_hotplug_priv_data *priv = platform_get_drvdata(pdev);
- int index = to_sensor_dev_attr_2(attr)->index;
- int nr = to_sensor_dev_attr_2(attr)->nr;
- u8 reg_val = 0;
-
- switch (nr) {
- case MLXCPLD_HOTPLUG_ATTR_TYPE_PSU:
- /* Bit = 0 : PSU is present. */
- reg_val = !!!(inb(priv->plat->psu_reg_offset) & BIT(index));
- break;
-
- case MLXCPLD_HOTPLUG_ATTR_TYPE_PWR:
- /* Bit = 1 : power cable is attached. */
- reg_val = !!(inb(priv->plat->pwr_reg_offset) & BIT(index %
- priv->plat->pwr_count));
- break;
-
- case MLXCPLD_HOTPLUG_ATTR_TYPE_FAN:
- /* Bit = 0 : FAN is present. */
- reg_val = !!!(inb(priv->plat->fan_reg_offset) & BIT(index %
- priv->plat->fan_count));
- break;
- }
-
- return sprintf(buf, "%u\n", reg_val);
-}
-
-#define PRIV_ATTR(i) priv->mlxcpld_hotplug_attr[i]
-#define PRIV_DEV_ATTR(i) priv->mlxcpld_hotplug_dev_attr[i]
-static int mlxcpld_hotplug_attr_init(struct mlxcpld_hotplug_priv_data *priv)
-{
- int num_attrs = priv->plat->psu_count + priv->plat->pwr_count +
- priv->plat->fan_count;
- int i;
-
- priv->group.attrs = devm_kzalloc(&priv->pdev->dev, num_attrs *
- sizeof(struct attribute *),
- GFP_KERNEL);
- if (!priv->group.attrs)
- return -ENOMEM;
-
- for (i = 0; i < num_attrs; i++) {
- PRIV_ATTR(i) = &PRIV_DEV_ATTR(i).dev_attr.attr;
-
- if (i < priv->plat->psu_count) {
- PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
- GFP_KERNEL, "psu%u", i + 1);
- PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_PSU;
- } else if (i < priv->plat->psu_count + priv->plat->pwr_count) {
- PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
- GFP_KERNEL, "pwr%u", i %
- priv->plat->pwr_count + 1);
- PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_PWR;
- } else {
- PRIV_ATTR(i)->name = devm_kasprintf(&priv->pdev->dev,
- GFP_KERNEL, "fan%u", i %
- priv->plat->fan_count + 1);
- PRIV_DEV_ATTR(i).nr = MLXCPLD_HOTPLUG_ATTR_TYPE_FAN;
- }
-
- if (!PRIV_ATTR(i)->name) {
- dev_err(&priv->pdev->dev, "Memory allocation failed for sysfs attribute %d.\n",
- i + 1);
- return -ENOMEM;
- }
-
- PRIV_DEV_ATTR(i).dev_attr.attr.name = PRIV_ATTR(i)->name;
- PRIV_DEV_ATTR(i).dev_attr.attr.mode = S_IRUGO;
- PRIV_DEV_ATTR(i).dev_attr.show = mlxcpld_hotplug_attr_show;
- PRIV_DEV_ATTR(i).index = i;
- sysfs_attr_init(&PRIV_DEV_ATTR(i).dev_attr.attr);
- }
-
- priv->group.attrs = priv->mlxcpld_hotplug_attr;
- priv->groups[0] = &priv->group;
- priv->groups[1] = NULL;
-
- return 0;
-}
-
-static int mlxcpld_hotplug_device_create(struct device *dev,
- struct mlxcpld_hotplug_device *item)
-{
- item->adapter = i2c_get_adapter(item->bus);
- if (!item->adapter) {
- dev_err(dev, "Failed to get adapter for bus %d\n",
- item->bus);
- return -EFAULT;
- }
-
- item->client = i2c_new_device(item->adapter, &item->brdinfo);
- if (!item->client) {
- dev_err(dev, "Failed to create client %s at bus %d at addr 0x%02x\n",
- item->brdinfo.type, item->bus, item->brdinfo.addr);
- i2c_put_adapter(item->adapter);
- item->adapter = NULL;
- return -EFAULT;
- }
-
- return 0;
-}
-
-static void mlxcpld_hotplug_device_destroy(struct mlxcpld_hotplug_device *item)
-{
- if (item->client) {
- i2c_unregister_device(item->client);
- item->client = NULL;
- }
-
- if (item->adapter) {
- i2c_put_adapter(item->adapter);
- item->adapter = NULL;
- }
-}
-
-static inline void
-mlxcpld_hotplug_work_helper(struct device *dev,
- struct mlxcpld_hotplug_device *item, u8 is_inverse,
- u16 offset, u8 mask, u8 *cache)
-{
- u8 val, asserted;
- int bit;
-
- /* Mask event. */
- outb(0, offset + MLXCPLD_HOTPLUG_MASK_OFF);
- /* Read status. */
- val = inb(offset) & mask;
- asserted = *cache ^ val;
- *cache = val;
-
- /*
- * Validate if item related to received signal type is valid.
- * It should never happen, excepted the situation when some
- * piece of hardware is broken. In such situation just produce
- * error message and return. Caller must continue to handle the
- * signals from other devices if any.
- */
- if (unlikely(!item)) {
- dev_err(dev, "False signal is received: register at offset 0x%02x, mask 0x%02x.\n",
- offset, mask);
- return;
- }
-
- for_each_set_bit(bit, (unsigned long *)&asserted, 8) {
- if (val & BIT(bit)) {
- if (is_inverse)
- mlxcpld_hotplug_device_destroy(item + bit);
- else
- mlxcpld_hotplug_device_create(dev, item + bit);
- } else {
- if (is_inverse)
- mlxcpld_hotplug_device_create(dev, item + bit);
- else
- mlxcpld_hotplug_device_destroy(item + bit);
- }
- }
-
- /* Acknowledge event. */
- outb(0, offset + MLXCPLD_HOTPLUG_EVENT_OFF);
- /* Unmask event. */
- outb(mask, offset + MLXCPLD_HOTPLUG_MASK_OFF);
-}
-
-/*
- * mlxcpld_hotplug_work_handler - performs traversing of CPLD interrupt
- * registers according to the below hierarchy schema:
- *
- * Aggregation registers (status/mask)
- * PSU registers: *---*
- * *-----------------* | |
- * |status/event/mask|----->| * |
- * *-----------------* | |
- * Power registers: | |
- * *-----------------* | |
- * |status/event/mask|----->| * |---> CPU
- * *-----------------* | |
- * FAN registers:
- * *-----------------* | |
- * |status/event/mask|----->| * |
- * *-----------------* | |
- * *---*
- * In case some system changed are detected: FAN in/out, PSU in/out, power
- * cable attached/detached, relevant device is created or destroyed.
- */
-static void mlxcpld_hotplug_work_handler(struct work_struct *work)
-{
- struct mlxcpld_hotplug_priv_data *priv = container_of(work,
- struct mlxcpld_hotplug_priv_data, dwork.work);
- u8 val, aggr_asserted;
- unsigned long flags;
-
- /* Mask aggregation event. */
- outb(0, priv->plat->top_aggr_offset + MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
- /* Read aggregation status. */
- val = inb(priv->plat->top_aggr_offset) & priv->plat->top_aggr_mask;
- aggr_asserted = priv->aggr_cache ^ val;
- priv->aggr_cache = val;
-
- /* Handle PSU configuration changes. */
- if (aggr_asserted & priv->plat->top_aggr_psu_mask)
- mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->psu,
- 1, priv->plat->psu_reg_offset,
- priv->plat->psu_mask,
- &priv->psu_cache);
-
- /* Handle power cable configuration changes. */
- if (aggr_asserted & priv->plat->top_aggr_pwr_mask)
- mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->pwr,
- 0, priv->plat->pwr_reg_offset,
- priv->plat->pwr_mask,
- &priv->pwr_cache);
-
- /* Handle FAN configuration changes. */
- if (aggr_asserted & priv->plat->top_aggr_fan_mask)
- mlxcpld_hotplug_work_helper(&priv->pdev->dev, priv->plat->fan,
- 1, priv->plat->fan_reg_offset,
- priv->plat->fan_mask,
- &priv->fan_cache);
-
- if (aggr_asserted) {
- spin_lock_irqsave(&priv->lock, flags);
-
- /*
- * It is possible, that some signals have been inserted, while
- * interrupt has been masked by mlxcpld_hotplug_work_handler.
- * In this case such signals will be missed. In order to handle
- * these signals delayed work is canceled and work task
- * re-scheduled for immediate execution. It allows to handle
- * missed signals, if any. In other case work handler just
- * validates that no new signals have been received during
- * masking.
- */
- cancel_delayed_work(&priv->dwork);
- schedule_delayed_work(&priv->dwork, 0);
-
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return;
- }
-
- /* Unmask aggregation event (no need acknowledge). */
- outb(priv->plat->top_aggr_mask, priv->plat->top_aggr_offset +
- MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
-}
-
-static void mlxcpld_hotplug_set_irq(struct mlxcpld_hotplug_priv_data *priv)
-{
- /* Clear psu presense event. */
- outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
- /* Set psu initial status as mask and unmask psu event. */
- priv->psu_cache = priv->plat->psu_mask;
- outb(priv->plat->psu_mask, priv->plat->psu_reg_offset +
- MLXCPLD_HOTPLUG_MASK_OFF);
-
- /* Clear power cable event. */
- outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
- /* Keep power initial status as zero and unmask power event. */
- outb(priv->plat->pwr_mask, priv->plat->pwr_reg_offset +
- MLXCPLD_HOTPLUG_MASK_OFF);
-
- /* Clear fan presense event. */
- outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
- /* Set fan initial status as mask and unmask fan event. */
- priv->fan_cache = priv->plat->fan_mask;
- outb(priv->plat->fan_mask, priv->plat->fan_reg_offset +
- MLXCPLD_HOTPLUG_MASK_OFF);
-
- /* Keep aggregation initial status as zero and unmask events. */
- outb(priv->plat->top_aggr_mask, priv->plat->top_aggr_offset +
- MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
-
- /* Invoke work handler for initializing hot plug devices setting. */
- mlxcpld_hotplug_work_handler(&priv->dwork.work);
-
- enable_irq(priv->irq);
-}
-
-static void mlxcpld_hotplug_unset_irq(struct mlxcpld_hotplug_priv_data *priv)
-{
- int i;
-
- disable_irq(priv->irq);
- cancel_delayed_work_sync(&priv->dwork);
-
- /* Mask aggregation event. */
- outb(0, priv->plat->top_aggr_offset + MLXCPLD_HOTPLUG_AGGR_MASK_OFF);
-
- /* Mask psu presense event. */
- outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF);
- /* Clear psu presense event. */
- outb(0, priv->plat->psu_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
-
- /* Mask power cable event. */
- outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF);
- /* Clear power cable event. */
- outb(0, priv->plat->pwr_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
-
- /* Mask fan presense event. */
- outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_MASK_OFF);
- /* Clear fan presense event. */
- outb(0, priv->plat->fan_reg_offset + MLXCPLD_HOTPLUG_EVENT_OFF);
-
- /* Remove all the attached devices. */
- for (i = 0; i < priv->plat->psu_count; i++)
- mlxcpld_hotplug_device_destroy(priv->plat->psu + i);
-
- for (i = 0; i < priv->plat->pwr_count; i++)
- mlxcpld_hotplug_device_destroy(priv->plat->pwr + i);
-
- for (i = 0; i < priv->plat->fan_count; i++)
- mlxcpld_hotplug_device_destroy(priv->plat->fan + i);
-}
-
-static irqreturn_t mlxcpld_hotplug_irq_handler(int irq, void *dev)
-{
- struct mlxcpld_hotplug_priv_data *priv =
- (struct mlxcpld_hotplug_priv_data *)dev;
-
- /* Schedule work task for immediate execution.*/
- schedule_delayed_work(&priv->dwork, 0);
-
- return IRQ_HANDLED;
-}
-
-static int mlxcpld_hotplug_probe(struct platform_device *pdev)
-{
- struct mlxcpld_hotplug_platform_data *pdata;
- struct mlxcpld_hotplug_priv_data *priv;
- int err;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- dev_err(&pdev->dev, "Failed to get platform data.\n");
- return -EINVAL;
- }
-
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->pdev = pdev;
- priv->plat = pdata;
-
- priv->irq = platform_get_irq(pdev, 0);
- if (priv->irq < 0) {
- dev_err(&pdev->dev, "Failed to get platform irq: %d\n",
- priv->irq);
- return priv->irq;
- }
-
- err = devm_request_irq(&pdev->dev, priv->irq,
- mlxcpld_hotplug_irq_handler, 0, pdev->name,
- priv);
- if (err) {
- dev_err(&pdev->dev, "Failed to request irq: %d\n", err);
- return err;
- }
- disable_irq(priv->irq);
-
- INIT_DELAYED_WORK(&priv->dwork, mlxcpld_hotplug_work_handler);
- spin_lock_init(&priv->lock);
-
- err = mlxcpld_hotplug_attr_init(priv);
- if (err) {
- dev_err(&pdev->dev, "Failed to allocate attributes: %d\n", err);
- return err;
- }
-
- priv->hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
- "mlxcpld_hotplug", priv, priv->groups);
- if (IS_ERR(priv->hwmon)) {
- dev_err(&pdev->dev, "Failed to register hwmon device %ld\n",
- PTR_ERR(priv->hwmon));
- return PTR_ERR(priv->hwmon);
- }
-
- platform_set_drvdata(pdev, priv);
-
- /* Perform initial interrupts setup. */
- mlxcpld_hotplug_set_irq(priv);
-
- return 0;
-}
-
-static int mlxcpld_hotplug_remove(struct platform_device *pdev)
-{
- struct mlxcpld_hotplug_priv_data *priv = platform_get_drvdata(pdev);
-
- /* Clean interrupts setup. */
- mlxcpld_hotplug_unset_irq(priv);
-
- return 0;
-}
-
-static struct platform_driver mlxcpld_hotplug_driver = {
- .driver = {
- .name = "mlxcpld-hotplug",
- },
- .probe = mlxcpld_hotplug_probe,
- .remove = mlxcpld_hotplug_remove,
-};
-
-module_platform_driver(mlxcpld_hotplug_driver);
-
-MODULE_AUTHOR("Vadim Pasternak <vadimp@mellanox.com>");
-MODULE_DESCRIPTION("Mellanox CPLD hotplug platform driver");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_ALIAS("platform:mlxcpld-hotplug");
diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c
index 77bac859342d..8f018b3f3cd4 100644
--- a/drivers/platform/x86/pmc_atom.c
+++ b/drivers/platform/x86/pmc_atom.c
@@ -309,17 +309,7 @@ static int pmc_dev_state_show(struct seq_file *s, void *unused)
return 0;
}
-static int pmc_dev_state_open(struct inode *inode, struct file *file)
-{
- return single_open(file, pmc_dev_state_show, inode->i_private);
-}
-
-static const struct file_operations pmc_dev_state_ops = {
- .open = pmc_dev_state_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pmc_dev_state);
static int pmc_pss_state_show(struct seq_file *s, void *unused)
{
@@ -336,17 +326,7 @@ static int pmc_pss_state_show(struct seq_file *s, void *unused)
return 0;
}
-static int pmc_pss_state_open(struct inode *inode, struct file *file)
-{
- return single_open(file, pmc_pss_state_show, inode->i_private);
-}
-
-static const struct file_operations pmc_pss_state_ops = {
- .open = pmc_pss_state_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pmc_pss_state);
static int pmc_sleep_tmr_show(struct seq_file *s, void *unused)
{
@@ -367,17 +347,7 @@ static int pmc_sleep_tmr_show(struct seq_file *s, void *unused)
return 0;
}
-static int pmc_sleep_tmr_open(struct inode *inode, struct file *file)
-{
- return single_open(file, pmc_sleep_tmr_show, inode->i_private);
-}
-
-static const struct file_operations pmc_sleep_tmr_ops = {
- .open = pmc_sleep_tmr_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(pmc_sleep_tmr);
static void pmc_dbgfs_unregister(struct pmc_dev *pmc)
{
@@ -395,17 +365,17 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc)
pmc->dbgfs_dir = dir;
f = debugfs_create_file("dev_state", S_IFREG | S_IRUGO,
- dir, pmc, &pmc_dev_state_ops);
+ dir, pmc, &pmc_dev_state_fops);
if (!f)
goto err;
f = debugfs_create_file("pss_state", S_IFREG | S_IRUGO,
- dir, pmc, &pmc_pss_state_ops);
+ dir, pmc, &pmc_pss_state_fops);
if (!f)
goto err;
f = debugfs_create_file("sleep_state", S_IFREG | S_IRUGO,
- dir, pmc, &pmc_sleep_tmr_ops);
+ dir, pmc, &pmc_sleep_tmr_fops);
if (!f)
goto err;
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
index d3cb26f6df73..03305e0b89ff 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -1252,7 +1252,7 @@ static int __init samsung_sysfs_init(struct samsung_laptop *samsung)
}
-static int show_call(struct seq_file *m, void *data)
+static int samsung_laptop_call_show(struct seq_file *m, void *data)
{
struct samsung_laptop *samsung = m->private;
struct sabi_data *sdata = &samsung->debug.data;
@@ -1274,19 +1274,7 @@ static int show_call(struct seq_file *m, void *data)
sdata->d0, sdata->d1, sdata->d2, sdata->d3);
return 0;
}
-
-static int samsung_debugfs_open(struct inode *inode, struct file *file)
-{
- return single_open(file, show_call, inode->i_private);
-}
-
-static const struct file_operations samsung_laptop_call_io_ops = {
- .owner = THIS_MODULE,
- .open = samsung_debugfs_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
+DEFINE_SHOW_ATTRIBUTE(samsung_laptop_call);
static void samsung_debugfs_exit(struct samsung_laptop *samsung)
{
@@ -1351,7 +1339,7 @@ static int samsung_debugfs_init(struct samsung_laptop *samsung)
dent = debugfs_create_file("call", S_IFREG | S_IRUGO,
samsung->debug.root, samsung,
- &samsung_laptop_call_io_ops);
+ &samsung_laptop_call_fops);
if (!dent)
goto error_debugfs;
diff --git a/drivers/platform/x86/silead_dmi.c b/drivers/platform/x86/silead_dmi.c
index 266535c2a72f..3a624090191d 100644
--- a/drivers/platform/x86/silead_dmi.c
+++ b/drivers/platform/x86/silead_dmi.c
@@ -67,6 +67,21 @@ static const struct silead_ts_dmi_data dexp_ursus_7w_data = {
.properties = dexp_ursus_7w_props,
};
+static const struct property_entry surftab_twin_10_1_st10432_8_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1900),
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
+ PROPERTY_ENTRY_U32("touchscreen-inverted-y", 1),
+ PROPERTY_ENTRY_STRING("firmware-name",
+ "gsl3670-surftab-twin-10-1-st10432-8.fw"),
+ PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+ { }
+};
+
+static const struct silead_ts_dmi_data surftab_twin_10_1_st10432_8_data = {
+ .acpi_name = "MSSL1680:00",
+ .properties = surftab_twin_10_1_st10432_8_props,
+};
+
static const struct property_entry surftab_wintron70_st70416_6_props[] = {
PROPERTY_ENTRY_U32("touchscreen-size-x", 884),
PROPERTY_ENTRY_U32("touchscreen-size-y", 632),
@@ -171,6 +186,97 @@ static const struct silead_ts_dmi_data digma_citi_e200_data = {
.properties = digma_citi_e200_props,
};
+static const struct property_entry onda_obook_20_plus_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1728),
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1148),
+ PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
+ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+ PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+ PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-onda-obook-20-plus.fw"),
+ PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+ PROPERTY_ENTRY_BOOL("silead,home-button"),
+ { }
+};
+
+static const struct silead_ts_dmi_data onda_obook_20_plus_data = {
+ .acpi_name = "MSSL1680:00",
+ .properties = onda_obook_20_plus_props,
+};
+
+static const struct property_entry chuwi_hi8_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1665),
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
+ PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+ PROPERTY_ENTRY_BOOL("silead,home-button"),
+ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-chuwi-hi8.fw"),
+ { }
+};
+
+static const struct silead_ts_dmi_data chuwi_hi8_data = {
+ .acpi_name = "MSSL0001:00",
+ .properties = chuwi_hi8_props,
+};
+
+static const struct property_entry chuwi_vi8_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1724),
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1140),
+ PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"),
+ PROPERTY_ENTRY_STRING("firmware-name", "gsl3676-chuwi-vi8.fw"),
+ PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+ PROPERTY_ENTRY_BOOL("silead,home-button"),
+ { }
+};
+
+static const struct silead_ts_dmi_data chuwi_vi8_data = {
+ .acpi_name = "MSSL1680:00",
+ .properties = chuwi_vi8_props,
+};
+
+static const struct property_entry trekstor_primebook_c13_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 2624),
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
+ PROPERTY_ENTRY_STRING("firmware-name",
+ "gsl1680-trekstor-primebook-c13.fw"),
+ PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+ PROPERTY_ENTRY_BOOL("silead,home-button"),
+ { }
+};
+
+static const struct silead_ts_dmi_data trekstor_primebook_c13_data = {
+ .acpi_name = "MSSL1680:00",
+ .properties = trekstor_primebook_c13_props,
+};
+
+static const struct property_entry teclast_x98plus2_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 2048),
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1280),
+ PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"),
+ PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"),
+ PROPERTY_ENTRY_STRING("firmware-name",
+ "gsl1686-teclast_x98plus2.fw"),
+ PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+ { }
+};
+
+static const struct silead_ts_dmi_data teclast_x98plus2_data = {
+ .acpi_name = "MSSL1680:00",
+ .properties = teclast_x98plus2_props,
+};
+
+static const struct property_entry teclast_x3_plus_props[] = {
+ PROPERTY_ENTRY_U32("touchscreen-size-x", 1980),
+ PROPERTY_ENTRY_U32("touchscreen-size-y", 1500),
+ PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-teclast-x3-plus.fw"),
+ PROPERTY_ENTRY_U32("silead,max-fingers", 10),
+ PROPERTY_ENTRY_BOOL("silead,home-button"),
+ { }
+};
+
+static const struct silead_ts_dmi_data teclast_x3_plus_data = {
+ .acpi_name = "MSSL1680:00",
+ .properties = teclast_x3_plus_props,
+};
+
static const struct dmi_system_id silead_ts_dmi_table[] = {
{
/* CUBE iwork8 Air */
@@ -199,6 +305,14 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
},
},
{
+ /* TrekStor SurfTab twin 10.1 ST10432-8 */
+ .driver_data = (void *)&surftab_twin_10_1_st10432_8_data,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "SurfTab twin 10.1"),
+ },
+ },
+ {
/* Trekstor Surftab Wintron 7.0 ST70416-6 */
.driver_data = (void *)&surftab_wintron70_st70416_6_data,
.matches = {
@@ -209,6 +323,17 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
},
},
{
+ /* Trekstor Surftab Wintron 7.0 ST70416-6, newer BIOS */
+ .driver_data = (void *)&surftab_wintron70_st70416_6_data,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TrekStor"),
+ DMI_MATCH(DMI_PRODUCT_NAME,
+ "SurfTab wintron 7.0 ST70416-6"),
+ /* Exact match, different versions need different fw */
+ DMI_MATCH(DMI_BIOS_VERSION, "TREK.G.WI71C.JGBMRBA05"),
+ },
+ },
+ {
/* Ployer Momo7w (same hardware as the Trekstor ST70416-6) */
.driver_data = (void *)&surftab_wintron70_st70416_6_data,
.matches = {
@@ -271,6 +396,56 @@ static const struct dmi_system_id silead_ts_dmi_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "Cherry Trail CR"),
},
},
+ {
+ /* Onda oBook 20 Plus */
+ .driver_data = (void *)&onda_obook_20_plus_data,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ONDA"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OBOOK 20 PLUS"),
+ },
+ },
+ {
+ /* Chuwi Hi8 */
+ .driver_data = (void *)&chuwi_hi8_data,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
+ },
+ },
+ {
+ /* Chuwi Vi8 (CWI506) */
+ .driver_data = (void *)&chuwi_vi8_data,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "i86"),
+ DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
+ },
+ },
+ {
+ /* Trekstor Primebook C13 */
+ .driver_data = (void *)&trekstor_primebook_c13_data,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TREKSTOR"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Primebook C13"),
+ },
+ },
+ {
+ /* Teclast X98 Plus II */
+ .driver_data = (void *)&teclast_x98plus2_data,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X98 Plus II"),
+ },
+ },
+ {
+ /* Teclast X3 Plus */
+ .driver_data = (void *)&teclast_x3_plus_data,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X3 Plus"),
+ DMI_MATCH(DMI_BOARD_NAME, "X3 Plus"),
+ },
+ },
{ },
};
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 117be48ff4de..d5eaf3b1edba 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -214,6 +214,10 @@ enum tpacpi_hkey_event_t {
/* AC-related events */
TP_HKEY_EV_AC_CHANGED = 0x6040, /* AC status changed */
+ /* Further user-interface events */
+ TP_HKEY_EV_PALM_DETECTED = 0x60b0, /* palm hoveres keyboard */
+ TP_HKEY_EV_PALM_UNDETECTED = 0x60b1, /* palm removed */
+
/* Misc */
TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */
};
@@ -2113,12 +2117,10 @@ static int hotkey_gmms_get_tablet_mode(int s, int *has_tablet_mode)
TP_ACPI_MULTI_MODE_FLAT;
break;
case 4:
- valid_modes = TP_ACPI_MULTI_MODE_LAPTOP |
- TP_ACPI_MULTI_MODE_TABLET |
- TP_ACPI_MULTI_MODE_STAND |
- TP_ACPI_MULTI_MODE_TENT;
- break;
case 5:
+ /* In mode 4, FLAT is not specified as a valid mode. However,
+ * it can be seen at least on the X1 Yoga 2nd Generation.
+ */
valid_modes = TP_ACPI_MULTI_MODE_LAPTOP |
TP_ACPI_MULTI_MODE_FLAT |
TP_ACPI_MULTI_MODE_TABLET |
@@ -4079,6 +4081,12 @@ static bool hotkey_notify_6xxx(const u32 hkey,
*send_acpi_ev = false;
break;
+ case TP_HKEY_EV_PALM_DETECTED:
+ case TP_HKEY_EV_PALM_UNDETECTED:
+ /* palm detected hovering the keyboard, forward to user-space
+ * via netlink for consumption */
+ return true;
+
default:
pr_warn("unknown possible thermal alarm or keyboard event received\n");
known = false;
diff --git a/drivers/pps/generators/pps_gen_parport.c b/drivers/pps/generators/pps_gen_parport.c
index dcd39fba6ddd..51cfde6afffd 100644
--- a/drivers/pps/generators/pps_gen_parport.c
+++ b/drivers/pps/generators/pps_gen_parport.c
@@ -70,7 +70,7 @@ static long hrtimer_error = SAFETY_INTERVAL;
/* the kernel hrtimer event */
static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
{
- struct timespec expire_time, ts1, ts2, ts3, dts;
+ struct timespec64 expire_time, ts1, ts2, ts3, dts;
struct pps_generator_pp *dev;
struct parport *port;
long lim, delta;
@@ -78,7 +78,7 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
/* We have to disable interrupts here. The idea is to prevent
* other interrupts on the same processor to introduce random
- * lags while polling the clock. getnstimeofday() takes <1us on
+ * lags while polling the clock. ktime_get_real_ts64() takes <1us on
* most machines while other interrupt handlers can take much
* more potentially.
*
@@ -88,22 +88,22 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
local_irq_save(flags);
/* first of all we get the time stamp... */
- getnstimeofday(&ts1);
- expire_time = ktime_to_timespec(hrtimer_get_softexpires(timer));
+ ktime_get_real_ts64(&ts1);
+ expire_time = ktime_to_timespec64(hrtimer_get_softexpires(timer));
dev = container_of(timer, struct pps_generator_pp, timer);
lim = NSEC_PER_SEC - send_delay - dev->port_write_time;
/* check if we are late */
if (expire_time.tv_sec != ts1.tv_sec || ts1.tv_nsec > lim) {
local_irq_restore(flags);
- pr_err("we are late this time %ld.%09ld\n",
- ts1.tv_sec, ts1.tv_nsec);
+ pr_err("we are late this time %lld.%09ld\n",
+ (s64)ts1.tv_sec, ts1.tv_nsec);
goto done;
}
/* busy loop until the time is right for an assert edge */
do {
- getnstimeofday(&ts2);
+ ktime_get_real_ts64(&ts2);
} while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim);
/* set the signal */
@@ -113,25 +113,25 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
/* busy loop until the time is right for a clear edge */
lim = NSEC_PER_SEC - dev->port_write_time;
do {
- getnstimeofday(&ts2);
+ ktime_get_real_ts64(&ts2);
} while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim);
/* unset the signal */
port->ops->write_control(port, NO_SIGNAL);
- getnstimeofday(&ts3);
+ ktime_get_real_ts64(&ts3);
local_irq_restore(flags);
/* update calibrated port write time */
- dts = timespec_sub(ts3, ts2);
+ dts = timespec64_sub(ts3, ts2);
dev->port_write_time =
- (dev->port_write_time + timespec_to_ns(&dts)) >> 1;
+ (dev->port_write_time + timespec64_to_ns(&dts)) >> 1;
done:
/* update calibrated hrtimer error */
- dts = timespec_sub(ts1, expire_time);
- delta = timespec_to_ns(&dts);
+ dts = timespec64_sub(ts1, expire_time);
+ delta = timespec64_to_ns(&dts);
/* If the new error value is bigger then the old, use the new
* value, if not then slowly move towards the new value. This
* way it should be safe in bad conditions and efficient in
@@ -161,17 +161,17 @@ static void calibrate_port(struct pps_generator_pp *dev)
long acc = 0;
for (i = 0; i < (1 << PORT_NTESTS_SHIFT); i++) {
- struct timespec a, b;
+ struct timespec64 a, b;
unsigned long irq_flags;
local_irq_save(irq_flags);
- getnstimeofday(&a);
+ ktime_get_real_ts64(&a);
port->ops->write_control(port, NO_SIGNAL);
- getnstimeofday(&b);
+ ktime_get_real_ts64(&b);
local_irq_restore(irq_flags);
- b = timespec_sub(b, a);
- acc += timespec_to_ns(&b);
+ b = timespec64_sub(b, a);
+ acc += timespec64_to_ns(&b);
}
dev->port_write_time = acc >> PORT_NTESTS_SHIFT;
@@ -180,9 +180,9 @@ static void calibrate_port(struct pps_generator_pp *dev)
static inline ktime_t next_intr_time(struct pps_generator_pp *dev)
{
- struct timespec ts;
+ struct timespec64 ts;
- getnstimeofday(&ts);
+ ktime_get_real_ts64(&ts);
return ktime_set(ts.tv_sec +
((ts.tv_nsec > 990 * NSEC_PER_MSEC) ? 1 : 0),
diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index d589331d1884..0767deba8e62 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -411,6 +411,24 @@ static const struct meson_pwm_data pwm_gxbb_ao_data = {
.num_parents = ARRAY_SIZE(pwm_gxbb_ao_parent_names),
};
+static const char * const pwm_axg_ee_parent_names[] = {
+ "xtal", "fclk_div5", "fclk_div4", "fclk_div3"
+};
+
+static const struct meson_pwm_data pwm_axg_ee_data = {
+ .parent_names = pwm_axg_ee_parent_names,
+ .num_parents = ARRAY_SIZE(pwm_axg_ee_parent_names),
+};
+
+static const char * const pwm_axg_ao_parent_names[] = {
+ "aoclk81", "xtal", "fclk_div4", "fclk_div5"
+};
+
+static const struct meson_pwm_data pwm_axg_ao_data = {
+ .parent_names = pwm_axg_ao_parent_names,
+ .num_parents = ARRAY_SIZE(pwm_axg_ao_parent_names),
+};
+
static const struct of_device_id meson_pwm_matches[] = {
{
.compatible = "amlogic,meson8b-pwm",
@@ -424,6 +442,14 @@ static const struct of_device_id meson_pwm_matches[] = {
.compatible = "amlogic,meson-gxbb-ao-pwm",
.data = &pwm_gxbb_ao_data
},
+ {
+ .compatible = "amlogic,meson-axg-ee-pwm",
+ .data = &pwm_axg_ee_data
+ },
+ {
+ .compatible = "amlogic,meson-axg-ao-pwm",
+ .data = &pwm_axg_ao_data
+ },
{},
};
MODULE_DEVICE_TABLE(of, meson_pwm_matches);
diff --git a/drivers/pwm/pwm-stmpe.c b/drivers/pwm/pwm-stmpe.c
index e464582a390a..3439f1e902cb 100644
--- a/drivers/pwm/pwm-stmpe.c
+++ b/drivers/pwm/pwm-stmpe.c
@@ -145,7 +145,7 @@ static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
break;
case 2:
- offset = STMPE24XX_PWMIC1;
+ offset = STMPE24XX_PWMIC2;
break;
default:
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index a813239300c3..83f2b0b15712 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -263,6 +263,7 @@ static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
export->pwm = pwm;
mutex_init(&export->lock);
+ export->child.class = parent->class;
export->child.release = pwm_export_release;
export->child.parent = parent;
export->child.devt = MKDEV(0, 0);
diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c
index e2a418598129..006ea5a45020 100644
--- a/drivers/rapidio/devices/tsi721_dma.c
+++ b/drivers/rapidio/devices/tsi721_dma.c
@@ -222,7 +222,7 @@ static int tsi721_bdma_ch_free(struct tsi721_bdma_chan *bdma_chan)
struct tsi721_device *priv = to_tsi721(bdma_chan->dchan.device);
#endif
- if (bdma_chan->bd_base == NULL)
+ if (!bdma_chan->bd_base)
return 0;
/* Check if DMA channel still running */
@@ -346,7 +346,7 @@ tsi721_desc_fill_init(struct tsi721_tx_desc *desc,
{
u64 rio_addr;
- if (bd_ptr == NULL)
+ if (!bd_ptr)
return -EINVAL;
/* Initialize DMA descriptor */
@@ -370,7 +370,7 @@ tsi721_desc_fill_init(struct tsi721_tx_desc *desc,
static int
tsi721_desc_fill_end(struct tsi721_dma_desc *bd_ptr, u32 bcount, bool interrupt)
{
- if (bd_ptr == NULL)
+ if (!bd_ptr)
return -EINVAL;
/* Update DMA descriptor */
@@ -555,9 +555,7 @@ static void tsi721_advance_work(struct tsi721_bdma_chan *bdma_chan,
* If there is no data transfer in progress, fetch new descriptor from
* the pending queue.
*/
-
- if (desc == NULL && bdma_chan->active_tx == NULL &&
- !list_empty(&bdma_chan->queue)) {
+ if (!desc && !bdma_chan->active_tx && !list_empty(&bdma_chan->queue)) {
desc = list_first_entry(&bdma_chan->queue,
struct tsi721_tx_desc, desc_node);
list_del_init((&desc->desc_node));
@@ -735,7 +733,7 @@ static dma_cookie_t tsi721_tx_submit(struct dma_async_tx_descriptor *txd)
static int tsi721_alloc_chan_resources(struct dma_chan *dchan)
{
struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan);
- struct tsi721_tx_desc *desc = NULL;
+ struct tsi721_tx_desc *desc;
int i;
tsi_debug(DMA, &dchan->dev->device, "DMAC%d", bdma_chan->id);
@@ -754,9 +752,6 @@ static int tsi721_alloc_chan_resources(struct dma_chan *dchan)
desc = kcalloc(dma_txqueue_sz, sizeof(struct tsi721_tx_desc),
GFP_ATOMIC);
if (!desc) {
- tsi_err(&dchan->dev->device,
- "DMAC%d Failed to allocate logical descriptors",
- bdma_chan->id);
tsi721_bdma_ch_free(bdma_chan);
return -ENOMEM;
}
@@ -799,7 +794,7 @@ static void tsi721_free_chan_resources(struct dma_chan *dchan)
tsi_debug(DMA, &dchan->dev->device, "DMAC%d", bdma_chan->id);
- if (bdma_chan->bd_base == NULL)
+ if (!bdma_chan->bd_base)
return;
tsi721_bdma_interrupt_enable(bdma_chan, 0);
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index 38d949405618..83406696c7aa 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -81,6 +81,7 @@ u16 rio_local_get_device_id(struct rio_mport *port)
return (RIO_GET_DID(port->sys_size, result));
}
+EXPORT_SYMBOL_GPL(rio_local_get_device_id);
/**
* rio_query_mport - Query mport device attributes
@@ -110,9 +111,8 @@ EXPORT_SYMBOL(rio_query_mport);
*/
struct rio_net *rio_alloc_net(struct rio_mport *mport)
{
- struct rio_net *net;
+ struct rio_net *net = kzalloc(sizeof(*net), GFP_KERNEL);
- net = kzalloc(sizeof(struct rio_net), GFP_KERNEL);
if (net) {
INIT_LIST_HEAD(&net->node);
INIT_LIST_HEAD(&net->devices);
@@ -243,18 +243,17 @@ int rio_request_inb_mbox(struct rio_mport *mport,
int rc = -ENOSYS;
struct resource *res;
- if (mport->ops->open_inb_mbox == NULL)
+ if (!mport->ops->open_inb_mbox)
goto out;
- res = kzalloc(sizeof(struct resource), GFP_KERNEL);
-
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
if (res) {
rio_init_mbox_res(res, mbox, mbox);
/* Make sure this mailbox isn't in use */
- if ((rc =
- request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE],
- res)) < 0) {
+ rc = request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE],
+ res);
+ if (rc < 0) {
kfree(res);
goto out;
}
@@ -277,6 +276,7 @@ int rio_request_inb_mbox(struct rio_mport *mport,
out:
return rc;
}
+EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
/**
* rio_release_inb_mbox - release inbound mailbox message service
@@ -305,6 +305,7 @@ int rio_release_inb_mbox(struct rio_mport *mport, int mbox)
return 0;
}
+EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
/**
* rio_request_outb_mbox - request outbound mailbox service
@@ -326,18 +327,17 @@ int rio_request_outb_mbox(struct rio_mport *mport,
int rc = -ENOSYS;
struct resource *res;
- if (mport->ops->open_outb_mbox == NULL)
+ if (!mport->ops->open_outb_mbox)
goto out;
- res = kzalloc(sizeof(struct resource), GFP_KERNEL);
-
+ res = kzalloc(sizeof(*res), GFP_KERNEL);
if (res) {
rio_init_mbox_res(res, mbox, mbox);
/* Make sure this outbound mailbox isn't in use */
- if ((rc =
- request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE],
- res)) < 0) {
+ rc = request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE],
+ res);
+ if (rc < 0) {
kfree(res);
goto out;
}
@@ -360,6 +360,7 @@ int rio_request_outb_mbox(struct rio_mport *mport,
out:
return rc;
}
+EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
/**
* rio_release_outb_mbox - release outbound mailbox message service
@@ -388,6 +389,7 @@ int rio_release_outb_mbox(struct rio_mport *mport, int mbox)
return 0;
}
+EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
/**
* rio_setup_inb_dbell - bind inbound doorbell callback
@@ -405,13 +407,10 @@ rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res,
void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst,
u16 info))
{
- int rc = 0;
- struct rio_dbell *dbell;
+ struct rio_dbell *dbell = kmalloc(sizeof(*dbell), GFP_KERNEL);
- if (!(dbell = kmalloc(sizeof(struct rio_dbell), GFP_KERNEL))) {
- rc = -ENOMEM;
- goto out;
- }
+ if (!dbell)
+ return -ENOMEM;
dbell->res = res;
dbell->dinb = dinb;
@@ -420,9 +419,7 @@ rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res,
mutex_lock(&mport->lock);
list_add_tail(&dbell->node, &mport->dbells);
mutex_unlock(&mport->lock);
-
- out:
- return rc;
+ return 0;
}
/**
@@ -444,17 +441,16 @@ int rio_request_inb_dbell(struct rio_mport *mport,
void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src,
u16 dst, u16 info))
{
- int rc = 0;
-
- struct resource *res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+ int rc;
+ struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
if (res) {
rio_init_dbell_res(res, start, end);
/* Make sure these doorbells aren't in use */
- if ((rc =
- request_resource(&mport->riores[RIO_DOORBELL_RESOURCE],
- res)) < 0) {
+ rc = request_resource(&mport->riores[RIO_DOORBELL_RESOURCE],
+ res);
+ if (rc < 0) {
kfree(res);
goto out;
}
@@ -467,6 +463,7 @@ int rio_request_inb_dbell(struct rio_mport *mport,
out:
return rc;
}
+EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
/**
* rio_release_inb_dbell - release inbound doorbell message service
@@ -508,6 +505,7 @@ int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end)
out:
return rc;
}
+EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
/**
* rio_request_outb_dbell - request outbound doorbell message range
@@ -536,6 +534,7 @@ struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start,
return res;
}
+EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
/**
* rio_release_outb_dbell - release outbound doorbell message range
@@ -553,6 +552,7 @@ int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res)
return rc;
}
+EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
/**
* rio_add_mport_pw_handler - add port-write message handler into the list
@@ -567,22 +567,17 @@ int rio_add_mport_pw_handler(struct rio_mport *mport, void *context,
int (*pwcback)(struct rio_mport *mport,
void *context, union rio_pw_msg *msg, int step))
{
- int rc = 0;
- struct rio_pwrite *pwrite;
+ struct rio_pwrite *pwrite = kzalloc(sizeof(*pwrite), GFP_KERNEL);
- pwrite = kzalloc(sizeof(struct rio_pwrite), GFP_KERNEL);
- if (!pwrite) {
- rc = -ENOMEM;
- goto out;
- }
+ if (!pwrite)
+ return -ENOMEM;
pwrite->pwcback = pwcback;
pwrite->context = context;
mutex_lock(&mport->lock);
list_add_tail(&pwrite->node, &mport->pwrites);
mutex_unlock(&mport->lock);
-out:
- return rc;
+ return 0;
}
EXPORT_SYMBOL_GPL(rio_add_mport_pw_handler);
@@ -632,7 +627,7 @@ int rio_request_inb_pwrite(struct rio_dev *rdev,
int rc = 0;
spin_lock(&rio_global_list_lock);
- if (rdev->pwcback != NULL)
+ if (rdev->pwcback)
rc = -ENOMEM;
else
rdev->pwcback = pwcback;
@@ -698,7 +693,7 @@ EXPORT_SYMBOL_GPL(rio_pw_enable);
int rio_map_inb_region(struct rio_mport *mport, dma_addr_t local,
u64 rbase, u32 size, u32 rflags)
{
- int rc = 0;
+ int rc;
unsigned long flags;
if (!mport->ops->map_inb)
@@ -742,7 +737,7 @@ EXPORT_SYMBOL_GPL(rio_unmap_inb_region);
int rio_map_outb_region(struct rio_mport *mport, u16 destid, u64 rbase,
u32 size, u32 rflags, dma_addr_t *local)
{
- int rc = 0;
+ int rc;
unsigned long flags;
if (!mport->ops->map_outb)
@@ -975,7 +970,7 @@ rio_chk_dev_route(struct rio_dev *rdev, struct rio_dev **nrdev, int *npnum)
rdev = rdev->prev;
}
- if (prev == NULL)
+ if (!prev)
goto err_out;
p_port = prev->rswitch->route_table[rdev->destid];
@@ -1054,7 +1049,7 @@ rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp)
RIO_MNT_REQ_CMD_IS);
/* Exit if the response is not expected */
- if (lnkresp == NULL)
+ if (!lnkresp)
return 0;
checkcount = 3;
@@ -1411,7 +1406,9 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
ext_ftr_ptr, &ftr_header);
if (RIO_GET_BLOCK_ID(ftr_header) == ftr)
return ext_ftr_ptr;
- if (!(ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header)))
+
+ ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header);
+ if (!ext_ftr_ptr)
break;
}
@@ -1462,6 +1459,7 @@ struct rio_dev *rio_get_asm(u16 vid, u16 did,
spin_unlock(&rio_global_list_lock);
return rdev;
}
+EXPORT_SYMBOL_GPL(rio_get_asm);
/**
* rio_get_device - Begin or continue searching for a RIO device by vid/did
@@ -1481,6 +1479,7 @@ struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from)
{
return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from);
}
+EXPORT_SYMBOL_GPL(rio_get_device);
/**
* rio_std_route_add_entry - Add switch route table entry using standard
@@ -1696,7 +1695,7 @@ int rio_route_add_entry(struct rio_dev *rdev,
spin_lock(&rdev->rswitch->lock);
- if (ops == NULL || ops->add_entry == NULL) {
+ if (!ops || !ops->add_entry) {
rc = rio_std_route_add_entry(rdev->net->hport, rdev->destid,
rdev->hopcount, table,
route_destid, route_port);
@@ -1749,7 +1748,7 @@ int rio_route_get_entry(struct rio_dev *rdev, u16 table,
spin_lock(&rdev->rswitch->lock);
- if (ops == NULL || ops->get_entry == NULL) {
+ if (!ops || !ops->get_entry) {
rc = rio_std_route_get_entry(rdev->net->hport, rdev->destid,
rdev->hopcount, table,
route_destid, route_port);
@@ -1797,7 +1796,7 @@ int rio_route_clr_table(struct rio_dev *rdev, u16 table, int lock)
spin_lock(&rdev->rswitch->lock);
- if (ops == NULL || ops->clr_table == NULL) {
+ if (!ops || !ops->clr_table) {
rc = rio_std_route_clr_table(rdev->net->hport, rdev->destid,
rdev->hopcount, table);
} else if (try_module_get(ops->owner)) {
@@ -1889,7 +1888,7 @@ struct dma_async_tx_descriptor *rio_dma_prep_xfer(struct dma_chan *dchan,
{
struct rio_dma_ext rio_ext;
- if (dchan->device->device_prep_slave_sg == NULL) {
+ if (!dchan->device->device_prep_slave_sg) {
pr_err("%s: prep_rio_sg == NULL\n", __func__);
return NULL;
}
@@ -2189,7 +2188,6 @@ int rio_init_mports(void)
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;
}
@@ -2216,6 +2214,7 @@ no_disc:
return 0;
}
+EXPORT_SYMBOL_GPL(rio_init_mports);
static int rio_get_hdid(int index)
{
@@ -2330,16 +2329,3 @@ int rio_unregister_mport(struct rio_mport *port)
return 0;
}
EXPORT_SYMBOL_GPL(rio_unregister_mport);
-
-EXPORT_SYMBOL_GPL(rio_local_get_device_id);
-EXPORT_SYMBOL_GPL(rio_get_device);
-EXPORT_SYMBOL_GPL(rio_get_asm);
-EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
-EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
-EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
-EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
-EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
-EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
-EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
-EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
-EXPORT_SYMBOL_GPL(rio_init_mports);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 42681c10cbe4..dd4708c58480 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -758,7 +758,7 @@ static int suspend_set_state(struct regulator_dev *rdev,
rstate = regulator_get_suspend_state(rdev, state);
if (rstate == NULL)
- return -EINVAL;
+ return 0;
/* If we have no suspend mode configration don't set anything;
* only warn if the driver implements set_suspend_voltage or
diff --git a/drivers/remoteproc/qcom_adsp_pil.c b/drivers/remoteproc/qcom_adsp_pil.c
index 3f6af54dbc96..373c167892d7 100644
--- a/drivers/remoteproc/qcom_adsp_pil.c
+++ b/drivers/remoteproc/qcom_adsp_pil.c
@@ -85,11 +85,6 @@ static int adsp_load(struct rproc *rproc, const struct firmware *fw)
adsp->mem_region, adsp->mem_phys, adsp->mem_size);
}
-static const struct rproc_fw_ops adsp_fw_ops = {
- .find_rsc_table = qcom_mdt_find_rsc_table,
- .load = adsp_load,
-};
-
static int adsp_start(struct rproc *rproc)
{
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
@@ -182,6 +177,7 @@ static const struct rproc_ops adsp_ops = {
.start = adsp_start,
.stop = adsp_stop,
.da_to_va = adsp_da_to_va,
+ .load = adsp_load,
};
static irqreturn_t adsp_wdog_interrupt(int irq, void *dev)
@@ -344,8 +340,6 @@ static int adsp_probe(struct platform_device *pdev)
return -ENOMEM;
}
- rproc->fw_ops = &adsp_fw_ops;
-
adsp = (struct qcom_adsp *)rproc->priv;
adsp->dev = &pdev->dev;
adsp->rproc = rproc;
diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c
index d487040b528b..00602499713f 100644
--- a/drivers/remoteproc/qcom_common.c
+++ b/drivers/remoteproc/qcom_common.c
@@ -32,32 +32,13 @@
static BLOCKING_NOTIFIER_HEAD(ssr_notifiers);
-/**
- * qcom_mdt_find_rsc_table() - provide dummy resource table for remoteproc
- * @rproc: remoteproc handle
- * @fw: firmware header
- * @tablesz: outgoing size of the table
- *
- * Returns a dummy table.
- */
-struct resource_table *qcom_mdt_find_rsc_table(struct rproc *rproc,
- const struct firmware *fw,
- int *tablesz)
-{
- static struct resource_table table = { .ver = 1, };
-
- *tablesz = sizeof(table);
- return &table;
-}
-EXPORT_SYMBOL_GPL(qcom_mdt_find_rsc_table);
-
static int glink_subdev_probe(struct rproc_subdev *subdev)
{
struct qcom_rproc_glink *glink = to_glink_subdev(subdev);
glink->edge = qcom_glink_smem_register(glink->dev, glink->node);
- return IS_ERR(glink->edge) ? PTR_ERR(glink->edge) : 0;
+ return PTR_ERR_OR_ZERO(glink->edge);
}
static void glink_subdev_remove(struct rproc_subdev *subdev)
diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h
index 832e20271664..728be9834d8b 100644
--- a/drivers/remoteproc/qcom_common.h
+++ b/drivers/remoteproc/qcom_common.h
@@ -27,10 +27,6 @@ struct qcom_rproc_ssr {
const char *name;
};
-struct resource_table *qcom_mdt_find_rsc_table(struct rproc *rproc,
- const struct firmware *fw,
- int *tablesz);
-
void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);
void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);
diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
index 8a3fa2bcc9f6..b4e5e725848d 100644
--- a/drivers/remoteproc/qcom_q6v5_pil.c
+++ b/drivers/remoteproc/qcom_q6v5_pil.c
@@ -303,16 +303,6 @@ static void q6v5_clk_disable(struct device *dev,
clk_disable_unprepare(clks[i]);
}
-static struct resource_table *q6v5_find_rsc_table(struct rproc *rproc,
- const struct firmware *fw,
- int *tablesz)
-{
- static struct resource_table table = { .ver = 1, };
-
- *tablesz = sizeof(table);
- return &table;
-}
-
static int q6v5_xfer_mem_ownership(struct q6v5 *qproc, int *current_perm,
bool remote_owner, phys_addr_t addr,
size_t size)
@@ -342,11 +332,6 @@ static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
return 0;
}
-static const struct rproc_fw_ops q6v5_fw_ops = {
- .find_rsc_table = q6v5_find_rsc_table,
- .load = q6v5_load,
-};
-
static int q6v5_rmb_pbl_wait(struct q6v5 *qproc, int ms)
{
unsigned long timeout;
@@ -931,6 +916,7 @@ static const struct rproc_ops q6v5_ops = {
.start = q6v5_start,
.stop = q6v5_stop,
.da_to_va = q6v5_da_to_va,
+ .load = q6v5_load,
};
static irqreturn_t q6v5_wdog_interrupt(int irq, void *dev)
@@ -1150,8 +1136,6 @@ static int q6v5_probe(struct platform_device *pdev)
return -ENOMEM;
}
- rproc->fw_ops = &q6v5_fw_ops;
-
qproc = (struct q6v5 *)rproc->priv;
qproc->dev = &pdev->dev;
qproc->rproc = rproc;
diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c
index c7686393d505..3f0609236a76 100644
--- a/drivers/remoteproc/qcom_wcnss.c
+++ b/drivers/remoteproc/qcom_wcnss.c
@@ -156,11 +156,6 @@ static int wcnss_load(struct rproc *rproc, const struct firmware *fw)
wcnss->mem_region, wcnss->mem_phys, wcnss->mem_size);
}
-static const struct rproc_fw_ops wcnss_fw_ops = {
- .find_rsc_table = qcom_mdt_find_rsc_table,
- .load = wcnss_load,
-};
-
static void wcnss_indicate_nv_download(struct qcom_wcnss *wcnss)
{
u32 val;
@@ -313,6 +308,7 @@ static const struct rproc_ops wcnss_ops = {
.start = wcnss_start,
.stop = wcnss_stop,
.da_to_va = wcnss_da_to_va,
+ .load = wcnss_load,
};
static irqreturn_t wcnss_wdog_interrupt(int irq, void *dev)
@@ -492,8 +488,6 @@ static int wcnss_probe(struct platform_device *pdev)
return -ENOMEM;
}
- rproc->fw_ops = &wcnss_fw_ops;
-
wcnss = (struct qcom_wcnss *)rproc->priv;
wcnss->dev = &pdev->dev;
wcnss->rproc = rproc;
diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index eab14b414bf0..4170dfbd93bd 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -732,17 +732,20 @@ static rproc_handle_resource_t rproc_loading_handlers[RSC_LAST] = {
};
/* handle firmware resource entries before booting the remote processor */
-static int rproc_handle_resources(struct rproc *rproc, int len,
+static int rproc_handle_resources(struct rproc *rproc,
rproc_handle_resource_t handlers[RSC_LAST])
{
struct device *dev = &rproc->dev;
rproc_handle_resource_t handler;
int ret = 0, i;
+ if (!rproc->table_ptr)
+ return 0;
+
for (i = 0; i < rproc->table_ptr->num; i++) {
int offset = rproc->table_ptr->offset[i];
struct fw_rsc_hdr *hdr = (void *)rproc->table_ptr + offset;
- int avail = len - offset - sizeof(*hdr);
+ int avail = rproc->table_sz - offset - sizeof(*hdr);
void *rsc = (void *)hdr + sizeof(*hdr);
/* make sure table isn't truncated */
@@ -849,16 +852,9 @@ static void rproc_resource_cleanup(struct rproc *rproc)
static int rproc_start(struct rproc *rproc, const struct firmware *fw)
{
- struct resource_table *table, *loaded_table;
+ struct resource_table *loaded_table;
struct device *dev = &rproc->dev;
- int ret, tablesz;
-
- /* look for the resource table */
- table = rproc_find_rsc_table(rproc, fw, &tablesz);
- if (!table) {
- dev_err(dev, "Resource table look up failed\n");
- return -EINVAL;
- }
+ int ret;
/* load the ELF segments to memory */
ret = rproc_load_segments(rproc, fw);
@@ -877,7 +873,7 @@ static int rproc_start(struct rproc *rproc, const struct firmware *fw)
*/
loaded_table = rproc_find_loaded_rsc_table(rproc, fw);
if (loaded_table) {
- memcpy(loaded_table, rproc->cached_table, tablesz);
+ memcpy(loaded_table, rproc->cached_table, rproc->table_sz);
rproc->table_ptr = loaded_table;
}
@@ -911,8 +907,7 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
{
struct device *dev = &rproc->dev;
const char *name = rproc->firmware;
- struct resource_table *table;
- int ret, tablesz;
+ int ret;
ret = rproc_fw_sanity_check(rproc, fw);
if (ret)
@@ -931,32 +926,17 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
}
rproc->bootaddr = rproc_get_boot_addr(rproc, fw);
- ret = -EINVAL;
- /* look for the resource table */
- table = rproc_find_rsc_table(rproc, fw, &tablesz);
- if (!table) {
- dev_err(dev, "Failed to find resource table\n");
- goto clean_up;
- }
-
- /*
- * Create a copy of the resource table. When a virtio device starts
- * and calls vring_new_virtqueue() the address of the allocated vring
- * will be stored in the cached_table. Before the device is started,
- * cached_table will be copied into device memory.
- */
- rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL);
- if (!rproc->cached_table)
- goto clean_up;
-
- rproc->table_ptr = rproc->cached_table;
+ /* load resource table */
+ ret = rproc_load_rsc_table(rproc, fw);
+ if (ret)
+ goto disable_iommu;
/* reset max_notifyid */
rproc->max_notifyid = -1;
/* handle fw resources which are required to boot rproc */
- ret = rproc_handle_resources(rproc, tablesz, rproc_loading_handlers);
+ ret = rproc_handle_resources(rproc, rproc_loading_handlers);
if (ret) {
dev_err(dev, "Failed to process resources: %d\n", ret);
goto clean_up_resources;
@@ -970,11 +950,10 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw)
clean_up_resources:
rproc_resource_cleanup(rproc);
-clean_up:
kfree(rproc->cached_table);
rproc->cached_table = NULL;
rproc->table_ptr = NULL;
-
+disable_iommu:
rproc_disable_iommu(rproc);
return ret;
}
@@ -1021,6 +1000,9 @@ static int rproc_stop(struct rproc *rproc)
/* remove any subdevices for the remote processor */
rproc_remove_subdevices(rproc);
+ /* the installed resource table is no longer accessible */
+ rproc->table_ptr = rproc->cached_table;
+
/* power off the remote processor */
ret = rproc->ops->stop(rproc);
if (ret) {
@@ -1028,10 +1010,6 @@ static int rproc_stop(struct rproc *rproc)
return ret;
}
- /* 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);
@@ -1057,8 +1035,6 @@ int rproc_trigger_recovery(struct rproc *rproc)
dev_err(dev, "recovering %s\n", rproc->name);
- init_completion(&rproc->crash_comp);
-
ret = mutex_lock_interruptible(&rproc->lock);
if (ret)
return ret;
@@ -1067,9 +1043,6 @@ int rproc_trigger_recovery(struct rproc *rproc)
if (ret)
goto unlock_mutex;
- /* wait until there is no more rproc users */
- wait_for_completion(&rproc->crash_comp);
-
/* load firmware */
ret = request_firmware(&firmware_p, rproc->firmware, dev);
if (ret < 0) {
@@ -1357,6 +1330,7 @@ static void rproc_type_release(struct device *dev)
ida_simple_remove(&rproc_dev_index, rproc->index);
kfree(rproc->firmware);
+ kfree(rproc->ops);
kfree(rproc);
}
@@ -1421,9 +1395,15 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
return NULL;
}
+ rproc->ops = kmemdup(ops, sizeof(*ops), GFP_KERNEL);
+ if (!rproc->ops) {
+ kfree(p);
+ kfree(rproc);
+ return NULL;
+ }
+
rproc->firmware = p;
rproc->name = name;
- rproc->ops = ops;
rproc->priv = &rproc[1];
rproc->auto_boot = true;
@@ -1445,8 +1425,14 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
atomic_set(&rproc->power, 0);
- /* Set ELF as the default fw_ops handler */
- rproc->fw_ops = &rproc_elf_fw_ops;
+ /* Default to ELF loader if no load function is specified */
+ if (!rproc->ops->load) {
+ rproc->ops->load = rproc_elf_load_segments;
+ rproc->ops->load_rsc_table = rproc_elf_load_rsc_table;
+ rproc->ops->find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table;
+ rproc->ops->sanity_check = rproc_elf_sanity_check;
+ rproc->ops->get_boot_addr = rproc_elf_get_boot_addr;
+ }
mutex_init(&rproc->lock);
@@ -1459,7 +1445,6 @@ struct rproc *rproc_alloc(struct device *dev, const char *name,
INIT_LIST_HEAD(&rproc->subdevs);
INIT_WORK(&rproc->crash_handler, rproc_crash_handler_work);
- init_completion(&rproc->crash_comp);
rproc->state = RPROC_OFFLINE;
diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index c523983a4aec..b17d72ec8603 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -39,8 +39,7 @@
*
* Make sure this fw image is sane.
*/
-static int
-rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw)
+int rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw)
{
const char *name = rproc->firmware;
struct device *dev = &rproc->dev;
@@ -98,6 +97,7 @@ rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw)
return 0;
}
+EXPORT_SYMBOL(rproc_elf_sanity_check);
/**
* rproc_elf_get_boot_addr() - Get rproc's boot address.
@@ -110,13 +110,13 @@ rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw)
* Note that the boot address is not a configurable property of all remote
* processors. Some will always boot at a specific hard-coded address.
*/
-static
u32 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
{
struct elf32_hdr *ehdr = (struct elf32_hdr *)fw->data;
return ehdr->e_entry;
}
+EXPORT_SYMBOL(rproc_elf_get_boot_addr);
/**
* rproc_elf_load_segments() - load firmware segments to memory
@@ -142,8 +142,7 @@ u32 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
* directly allocate memory for every segment/resource. This is not yet
* supported, though.
*/
-static int
-rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
+int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
{
struct device *dev = &rproc->dev;
struct elf32_hdr *ehdr;
@@ -207,6 +206,7 @@ rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
return ret;
}
+EXPORT_SYMBOL(rproc_elf_load_segments);
static struct elf32_shdr *
find_table(struct device *dev, struct elf32_hdr *ehdr, size_t fw_size)
@@ -268,41 +268,49 @@ find_table(struct device *dev, struct elf32_hdr *ehdr, size_t fw_size)
}
/**
- * rproc_elf_find_rsc_table() - find the resource table
+ * rproc_elf_load_rsc_table() - load the resource table
* @rproc: the rproc handle
* @fw: the ELF firmware image
- * @tablesz: place holder for providing back the table size
*
* This function finds the resource table inside the remote processor's
- * firmware. It is used both upon the registration of @rproc (in order
- * to look for and register the supported virito devices), and when the
- * @rproc is booted.
+ * firmware, load it into the @cached_table and update @table_ptr.
*
- * Returns the pointer to the resource table if it is found, and write its
- * size into @tablesz. If a valid table isn't found, NULL is returned
- * (and @tablesz isn't set).
+ * Return: 0 on success, negative errno on failure.
*/
-static struct resource_table *
-rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
- int *tablesz)
+int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw)
{
struct elf32_hdr *ehdr;
struct elf32_shdr *shdr;
struct device *dev = &rproc->dev;
struct resource_table *table = NULL;
const u8 *elf_data = fw->data;
+ size_t tablesz;
ehdr = (struct elf32_hdr *)elf_data;
shdr = find_table(dev, ehdr, fw->size);
if (!shdr)
- return NULL;
+ return -EINVAL;
table = (struct resource_table *)(elf_data + shdr->sh_offset);
- *tablesz = shdr->sh_size;
+ tablesz = shdr->sh_size;
+
+ /*
+ * Create a copy of the resource table. When a virtio device starts
+ * and calls vring_new_virtqueue() the address of the allocated vring
+ * will be stored in the cached_table. Before the device is started,
+ * cached_table will be copied into device memory.
+ */
+ rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL);
+ if (!rproc->cached_table)
+ return -ENOMEM;
- return table;
+ rproc->table_ptr = rproc->cached_table;
+ rproc->table_sz = tablesz;
+
+ return 0;
}
+EXPORT_SYMBOL(rproc_elf_load_rsc_table);
/**
* rproc_elf_find_loaded_rsc_table() - find the loaded resource table
@@ -315,8 +323,8 @@ rproc_elf_find_rsc_table(struct rproc *rproc, const struct firmware *fw,
* Returns the pointer to the resource table if it is found or NULL otherwise.
* If the table wasn't loaded yet the result is unspecified.
*/
-static struct resource_table *
-rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
+struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc,
+ const struct firmware *fw)
{
struct elf32_hdr *ehdr = (struct elf32_hdr *)fw->data;
struct elf32_shdr *shdr;
@@ -327,11 +335,4 @@ rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
return rproc_da_to_va(rproc, shdr->sh_addr, shdr->sh_size);
}
-
-const struct rproc_fw_ops rproc_elf_fw_ops = {
- .load = rproc_elf_load_segments,
- .find_rsc_table = rproc_elf_find_rsc_table,
- .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
- .sanity_check = rproc_elf_sanity_check,
- .get_boot_addr = rproc_elf_get_boot_addr
-};
+EXPORT_SYMBOL(rproc_elf_find_loaded_rsc_table);
diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index c1077bec5d0b..55a2950c5cb7 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -25,26 +25,6 @@
struct rproc;
-/**
- * struct rproc_fw_ops - firmware format specific operations.
- * @find_rsc_table: find the resource table inside the firmware image
- * @find_loaded_rsc_table: find the loaded resouce table
- * @load: load firmeware to memory, where the remote processor
- * expects to find it
- * @sanity_check: sanity check the fw image
- * @get_boot_addr: get boot address to entry point specified in firmware
- */
-struct rproc_fw_ops {
- struct resource_table *(*find_rsc_table)(struct rproc *rproc,
- const struct firmware *fw,
- int *tablesz);
- struct resource_table *(*find_loaded_rsc_table)(
- struct rproc *rproc, const struct firmware *fw);
- int (*load)(struct rproc *rproc, const struct firmware *fw);
- int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
- u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
-};
-
/* from remoteproc_core.c */
void rproc_release(struct kref *kref);
irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int vq_id);
@@ -74,11 +54,18 @@ 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);
+int rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw);
+u32 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw);
+int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw);
+int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw);
+struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc,
+ const struct firmware *fw);
+
static inline
int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
{
- if (rproc->fw_ops->sanity_check)
- return rproc->fw_ops->sanity_check(rproc, fw);
+ if (rproc->ops->sanity_check)
+ return rproc->ops->sanity_check(rproc, fw);
return 0;
}
@@ -86,8 +73,8 @@ int rproc_fw_sanity_check(struct rproc *rproc, const struct firmware *fw)
static inline
u32 rproc_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
{
- if (rproc->fw_ops->get_boot_addr)
- return rproc->fw_ops->get_boot_addr(rproc, fw);
+ if (rproc->ops->get_boot_addr)
+ return rproc->ops->get_boot_addr(rproc, fw);
return 0;
}
@@ -95,33 +82,29 @@ u32 rproc_get_boot_addr(struct rproc *rproc, const struct firmware *fw)
static inline
int rproc_load_segments(struct rproc *rproc, const struct firmware *fw)
{
- if (rproc->fw_ops->load)
- return rproc->fw_ops->load(rproc, fw);
+ if (rproc->ops->load)
+ return rproc->ops->load(rproc, fw);
return -EINVAL;
}
-static inline
-struct resource_table *rproc_find_rsc_table(struct rproc *rproc,
- const struct firmware *fw,
- int *tablesz)
+static inline int rproc_load_rsc_table(struct rproc *rproc,
+ const struct firmware *fw)
{
- if (rproc->fw_ops->find_rsc_table)
- return rproc->fw_ops->find_rsc_table(rproc, fw, tablesz);
+ if (rproc->ops->load_rsc_table)
+ return rproc->ops->load_rsc_table(rproc, fw);
- return NULL;
+ return 0;
}
static inline
struct resource_table *rproc_find_loaded_rsc_table(struct rproc *rproc,
const struct firmware *fw)
{
- if (rproc->fw_ops->find_loaded_rsc_table)
- return rproc->fw_ops->find_loaded_rsc_table(rproc, fw);
+ if (rproc->ops->find_loaded_rsc_table)
+ return rproc->ops->find_loaded_rsc_table(rproc, fw);
return NULL;
}
-extern const struct rproc_fw_ops rproc_elf_fw_ops;
-
#endif /* REMOTEPROC_INTERNAL_H */
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index 294634836b32..b0633fd4c041 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -327,7 +327,7 @@ int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id)
ret = register_virtio_device(vdev);
if (ret) {
- put_device(&rproc->dev);
+ put_device(&vdev->dev);
dev_err(dev, "failed to register vdev: %d\n", ret);
goto out;
}
diff --git a/drivers/remoteproc/st_slim_rproc.c b/drivers/remoteproc/st_slim_rproc.c
index 6cfd862f945b..1ffb1f0c43d6 100644
--- a/drivers/remoteproc/st_slim_rproc.c
+++ b/drivers/remoteproc/st_slim_rproc.c
@@ -204,27 +204,9 @@ static const struct rproc_ops slim_rproc_ops = {
.start = slim_rproc_start,
.stop = slim_rproc_stop,
.da_to_va = slim_rproc_da_to_va,
-};
-
-/*
- * Firmware handler operations: sanity, boot address, load ...
- */
-
-static struct resource_table empty_rsc_tbl = {
- .ver = 1,
- .num = 0,
-};
-
-static struct resource_table *slim_rproc_find_rsc_table(struct rproc *rproc,
- const struct firmware *fw,
- int *tablesz)
-{
- *tablesz = sizeof(empty_rsc_tbl);
- return &empty_rsc_tbl;
-}
-
-static struct rproc_fw_ops slim_rproc_fw_ops = {
- .find_rsc_table = slim_rproc_find_rsc_table,
+ .get_boot_addr = rproc_elf_get_boot_addr,
+ .load = rproc_elf_load_segments,
+ .sanity_check = rproc_elf_sanity_check,
};
/**
@@ -249,7 +231,6 @@ struct st_slim_rproc *st_slim_rproc_alloc(struct platform_device *pdev,
struct rproc *rproc;
struct resource *res;
int err, i;
- const struct rproc_fw_ops *elf_ops;
if (!fw_name)
return ERR_PTR(-EINVAL);
@@ -267,13 +248,6 @@ struct st_slim_rproc *st_slim_rproc_alloc(struct platform_device *pdev,
slim_rproc = rproc->priv;
slim_rproc->rproc = rproc;
- elf_ops = rproc->fw_ops;
- /* Use some generic elf ops */
- slim_rproc_fw_ops.load = elf_ops->load;
- slim_rproc_fw_ops.sanity_check = elf_ops->sanity_check;
-
- rproc->fw_ops = &slim_rproc_fw_ops;
-
/* get imem and dmem */
for (i = 0; i < ARRAY_SIZE(mem_names); i++) {
res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c
index 40d76d2a5eff..e0f31ed096a5 100644
--- a/drivers/rpmsg/qcom_glink_native.c
+++ b/drivers/rpmsg/qcom_glink_native.c
@@ -221,6 +221,7 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink,
/* Setup glink internal glink_channel data */
spin_lock_init(&channel->recv_lock);
spin_lock_init(&channel->intent_lock);
+ mutex_init(&channel->intent_req_lock);
channel->glink = glink;
channel->name = kstrdup(name, GFP_KERNEL);
diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c
index 5cdaa5f8fb61..892f2b92a4d8 100644
--- a/drivers/rpmsg/qcom_glink_smem.c
+++ b/drivers/rpmsg/qcom_glink_smem.c
@@ -29,8 +29,6 @@
#include <linux/workqueue.h>
#include <linux/list.h>
-#include <linux/delay.h>
-#include <linux/rpmsg.h>
#include <linux/rpmsg/qcom_glink.h>
#include "qcom_glink_native.h"
@@ -185,6 +183,9 @@ static void glink_smem_tx_write(struct qcom_glink_pipe *glink_pipe,
if (head >= pipe->native.length)
head -= pipe->native.length;
+ /* Ensure ordering of fifo and head update */
+ wmb();
+
*pipe->head = cpu_to_le32(head);
}
diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c
index e540ca362d08..8428eba8cb73 100644
--- a/drivers/rpmsg/qcom_smd.c
+++ b/drivers/rpmsg/qcom_smd.c
@@ -200,6 +200,7 @@ struct qcom_smd_channel {
char *name;
enum smd_channel_state state;
enum smd_channel_state remote_state;
+ wait_queue_head_t state_change_event;
struct smd_channel_info_pair *info;
struct smd_channel_info_word_pair *info_word;
@@ -570,13 +571,15 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
if (remote_state != channel->remote_state) {
channel->remote_state = remote_state;
need_state_scan = true;
+
+ wake_up_interruptible_all(&channel->state_change_event);
}
/* Indicate that we have seen any state change */
SET_RX_CHANNEL_FLAG(channel, fSTATE, 0);
/* Signal waiting qcom_smd_send() about the interrupt */
if (!GET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR))
- wake_up_interruptible(&channel->fblockread_event);
+ wake_up_interruptible_all(&channel->fblockread_event);
/* Don't consume any data until we've opened the channel */
if (channel->state != SMD_CHANNEL_OPENED)
@@ -740,28 +743,37 @@ static int __qcom_smd_send(struct qcom_smd_channel *channel, const void *data,
if (ret)
return ret;
- while (qcom_smd_get_tx_avail(channel) < tlen) {
+ while (qcom_smd_get_tx_avail(channel) < tlen &&
+ channel->state == SMD_CHANNEL_OPENED) {
if (!wait) {
ret = -EAGAIN;
- goto out;
- }
-
- if (channel->state != SMD_CHANNEL_OPENED) {
- ret = -EPIPE;
- goto out;
+ goto out_unlock;
}
SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 0);
+ /* Wait without holding the tx_lock */
+ mutex_unlock(&channel->tx_lock);
+
ret = wait_event_interruptible(channel->fblockread_event,
qcom_smd_get_tx_avail(channel) >= tlen ||
channel->state != SMD_CHANNEL_OPENED);
if (ret)
- goto out;
+ return ret;
+
+ ret = mutex_lock_interruptible(&channel->tx_lock);
+ if (ret)
+ return ret;
SET_TX_CHANNEL_FLAG(channel, fBLOCKREADINTR, 1);
}
+ /* Fail if the channel was closed */
+ if (channel->state != SMD_CHANNEL_OPENED) {
+ ret = -EPIPE;
+ goto out_unlock;
+ }
+
SET_TX_CHANNEL_FLAG(channel, fTAIL, 0);
qcom_smd_write_fifo(channel, hdr, sizeof(hdr));
@@ -774,7 +786,7 @@ static int __qcom_smd_send(struct qcom_smd_channel *channel, const void *data,
qcom_smd_signal_channel(channel);
-out:
+out_unlock:
mutex_unlock(&channel->tx_lock);
return ret;
@@ -786,7 +798,9 @@ out:
static int qcom_smd_channel_open(struct qcom_smd_channel *channel,
rpmsg_rx_cb_t cb)
{
+ struct qcom_smd_edge *edge = channel->edge;
size_t bb_size;
+ int ret;
/*
* Packets are maximum 4k, but reduce if the fifo is smaller
@@ -798,9 +812,33 @@ static int qcom_smd_channel_open(struct qcom_smd_channel *channel,
qcom_smd_channel_set_callback(channel, cb);
qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENING);
+
+ /* Wait for remote to enter opening or opened */
+ ret = wait_event_interruptible_timeout(channel->state_change_event,
+ channel->remote_state == SMD_CHANNEL_OPENING ||
+ channel->remote_state == SMD_CHANNEL_OPENED,
+ HZ);
+ if (!ret) {
+ dev_err(&edge->dev, "remote side did not enter opening state\n");
+ goto out_close_timeout;
+ }
+
qcom_smd_channel_set_state(channel, SMD_CHANNEL_OPENED);
+ /* Wait for remote to enter opened */
+ ret = wait_event_interruptible_timeout(channel->state_change_event,
+ channel->remote_state == SMD_CHANNEL_OPENED,
+ HZ);
+ if (!ret) {
+ dev_err(&edge->dev, "remote side did not enter open state\n");
+ goto out_close_timeout;
+ }
+
return 0;
+
+out_close_timeout:
+ qcom_smd_channel_set_state(channel, SMD_CHANNEL_CLOSED);
+ return -ETIMEDOUT;
}
/*
@@ -1055,6 +1093,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
mutex_init(&channel->tx_lock);
spin_lock_init(&channel->recv_lock);
init_waitqueue_head(&channel->fblockread_event);
+ init_waitqueue_head(&channel->state_change_event);
info = qcom_smem_get(edge->remote_pid, smem_info_item, &info_size);
if (IS_ERR(info)) {
@@ -1161,7 +1200,7 @@ static void qcom_channel_scan_worker(struct work_struct *work)
dev_dbg(&edge->dev, "new channel found: '%s'\n", channel->name);
set_bit(i, edge->allocated[tbl]);
- wake_up_interruptible(&edge->new_channel_event);
+ wake_up_interruptible_all(&edge->new_channel_event);
}
}
@@ -1195,11 +1234,6 @@ static void qcom_channel_state_worker(struct work_struct *work)
if (channel->state != SMD_CHANNEL_CLOSED)
continue;
- remote_state = GET_RX_CHANNEL_INFO(channel, state);
- if (remote_state != SMD_CHANNEL_OPENING &&
- remote_state != SMD_CHANNEL_OPENED)
- continue;
-
if (channel->registered)
continue;
diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig
index bc27d716aa6b..1444333210c7 100644
--- a/drivers/s390/block/Kconfig
+++ b/drivers/s390/block/Kconfig
@@ -16,6 +16,7 @@ config BLK_DEV_XPRAM
config DCSSBLK
def_tristate m
select DAX
+ select FS_DAX_LIMITED
prompt "DCSSBLK support"
depends on S390 && BLOCK
help
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 6aaefb780436..9cae08b36b80 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -916,7 +916,8 @@ __dcssblk_direct_access(struct dcssblk_dev_info *dev_info, pgoff_t pgoff,
dev_sz = dev_info->end - dev_info->start + 1;
*kaddr = (void *) dev_info->start + offset;
- *pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV);
+ *pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset),
+ PFN_DEV|PFN_SPECIAL);
return (dev_sz - offset) / PAGE_SIZE;
}
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 2c2e6a3b4c7e..7b31f19ade83 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -251,8 +251,9 @@ static int oprompci2node(void __user *argp, struct device_node *dp, struct openp
struct pci_dev *pdev;
struct device_node *dp;
- pdev = pci_get_bus_and_slot (((int *) op->oprom_array)[0],
- ((int *) op->oprom_array)[1]);
+ pdev = pci_get_domain_bus_and_slot(0,
+ ((int *) op->oprom_array)[0],
+ ((int *) op->oprom_array)[1]);
dp = pci_device_to_OF_node(pdev);
data->current_node = dp;
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index f8c25ee082ef..e68e1d343d53 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -1,19 +1,19 @@
menuconfig STAGING_MEDIA
- bool "Media staging drivers"
- default n
- ---help---
- This option allows you to select a number of media drivers that
+ bool "Media staging drivers"
+ default n
+ ---help---
+ This option allows you to select a number of media drivers that
don't have the "normal" Linux kernel quality level.
Most of them don't follow properly the V4L, DVB and/or RC API's,
so, they won't likely work fine with the existing applications.
That also means that, once fixed, their API's will change to match
the existing ones.
- If you wish to work on these drivers, to help improve them, or
- to report problems you have with them, please use the
+ If you wish to work on these drivers, to help improve them, or
+ to report problems you have with them, please use the
linux-media@vger.kernel.org mailing list.
- If in doubt, say N here.
+ If in doubt, say N here.
if STAGING_MEDIA && MEDIA_SUPPORT
@@ -31,7 +31,6 @@ source "drivers/staging/media/imx/Kconfig"
source "drivers/staging/media/omap4iss/Kconfig"
-# Keep LIRC at the end, as it has sub-menus
-source "drivers/staging/media/lirc/Kconfig"
+source "drivers/staging/media/tegra-vde/Kconfig"
endif
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index be732cf932fd..59a47f69884f 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -2,7 +2,7 @@
obj-$(CONFIG_I2C_BCM2048) += bcm2048/
obj-$(CONFIG_DVB_CXD2099) += cxd2099/
obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx/
-obj-$(CONFIG_LIRC_STAGING) += lirc/
obj-$(CONFIG_VIDEO_DM365_VPFE) += davinci_vpfe/
obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
obj-$(CONFIG_INTEL_ATOMISP) += atomisp/
+obj-$(CONFIG_TEGRA_VDE) += tegra-vde/
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
index e70d8afcc229..61b7598469eb 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c
@@ -1370,13 +1370,9 @@ static int gc0310_probe(struct i2c_client *client)
dev->fmt_idx = 0;
v4l2_i2c_subdev_init(&(dev->sd), client, &gc0310_ops);
- if (ACPI_COMPANION(&client->dev))
- pdata = gmin_camera_platform_data(&dev->sd,
- ATOMISP_INPUT_FORMAT_RAW_8,
- atomisp_bayer_order_grbg);
- else
- pdata = client->dev.platform_data;
-
+ pdata = gmin_camera_platform_data(&dev->sd,
+ ATOMISP_INPUT_FORMAT_RAW_8,
+ atomisp_bayer_order_grbg);
if (!pdata) {
ret = -EINVAL;
goto out_free;
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
index 85da5fe24033..d8de46da64ae 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
@@ -1108,9 +1108,7 @@ static int gc2235_probe(struct i2c_client *client)
dev->fmt_idx = 0;
v4l2_i2c_subdev_init(&(dev->sd), client, &gc2235_ops);
- gcpdev = client->dev.platform_data;
- if (ACPI_COMPANION(&client->dev))
- gcpdev = gmin_camera_platform_data(&dev->sd,
+ gcpdev = gmin_camera_platform_data(&dev->sd,
ATOMISP_INPUT_FORMAT_RAW_10,
atomisp_bayer_order_grbg);
@@ -1147,10 +1145,8 @@ static int gc2235_probe(struct i2c_client *client)
if (ret)
gc2235_remove(client);
- if (ACPI_HANDLE(&client->dev))
- ret = atomisp_register_i2c_module(&dev->sd, gcpdev, RAW_CAMERA);
+ return atomisp_register_i2c_module(&dev->sd, gcpdev, RAW_CAMERA);
- return ret;
out_free:
v4l2_device_unregister_subdev(&dev->sd);
kfree(dev);
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c
index 4fd9f538ac95..7098bf317f16 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c
@@ -562,10 +562,10 @@ static const struct v4l2_ctrl_config lm3554_controls[] = {
{
.ops = &ctrl_ops,
.id = V4L2_CID_FLASH_STATUS,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
.name = "Flash Status",
- .min = 0,
- .max = 100,
+ .min = ATOMISP_FLASH_STATUS_OK,
+ .max = ATOMISP_FLASH_STATUS_TIMEOUT,
.step = 1,
.def = ATOMISP_FLASH_STATUS_OK,
.flags = 0,
@@ -574,10 +574,10 @@ static const struct v4l2_ctrl_config lm3554_controls[] = {
{
.ops = &ctrl_ops,
.id = V4L2_CID_FLASH_STATUS_REGISTER,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
.name = "Flash Status Register",
.min = 0,
- .max = 100,
+ .max = 255,
.step = 1,
.def = 0,
.flags = 0,
@@ -824,22 +824,15 @@ static void *lm3554_platform_data_func(struct i2c_client *client)
{
static struct lm3554_platform_data platform_data;
- if (ACPI_COMPANION(&client->dev)) {
- platform_data.gpio_reset =
- desc_to_gpio(gpiod_get_index(&(client->dev),
+ platform_data.gpio_reset =
+ desc_to_gpio(gpiod_get_index(&client->dev,
NULL, 2, GPIOD_OUT_LOW));
- platform_data.gpio_strobe =
- desc_to_gpio(gpiod_get_index(&(client->dev),
+ platform_data.gpio_strobe =
+ desc_to_gpio(gpiod_get_index(&client->dev,
NULL, 0, GPIOD_OUT_LOW));
- platform_data.gpio_torch =
- desc_to_gpio(gpiod_get_index(&(client->dev),
+ platform_data.gpio_torch =
+ desc_to_gpio(gpiod_get_index(&client->dev,
NULL, 1, GPIOD_OUT_LOW));
- } else {
- platform_data.gpio_reset = -1;
- platform_data.gpio_strobe = -1;
- platform_data.gpio_torch = -1;
- }
-
dev_info(&client->dev, "camera pdata: lm3554: reset: %d strobe %d torch %d\n",
platform_data.gpio_reset, platform_data.gpio_strobe,
platform_data.gpio_torch);
@@ -868,10 +861,7 @@ static int lm3554_probe(struct i2c_client *client)
if (!flash)
return -ENOMEM;
- flash->pdata = client->dev.platform_data;
-
- if (!flash->pdata || ACPI_COMPANION(&client->dev))
- flash->pdata = lm3554_platform_data_func(client);
+ flash->pdata = lm3554_platform_data_func(client);
v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops);
flash->sd.internal_ops = &lm3554_internal_ops;
@@ -914,9 +904,7 @@ static int lm3554_probe(struct i2c_client *client)
dev_err(&client->dev, "gpio request/direction_output fail");
goto fail2;
}
- if (ACPI_HANDLE(&client->dev))
- err = atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH);
- return 0;
+ return atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH);
fail2:
media_entity_cleanup(&flash->sd.entity);
v4l2_ctrl_handler_free(&flash->ctrl_handler);
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
index 55882bea2049..df253a557c76 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-mt9m114.c
@@ -1844,11 +1844,9 @@ static int mt9m114_probe(struct i2c_client *client)
return -ENOMEM;
v4l2_i2c_subdev_init(&dev->sd, client, &mt9m114_ops);
- pdata = client->dev.platform_data;
- if (ACPI_COMPANION(&client->dev))
- pdata = gmin_camera_platform_data(&dev->sd,
- ATOMISP_INPUT_FORMAT_RAW_10,
- atomisp_bayer_order_grbg);
+ pdata = gmin_camera_platform_data(&dev->sd,
+ ATOMISP_INPUT_FORMAT_RAW_10,
+ atomisp_bayer_order_grbg);
if (pdata)
ret = mt9m114_s_config(&dev->sd, client->irq, pdata);
if (!pdata || ret) {
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index cd67d38f183a..84f8d33ce2d1 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -1447,13 +1447,9 @@ static int ov2680_probe(struct i2c_client *client)
dev->fmt_idx = 0;
v4l2_i2c_subdev_init(&(dev->sd), client, &ov2680_ops);
- if (ACPI_COMPANION(&client->dev))
- pdata = gmin_camera_platform_data(&dev->sd,
- ATOMISP_INPUT_FORMAT_RAW_10,
- atomisp_bayer_order_bggr);
- else
- pdata = client->dev.platform_data;
-
+ pdata = gmin_camera_platform_data(&dev->sd,
+ ATOMISP_INPUT_FORMAT_RAW_10,
+ atomisp_bayer_order_bggr);
if (!pdata) {
ret = -EINVAL;
goto out_free;
diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
index 4df7eba8d375..2b6ae0faf972 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c
@@ -1259,7 +1259,6 @@ static int ov2722_probe(struct i2c_client *client)
struct ov2722_device *dev;
void *ovpdev;
int ret;
- struct acpi_device *adev;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
@@ -1270,14 +1269,9 @@ static int ov2722_probe(struct i2c_client *client)
dev->fmt_idx = 0;
v4l2_i2c_subdev_init(&(dev->sd), client, &ov2722_ops);
- ovpdev = client->dev.platform_data;
- adev = ACPI_COMPANION(&client->dev);
- if (adev) {
- adev->power.flags.power_resources = 0;
- ovpdev = gmin_camera_platform_data(&dev->sd,
- ATOMISP_INPUT_FORMAT_RAW_10,
- atomisp_bayer_order_grbg);
- }
+ ovpdev = gmin_camera_platform_data(&dev->sd,
+ ATOMISP_INPUT_FORMAT_RAW_10,
+ atomisp_bayer_order_grbg);
ret = ov2722_s_config(&dev->sd, client->irq, ovpdev);
if (ret)
@@ -1296,10 +1290,7 @@ static int ov2722_probe(struct i2c_client *client)
if (ret)
ov2722_remove(client);
- if (ACPI_HANDLE(&client->dev))
- ret = atomisp_register_i2c_module(&dev->sd, ovpdev, RAW_CAMERA);
-
- return ret;
+ return atomisp_register_i2c_module(&dev->sd, ovpdev, RAW_CAMERA);
out_ctrl_handler_free:
v4l2_ctrl_handler_free(&dev->ctrl_handler);
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index bf4897347df7..03f75dd80f87 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -174,7 +174,6 @@ struct ov2680_format {
struct mutex input_lock;
struct v4l2_ctrl_handler ctrl_handler;
struct camera_sensor_platform_data *platform_data;
- struct timespec timestamp_t_focus_abs;
int vt_pix_clk_freq_mhz;
int fmt_idx;
int run_mode;
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
index 3e7c3851280f..40d01bf4bf28 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
+++ b/drivers/staging/media/atomisp/i2c/ov5693/atomisp-ov5693.c
@@ -82,6 +82,7 @@ static int ad5823_i2c_write(struct i2c_client *client, u8 reg, u8 val)
{
struct i2c_msg msg;
u8 buf[2];
+
buf[0] = reg;
buf[1] = val;
msg.addr = AD5823_VCM_ADDR;
@@ -98,6 +99,7 @@ static int ad5823_i2c_read(struct i2c_client *client, u8 reg, u8 *val)
{
struct i2c_msg msg[2];
u8 buf[2];
+
buf[0] = reg;
buf[1] = 0;
@@ -211,7 +213,8 @@ static int vcm_dw_i2c_write(struct i2c_client *client, u16 data)
return ret == num_msg ? 0 : -EIO;
}
-/* Theory: per datasheet, the two VCMs both allow for a 2-byte read.
+/*
+ * Theory: per datasheet, the two VCMs both allow for a 2-byte read.
* The DW9714 doesn't actually specify what this does (it has a
* two-byte write-only protocol, but specifies the read sequence as
* legal), but it returns the same data (zeroes) always, after an
@@ -222,12 +225,14 @@ static int vcm_dw_i2c_write(struct i2c_client *client, u16 data)
* these) in AD5823 are not pairwise repetitions of the same 16 bit
* word. So all we have to do is sequentially read two bytes at a
* time and see if we detect a difference in any of the first four
- * pairs. */
+ * pairs.
+ */
static int vcm_detect(struct i2c_client *client)
{
int i, ret;
struct i2c_msg msg;
u16 data0 = 0, data;
+
for (i = 0; i < 4; i++) {
msg.addr = VCM_ADDR;
msg.flags = I2C_M_RD;
@@ -235,8 +240,10 @@ static int vcm_detect(struct i2c_client *client)
msg.buf = (u8 *)&data;
ret = i2c_transfer(client->adapter, &msg, 1);
- /* DW9714 always fails the first read and returns
- * zeroes for subsequent ones */
+ /*
+ * DW9714 always fails the first read and returns
+ * zeroes for subsequent ones
+ */
if (i == 0 && ret == -EREMOTEIO) {
data0 = 0;
continue;
@@ -530,9 +537,11 @@ static long __ov5693_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
hts = ov5693_res[dev->fmt_idx].pixels_per_line;
vts = ov5693_res[dev->fmt_idx].lines_per_frame;
- /*If coarse_itg is larger than 1<<15, can not write to reg directly.
- The way is to write coarse_itg/2 to the reg, meanwhile write 2*hts
- to the reg. */
+ /*
+ * If coarse_itg is larger than 1<<15, can not write to reg directly.
+ * The way is to write coarse_itg/2 to the reg, meanwhile write 2*hts
+ * to the reg.
+ */
if (coarse_itg > (1 << 15)) {
hts = hts * 2;
coarse_itg = (int)coarse_itg / 2;
@@ -690,6 +699,7 @@ static long ov5693_s_exposure(struct v4l2_subdev *sd,
/* we should not accept the invalid value below */
if (analog_gain == 0) {
struct i2c_client *client = v4l2_get_subdevdata(sd);
+
v4l2_err(client, "%s: invalid value\n", __func__);
return -EINVAL;
}
@@ -722,6 +732,7 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
int ret;
int i;
u8 *b = buf;
+
dev->otp_size = 0;
for (i = 1; i < OV5693_OTP_BANK_MAX; i++) {
/*set bank NO and OTP read mode. */
@@ -753,7 +764,7 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
//pr_debug("BANK[%2d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i, *b, *(b+1), *(b+2), *(b+3), *(b+4), *(b+5), *(b+6), *(b+7), *(b+8), *(b+9), *(b+10), *(b+11), *(b+12), *(b+13), *(b+14), *(b+15));
//Intel OTP map, try to read 320byts first.
- if (21 == i) {
+ if (i == 21) {
if ((*b) == 0) {
dev->otp_size = 320;
break;
@@ -761,15 +772,15 @@ static int __ov5693_otp_read(struct v4l2_subdev *sd, u8 *buf)
b = buf;
continue;
}
- } else if (24 == i) { //if the first 320bytes data doesn't not exist, try to read the next 32bytes data.
+ } else if (i == 24) { //if the first 320bytes data doesn't not exist, try to read the next 32bytes data.
if ((*b) == 0) {
dev->otp_size = 32;
break;
- } else {
+ } else {
b = buf;
continue;
}
- } else if (27 == i) { //if the prvious 32bytes data doesn't exist, try to read the next 32bytes data again.
+ } else if (i == 27) { //if the prvious 32bytes data doesn't exist, try to read the next 32bytes data again.
if ((*b) == 0) {
dev->otp_size = 32;
break;
@@ -875,8 +886,10 @@ static long ov5693_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
return 0;
}
-/* This returns the exposure time being used. This should only be used
- for filling in EXIF data, not for actual image processing. */
+/*
+ * This returns the exposure time being used. This should only be used
+ * for filling in EXIF data, not for actual image processing.
+ */
static int ov5693_q_exposure(struct v4l2_subdev *sd, s32 *value)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -973,7 +986,7 @@ static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
if (ret == 0) {
dev->number_of_steps = value - dev->focus;
dev->focus = value;
- getnstimeofday(&(dev->timestamp_t_focus_abs));
+ dev->timestamp_t_focus_abs = ktime_get();
} else
dev_err(&client->dev,
"%s: i2c failed. ret %d\n", __func__, ret);
@@ -984,6 +997,7 @@ static int ov5693_t_focus_abs(struct v4l2_subdev *sd, s32 value)
static int ov5693_t_focus_rel(struct v4l2_subdev *sd, s32 value)
{
struct ov5693_device *dev = to_ov5693_sensor(sd);
+
return ov5693_t_focus_abs(sd, dev->focus + value);
}
@@ -993,16 +1007,13 @@ static int ov5693_q_focus_status(struct v4l2_subdev *sd, s32 *value)
{
u32 status = 0;
struct ov5693_device *dev = to_ov5693_sensor(sd);
- struct timespec temptime;
- const struct timespec timedelay = {
- 0,
- min((u32)abs(dev->number_of_steps) * DELAY_PER_STEP_NS,
- (u32)DELAY_MAX_PER_STEP_NS),
- };
-
- getnstimeofday(&temptime);
- temptime = timespec_sub(temptime, (dev->timestamp_t_focus_abs));
- if (timespec_compare(&temptime, &timedelay) <= 0) {
+ ktime_t temptime;
+ ktime_t timedelay = ns_to_ktime(min_t(u32,
+ abs(dev->number_of_steps) * DELAY_PER_STEP_NS,
+ DELAY_MAX_PER_STEP_NS));
+
+ temptime = ktime_sub(ktime_get(), (dev->timestamp_t_focus_abs));
+ if (ktime_compare(temptime, timedelay) <= 0) {
status |= ATOMISP_FOCUS_STATUS_MOVING;
status |= ATOMISP_FOCUS_HP_IN_PROGRESS;
} else {
@@ -1033,6 +1044,7 @@ static int ov5693_q_focus_abs(struct v4l2_subdev *sd, s32 *value)
static int ov5693_t_vcm_slew(struct v4l2_subdev *sd, s32 value)
{
struct ov5693_device *dev = to_ov5693_sensor(sd);
+
dev->number_of_steps = value;
dev->vcm_update = true;
return 0;
@@ -1041,6 +1053,7 @@ static int ov5693_t_vcm_slew(struct v4l2_subdev *sd, s32 value)
static int ov5693_t_vcm_timing(struct v4l2_subdev *sd, s32 value)
{
struct ov5693_device *dev = to_ov5693_sensor(sd);
+
dev->number_of_steps = value;
dev->vcm_update = true;
return 0;
@@ -1293,11 +1306,13 @@ static int power_ctrl(struct v4l2_subdev *sd, bool flag)
if (!dev || !dev->platform_data)
return -ENODEV;
- /* This driver assumes "internal DVDD, PWDNB tied to DOVDD".
+ /*
+ * This driver assumes "internal DVDD, PWDNB tied to DOVDD".
* In this set up only gpio0 (XSHUTDN) should be available
* but in some products (for example ECS) gpio1 (PWDNB) is
* also available. If gpio1 is available we emulate it being
- * tied to DOVDD here. */
+ * tied to DOVDD here.
+ */
if (flag) {
ret = dev->platform_data->v2p8_ctrl(sd, 1);
dev->platform_data->gpio1_ctrl(sd, 1);
@@ -1333,7 +1348,7 @@ static int __power_up(struct v4l2_subdev *sd)
struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
- if (NULL == dev->platform_data) {
+ if (!dev->platform_data) {
dev_err(&client->dev,
"no camera_sensor_platform_data");
return -ENODEV;
@@ -1381,7 +1396,7 @@ static int power_down(struct v4l2_subdev *sd)
int ret = 0;
dev->focus = OV5693_INVALID_CONFIG;
- if (NULL == dev->platform_data) {
+ if (!dev->platform_data) {
dev_err(&client->dev,
"no camera_sensor_platform_data");
return -ENODEV;
@@ -1563,6 +1578,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
struct camera_mipi_info *ov5693_info = NULL;
int ret = 0;
int idx;
+
if (format->pad)
return -EINVAL;
if (!fmt)
@@ -1599,6 +1615,7 @@ static int ov5693_set_fmt(struct v4l2_subdev *sd,
ret = startup(sd);
if (ret) {
int i = 0;
+
dev_err(&client->dev, "ov5693 startup err, retry to power up\n");
for (i = 0; i < OV5693_POWER_UP_RETRY_NUM; i++) {
dev_err(&client->dev,
@@ -1655,6 +1672,7 @@ static int ov5693_get_fmt(struct v4l2_subdev *sd,
{
struct v4l2_mbus_framefmt *fmt = &format->format;
struct ov5693_device *dev = to_ov5693_sensor(sd);
+
if (format->pad)
return -EINVAL;
@@ -1818,6 +1836,7 @@ static int ov5693_s_parm(struct v4l2_subdev *sd,
struct v4l2_streamparm *param)
{
struct ov5693_device *dev = to_ov5693_sensor(sd);
+
dev->run_mode = param->parm.capture.capturemode;
mutex_lock(&dev->input_lock);
@@ -1907,6 +1926,7 @@ static int ov5693_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct ov5693_device *dev = to_ov5693_sensor(sd);
+
dev_dbg(&client->dev, "ov5693_remove...\n");
dev->platform_data->csi_cfg(sd, 0);
@@ -1928,13 +1948,14 @@ static int ov5693_probe(struct i2c_client *client)
int i2c;
int ret = 0;
void *pdata = client->dev.platform_data;
- struct acpi_device *adev;
unsigned int i;
- /* Firmware workaround: Some modules use a "secondary default"
+ /*
+ * Firmware workaround: Some modules use a "secondary default"
* address of 0x10 which doesn't appear on schematics, and
* some BIOS versions haven't gotten the memo. Work around
- * via config. */
+ * via config.
+ */
i2c = gmin_get_var_int(&client->dev, "I2CAddr", -1);
if (i2c != -1) {
dev_info(&client->dev,
@@ -1952,14 +1973,9 @@ static int ov5693_probe(struct i2c_client *client)
dev->fmt_idx = 0;
v4l2_i2c_subdev_init(&(dev->sd), client, &ov5693_ops);
- adev = ACPI_COMPANION(&client->dev);
- if (adev) {
- adev->power.flags.power_resources = 0;
- pdata = gmin_camera_platform_data(&dev->sd,
- ATOMISP_INPUT_FORMAT_RAW_10,
- atomisp_bayer_order_bggr);
- }
-
+ pdata = gmin_camera_platform_data(&dev->sd,
+ ATOMISP_INPUT_FORMAT_RAW_10,
+ atomisp_bayer_order_bggr);
if (!pdata)
goto out_free;
diff --git a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
index 2ea63807c56d..68cfcb4a6c3c 100644
--- a/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
+++ b/drivers/staging/media/atomisp/i2c/ov5693/ov5693.h
@@ -221,7 +221,7 @@ struct ov5693_device {
struct v4l2_ctrl_handler ctrl_handler;
struct camera_sensor_platform_data *platform_data;
- struct timespec timestamp_t_focus_abs;
+ ktime_t timestamp_t_focus_abs;
int vt_pix_clk_freq_mhz;
int fmt_idx;
int run_mode;
diff --git a/drivers/staging/media/atomisp/i2c/ov8858.c b/drivers/staging/media/atomisp/i2c/ov8858.c
index ba147ac2e36f..3cf8c710ac65 100644
--- a/drivers/staging/media/atomisp/i2c/ov8858.c
+++ b/drivers/staging/media/atomisp/i2c/ov8858.c
@@ -2077,29 +2077,28 @@ static int ov8858_probe(struct i2c_client *client)
v4l2_i2c_subdev_init(&(dev->sd), client, &ov8858_ops);
- if (ACPI_COMPANION(&client->dev)) {
- pdata = gmin_camera_platform_data(&dev->sd,
- ATOMISP_INPUT_FORMAT_RAW_10,
- atomisp_bayer_order_bggr);
- if (!pdata) {
- dev_err(&client->dev,
- "%s: failed to get acpi platform data\n",
- __func__);
- goto out_free;
- }
- ret = ov8858_s_config(&dev->sd, client->irq, pdata);
- if (ret) {
- dev_err(&client->dev,
- "%s: failed to set config\n", __func__);
- goto out_free;
- }
- ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA);
- if (ret) {
- dev_err(&client->dev,
- "%s: failed to register subdev\n", __func__);
- goto out_free;
- }
+ pdata = gmin_camera_platform_data(&dev->sd,
+ ATOMISP_INPUT_FORMAT_RAW_10,
+ atomisp_bayer_order_bggr);
+ if (!pdata) {
+ dev_err(&client->dev,
+ "%s: failed to get acpi platform data\n",
+ __func__);
+ goto out_free;
+ }
+ ret = ov8858_s_config(&dev->sd, client->irq, pdata);
+ if (ret) {
+ dev_err(&client->dev,
+ "%s: failed to set config\n", __func__);
+ goto out_free;
}
+ ret = atomisp_register_i2c_module(&dev->sd, pdata, RAW_CAMERA);
+ if (ret) {
+ dev_err(&client->dev,
+ "%s: failed to register subdev\n", __func__);
+ goto out_free;
+ }
+
/*
* sd->name is updated with sensor driver name by the v4l2.
* change it to sensor name in this case.
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp.h b/drivers/staging/media/atomisp/include/linux/atomisp.h
index 15fa5679bae7..ebe193ba3871 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp.h
@@ -68,7 +68,9 @@
#define V4L2_MBUS_FMT_CUSTOM_RGB32 0x800a
/* Custom media bus format for M10MO RAW capture */
+#if 0
#define V4L2_MBUS_FMT_CUSTOM_M10MO_RAW 0x800b
+#endif
/* Configuration used by Bayer noise reduction and YCC noise reduction */
struct atomisp_nr_config {
diff --git a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
index 7e3ca12dd4e9..c52c56a17e17 100644
--- a/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
+++ b/drivers/staging/media/atomisp/include/linux/atomisp_gmin_platform.h
@@ -23,7 +23,6 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
struct v4l2_subdev *atomisp_gmin_find_subdev(struct i2c_adapter *adapter,
struct i2c_board_info *board_info);
int atomisp_gmin_remove_subdev(struct v4l2_subdev *sd);
-int gmin_get_config_var(struct device *dev, const char *var, char *out, size_t *out_len);
int gmin_get_var_int(struct device *dev, const char *var, int def);
int camera_sensor_csi(struct v4l2_subdev *sd, u32 port,
u32 lanes, u32 format, u32 bayer_order, int flag);
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c
index 7129b88456cb..ceedb82b6beb 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.c
@@ -15,9 +15,9 @@
*
*/
+#include <linux/device.h>
#include <linux/err.h>
#include <linux/kernel.h>
-#include <linux/pci.h>
#include "atomisp_compat.h"
#include "atomisp_internal.h"
@@ -33,7 +33,7 @@
* bit 2: memory statistic
*/
struct _iunit_debug {
- struct pci_driver *drv;
+ struct device_driver *drv;
struct atomisp_device *isp;
unsigned int dbglvl;
unsigned int dbgfun;
@@ -164,26 +164,25 @@ static const struct driver_attribute iunit_drvfs_attrs[] = {
__ATTR(dbgopt, 0644, iunit_dbgopt_show, iunit_dbgopt_store),
};
-static int iunit_drvfs_create_files(struct pci_driver *drv)
+static int iunit_drvfs_create_files(struct device_driver *drv)
{
int i, ret = 0;
for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++)
- ret |= driver_create_file(&(drv->driver),
- &iunit_drvfs_attrs[i]);
+ ret |= driver_create_file(drv, &iunit_drvfs_attrs[i]);
return ret;
}
-static void iunit_drvfs_remove_files(struct pci_driver *drv)
+static void iunit_drvfs_remove_files(struct device_driver *drv)
{
int i;
for (i = 0; i < ARRAY_SIZE(iunit_drvfs_attrs); i++)
- driver_remove_file(&(drv->driver), &iunit_drvfs_attrs[i]);
+ driver_remove_file(drv, &iunit_drvfs_attrs[i]);
}
-int atomisp_drvfs_init(struct pci_driver *drv, struct atomisp_device *isp)
+int atomisp_drvfs_init(struct device_driver *drv, struct atomisp_device *isp)
{
int ret;
@@ -193,7 +192,7 @@ int atomisp_drvfs_init(struct pci_driver *drv, struct atomisp_device *isp)
ret = iunit_drvfs_create_files(iunit_debug.drv);
if (ret) {
dev_err(atomisp_dev, "drvfs_create_files error: %d\n", ret);
- iunit_drvfs_remove_files(drv);
+ iunit_drvfs_remove_files(iunit_debug.drv);
}
return ret;
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h
index b91bfef21639..7c99240d107a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_drvfs.h
@@ -18,8 +18,7 @@
#ifndef __ATOMISP_DRVFS_H__
#define __ATOMISP_DRVFS_H__
-extern int atomisp_drvfs_init(struct pci_driver *drv, struct atomisp_device
- *isp);
-extern void atomisp_drvfs_exit(void);
+int atomisp_drvfs_init(struct device_driver *drv, struct atomisp_device *isp);
+void atomisp_drvfs_exit(void);
#endif /* __ATOMISP_DRVFS_H__ */
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h
index 52a6f8002048..dc476a3dd271 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_internal.h
@@ -227,7 +227,6 @@ struct atomisp_device {
struct media_device media_dev;
struct atomisp_platform_data *pdata;
void *mmu_l1_base;
- struct pci_dev *pci_root;
const struct firmware *firmware;
struct pm_qos_request pm_qos;
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c
index 339b5d31e1f1..5c84dd63778e 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_ioctl.c
@@ -501,7 +501,9 @@ const struct atomisp_format_bridge atomisp_output_fmts[] = {
.mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
.sh_fmt = CSS_FRAME_FORMAT_BINARY_8,
.description = "JPEG"
- }, {
+ },
+#if 0
+ {
/* This is a custom format being used by M10MO to send the RAW data */
.pixelformat = V4L2_PIX_FMT_CUSTOM_M10MO_RAW,
.depth = 8,
@@ -509,6 +511,7 @@ const struct atomisp_format_bridge atomisp_output_fmts[] = {
.sh_fmt = CSS_FRAME_FORMAT_BINARY_8,
.description = "Custom RAW for M10MO"
},
+#endif
};
const struct atomisp_format_bridge *atomisp_get_format_bridge(
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c
index 70b53988553c..f3e18d627b0a 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_subdev.c
@@ -48,7 +48,9 @@ const struct atomisp_in_fmt_conv atomisp_in_fmt_conv[] = {
{ V4L2_MBUS_FMT_CUSTOM_NV12, 12, 12, CSS_FRAME_FORMAT_NV12, 0, CSS_FRAME_FORMAT_NV12 },
{ V4L2_MBUS_FMT_CUSTOM_NV21, 12, 12, CSS_FRAME_FORMAT_NV21, 0, CSS_FRAME_FORMAT_NV21 },
{ V4L2_MBUS_FMT_CUSTOM_YUV420, 12, 12, ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY, 0, IA_CSS_STREAM_FORMAT_YUV420_8_LEGACY },
+#if 0
{ V4L2_MBUS_FMT_CUSTOM_M10MO_RAW, 8, 8, CSS_FRAME_FORMAT_BINARY_8, 0, IA_CSS_STREAM_FORMAT_BINARY_8 },
+#endif
/* no valid V4L2 MBUS code for metadata format, so leave it 0. */
{ 0, 0, 0, ATOMISP_INPUT_FORMAT_EMBEDDED, 0, IA_CSS_STREAM_FORMAT_EMBEDDED },
{}
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c
index 3c260f8b52e2..548e00e7d67b 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/atomisp_v4l2.c
@@ -1152,8 +1152,6 @@ alloc_fail:
return err;
}
-static struct pci_driver atomisp_pci_driver;
-
#define ATOM_ISP_PCI_BAR 0
static int atomisp_pci_probe(struct pci_dev *dev,
@@ -1212,11 +1210,6 @@ static int atomisp_pci_probe(struct pci_dev *dev,
isp->pdev = dev;
isp->dev = &dev->dev;
isp->sw_contex.power_state = ATOM_ISP_POWER_UP;
- isp->pci_root = pci_get_bus_and_slot(0, 0);
- if (!isp->pci_root) {
- dev_err(&dev->dev, "Unable to find PCI host\n");
- return -ENODEV;
- }
isp->saved_regs.ispmmadr = start;
rt_mutex_init(&isp->mutex);
@@ -1451,7 +1444,7 @@ static int atomisp_pci_probe(struct pci_dev *dev,
isp->firmware = NULL;
isp->css_env.isp_css_fw.data = NULL;
- atomisp_drvfs_init(&atomisp_pci_driver, isp);
+ atomisp_drvfs_init(&dev->driver->driver, isp);
return 0;
@@ -1496,7 +1489,6 @@ load_fw_fail:
/* Address later when we worry about the ...field chips */
if (IS_ENABLED(CONFIG_PM) && atomisp_mrfld_power_down(isp))
dev_err(&dev->dev, "Failed to switch off ISP\n");
- pci_dev_put(isp->pci_root);
return err;
}
@@ -1517,8 +1509,6 @@ static void atomisp_pci_remove(struct pci_dev *dev)
pm_qos_remove_request(&isp->pm_qos);
atomisp_msi_irq_uninit(isp, dev);
- pci_dev_put(isp->pci_root);
-
atomisp_unregister_entities(isp);
destroy_workqueue(isp->wdt_work_queue);
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8.host.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8.host.c
index 682f8b709ff9..47bb5042381b 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8.host.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/eed1_8/ia_css_eed1_8.host.c
@@ -32,44 +32,44 @@
#define NUMBER_OF_TCINV_POINTS 9
#define NUMBER_OF_FCINV_POINTS 9
-const int16_t chgrinv_x[NUMBER_OF_CHGRINV_POINTS] = {
+static const int16_t chgrinv_x[NUMBER_OF_CHGRINV_POINTS] = {
0, 16, 64, 144, 272, 448, 672, 976,
1376, 1888, 2528, 3312, 4256, 5376, 6688};
-const int16_t chgrinv_a[NUMBER_OF_CHGRINV_POINTS] = {
+static const int16_t chgrinv_a[NUMBER_OF_CHGRINV_POINTS] = {
-7171, -256, -29, -3456, -1071, -475, -189, -102,
-48, -38, -10, -9, -7, -6, 0};
-const int16_t chgrinv_b[NUMBER_OF_CHGRINV_POINTS] = {
+static const int16_t chgrinv_b[NUMBER_OF_CHGRINV_POINTS] = {
8191, 1021, 256, 114, 60, 37, 24, 17,
12, 9, 6, 5, 4, 3, 2};
-const int16_t chgrinv_c[NUMBER_OF_CHGRINV_POINTS] = {
+static const int16_t chgrinv_c[NUMBER_OF_CHGRINV_POINTS] = {
1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0};
-const int16_t tcinv_x[NUMBER_OF_TCINV_POINTS] = {
+static const int16_t tcinv_x[NUMBER_OF_TCINV_POINTS] = {
0, 4, 11, 23, 42, 68, 102, 148, 205};
-const int16_t tcinv_a[NUMBER_OF_TCINV_POINTS] = {
+static const int16_t tcinv_a[NUMBER_OF_TCINV_POINTS] = {
-6364, -631, -126, -34, -13, -6, -4452, -2156, 0};
-const int16_t tcinv_b[NUMBER_OF_TCINV_POINTS] = {
+static const int16_t tcinv_b[NUMBER_OF_TCINV_POINTS] = {
8191, 1828, 726, 352, 197, 121, 80, 55, 40};
-const int16_t tcinv_c[NUMBER_OF_TCINV_POINTS] = {
+static const int16_t tcinv_c[NUMBER_OF_TCINV_POINTS] = {
1, 1, 1, 1, 1, 1, 0, 0, 0};
-const int16_t fcinv_x[NUMBER_OF_FCINV_POINTS] = {
+static const int16_t fcinv_x[NUMBER_OF_FCINV_POINTS] = {
0, 80, 216, 456, 824, 1344, 2040, 2952, 4096};
-const int16_t fcinv_a[NUMBER_OF_FCINV_POINTS] = {
+static const int16_t fcinv_a[NUMBER_OF_FCINV_POINTS] = {
-5244, -486, -86, -2849, -961, -400, -180, -86, 0};
-const int16_t fcinv_b[NUMBER_OF_FCINV_POINTS] = {
+static const int16_t fcinv_b[NUMBER_OF_FCINV_POINTS] = {
8191, 1637, 607, 287, 159, 98, 64, 44, 32};
-const int16_t fcinv_c[NUMBER_OF_FCINV_POINTS] = {
+static const int16_t fcinv_c[NUMBER_OF_FCINV_POINTS] = {
1, 1, 1, 0, 0, 0, 0, 0, 0};
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c
index dd1127a21494..f22d73b56bc6 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/debug/src/ia_css_debug.c
@@ -2567,6 +2567,7 @@ ia_css_debug_mode_enable_dma_channel(int dma_id,
return rc;
}
+static
void dtrace_dot(const char *fmt, ...)
{
va_list ap;
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h
index 2283dd1c1c9b..fa3f09347b22 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h
+++ b/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/isp_param/interface/ia_css_isp_param_types.h
@@ -95,7 +95,7 @@ union ia_css_all_memory_offsets {
};
#define IA_CSS_DEFAULT_ISP_MEM_PARAMS \
- { { { { 0, 0 } } } }
+ { { { { NULL, 0 } } } }
#define IA_CSS_DEFAULT_ISP_CSS_PARAMS \
{ { { { 0, 0 } } } }
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c
index a1c81c12718c..4338b8a1309f 100644
--- a/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c
+++ b/drivers/staging/media/atomisp/pci/atomisp2/hmm/hmm.c
@@ -158,10 +158,10 @@ static ssize_t dynamic_pool_show(struct device *dev,
return ret;
};
-static DEVICE_ATTR(active_bo, 0444, active_bo_show, NULL);
-static DEVICE_ATTR(free_bo, 0444, free_bo_show, NULL);
-static DEVICE_ATTR(reserved_pool, 0444, reserved_pool_show, NULL);
-static DEVICE_ATTR(dynamic_pool, 0444, dynamic_pool_show, NULL);
+static DEVICE_ATTR_RO(active_bo);
+static DEVICE_ATTR_RO(free_bo);
+static DEVICE_ATTR_RO(reserved_pool);
+static DEVICE_ATTR_RO(dynamic_pool);
static struct attribute *sysfs_attrs_ctrl[] = {
&dev_attr_active_bo.attr,
diff --git a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
index bf9f34b7ad72..d8b7183db252 100644
--- a/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
+++ b/drivers/staging/media/atomisp/platform/intel-mid/atomisp_gmin_platform.c
@@ -114,7 +114,7 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
struct i2c_board_info *bi;
struct gmin_subdev *gs;
struct i2c_client *client = v4l2_get_subdevdata(subdev);
- struct acpi_device *adev;
+ struct acpi_device *adev = ACPI_COMPANION(&client->dev);
dev_info(&client->dev, "register atomisp i2c module type %d\n", type);
@@ -124,9 +124,7 @@ int atomisp_register_i2c_module(struct v4l2_subdev *subdev,
* tickled during suspend/resume. This has caused power and
* performance issues on multiple devices.
*/
- adev = ACPI_COMPANION(&client->dev);
- if (adev)
- adev->power.flags.power_resources = 0;
+ adev->power.flags.power_resources = 0;
for (i = 0; i < MAX_SUBDEVS; i++)
if (!pdata.subdevs[i].type)
@@ -211,7 +209,7 @@ struct gmin_cfg_var {
const char *name, *val;
};
-static const struct gmin_cfg_var ffrd8_vars[] = {
+static struct gmin_cfg_var ffrd8_vars[] = {
{ "INTCF1B:00_ImxId", "0x134" },
{ "INTCF1B:00_CsiPort", "1" },
{ "INTCF1B:00_CsiLanes", "4" },
@@ -222,14 +220,14 @@ static const struct gmin_cfg_var ffrd8_vars[] = {
/* Cribbed from MCG defaults in the mt9m114 driver, not actually verified
* vs. T100 hardware
*/
-static const struct gmin_cfg_var t100_vars[] = {
+static struct gmin_cfg_var t100_vars[] = {
{ "INT33F0:00_CsiPort", "0" },
{ "INT33F0:00_CsiLanes", "1" },
{ "INT33F0:00_CamClk", "1" },
{},
};
-static const struct gmin_cfg_var mrd7_vars[] = {
+static struct gmin_cfg_var mrd7_vars[] = {
{"INT33F8:00_CamType", "1"},
{"INT33F8:00_CsiPort", "1"},
{"INT33F8:00_CsiLanes", "2"},
@@ -245,7 +243,7 @@ static const struct gmin_cfg_var mrd7_vars[] = {
{},
};
-static const struct gmin_cfg_var ecs7_vars[] = {
+static struct gmin_cfg_var ecs7_vars[] = {
{"INT33BE:00_CsiPort", "1"},
{"INT33BE:00_CsiLanes", "2"},
{"INT33BE:00_CsiFmt", "13"},
@@ -260,8 +258,7 @@ static const struct gmin_cfg_var ecs7_vars[] = {
{},
};
-
-static const struct gmin_cfg_var i8880_vars[] = {
+static struct gmin_cfg_var i8880_vars[] = {
{"XXOV2680:00_CsiPort", "1"},
{"XXOV2680:00_CsiLanes", "1"},
{"XXOV2680:00_CamClk", "0"},
@@ -271,18 +268,46 @@ static const struct gmin_cfg_var i8880_vars[] = {
{},
};
-static const struct {
- const char *dmi_board_name;
- const struct gmin_cfg_var *vars;
-} hard_vars[] = {
- { "BYT-T FFD8", ffrd8_vars },
- { "T100TA", t100_vars },
- { "MRD7", mrd7_vars },
- { "ST70408", ecs7_vars },
- { "VTA0803", i8880_vars },
+static const struct dmi_system_id gmin_vars[] = {
+ {
+ .ident = "BYT-T FFD8",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
+ },
+ .driver_data = ffrd8_vars,
+ },
+ {
+ .ident = "T100TA",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "T100TA"),
+ },
+ .driver_data = t100_vars,
+ },
+ {
+ .ident = "MRD7",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "TABLET"),
+ DMI_MATCH(DMI_BOARD_VERSION, "MRD 7"),
+ },
+ .driver_data = mrd7_vars,
+ },
+ {
+ .ident = "ST70408",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "ST70408"),
+ },
+ .driver_data = ecs7_vars,
+ },
+ {
+ .ident = "VTA0803",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "VTA0803"),
+ },
+ .driver_data = i8880_vars,
+ },
+ {}
};
-
#define GMIN_CFG_VAR_EFI_GUID EFI_GUID(0xecb54cd9, 0xe5ae, 0x4fdc, \
0xa9, 0x71, 0xe8, 0x77, \
0x75, 0x60, 0x68, 0xf7)
@@ -322,8 +347,6 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
VLV2_CLK_PLL_19P2MHZ);
gmin_subdevs[i].csi_port = gmin_get_var_int(dev, "CsiPort", 0);
gmin_subdevs[i].csi_lanes = gmin_get_var_int(dev, "CsiLanes", 1);
- gmin_subdevs[i].gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW);
- gmin_subdevs[i].gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW);
/* get PMC clock with clock framework */
snprintf(gmin_pmc_clk_name,
@@ -356,9 +379,11 @@ static struct gmin_subdev *gmin_subdev_add(struct v4l2_subdev *subdev)
if (!ret)
clk_disable_unprepare(gmin_subdevs[i].pmc_clk);
+ gmin_subdevs[i].gpio0 = gpiod_get_index(dev, NULL, 0, GPIOD_OUT_LOW);
if (IS_ERR(gmin_subdevs[i].gpio0))
gmin_subdevs[i].gpio0 = NULL;
+ gmin_subdevs[i].gpio1 = gpiod_get_index(dev, NULL, 1, GPIOD_OUT_LOW);
if (IS_ERR(gmin_subdevs[i].gpio1))
gmin_subdevs[i].gpio1 = NULL;
@@ -394,7 +419,7 @@ static int gmin_gpio0_ctrl(struct v4l2_subdev *subdev, int on)
{
struct gmin_subdev *gs = find_gmin_subdev(subdev);
- if (gs && gs->gpio0) {
+ if (gs) {
gpiod_set_value(gs->gpio0, on);
return 0;
}
@@ -405,7 +430,7 @@ static int gmin_gpio1_ctrl(struct v4l2_subdev *subdev, int on)
{
struct gmin_subdev *gs = find_gmin_subdev(subdev);
- if (gs && gs->gpio1) {
+ if (gs) {
gpiod_set_value(gs->gpio1, on);
return 0;
}
@@ -606,17 +631,41 @@ int atomisp_gmin_register_vcm_control(struct camera_vcm_control *vcmCtrl)
}
EXPORT_SYMBOL_GPL(atomisp_gmin_register_vcm_control);
+static int gmin_get_hardcoded_var(struct gmin_cfg_var *varlist,
+ const char *var8, char *out, size_t *out_len)
+{
+ struct gmin_cfg_var *gv;
+
+ for (gv = varlist; gv->name; gv++) {
+ size_t vl;
+
+ if (strcmp(var8, gv->name))
+ continue;
+
+ vl = strlen(gv->val);
+ if (vl > *out_len - 1)
+ return -ENOSPC;
+
+ strcpy(out, gv->val);
+ *out_len = vl;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
/* Retrieves a device-specific configuration variable. The dev
* argument should be a device with an ACPI companion, as all
* configuration is based on firmware ID.
*/
-int gmin_get_config_var(struct device *dev, const char *var, char *out,
- size_t *out_len)
+static int gmin_get_config_var(struct device *dev, const char *var,
+ char *out, size_t *out_len)
{
char var8[CFG_VAR_NAME_MAX];
efi_char16_t var16[CFG_VAR_NAME_MAX];
struct efivar_entry *ev;
- int i, j, ret;
+ const struct dmi_system_id *id;
+ int i, ret;
if (dev && ACPI_COMPANION(dev))
dev = &ACPI_COMPANION(dev)->dev;
@@ -633,28 +682,9 @@ int gmin_get_config_var(struct device *dev, const char *var, char *out,
* Some device firmwares lack the ability to set EFI variables at
* runtime.
*/
- for (i = 0; i < ARRAY_SIZE(hard_vars); i++) {
- if (dmi_match(DMI_BOARD_NAME, hard_vars[i].dmi_board_name)) {
- for (j = 0; hard_vars[i].vars[j].name; j++) {
- size_t vl;
- const struct gmin_cfg_var *gv;
-
- gv = &hard_vars[i].vars[j];
- vl = strlen(gv->val);
-
- if (strcmp(var8, gv->name))
- continue;
- if (vl > *out_len - 1)
- return -ENOSPC;
-
- memcpy(out, gv->val, min(*out_len, vl+1));
- out[*out_len-1] = 0;
- *out_len = vl;
-
- return 0;
- }
- }
- }
+ id = dmi_first_match(gmin_vars);
+ if (id)
+ return gmin_get_hardcoded_var(id->driver_data, var8, out, out_len);
/* Our variable names are ASCII by construction, but EFI names
* are wide chars. Convert and zero-pad.
@@ -693,7 +723,6 @@ int gmin_get_config_var(struct device *dev, const char *var, char *out,
return ret;
}
-EXPORT_SYMBOL_GPL(gmin_get_config_var);
int gmin_get_var_int(struct device *dev, const char *var, int def)
{
diff --git a/drivers/staging/media/cxd2099/Makefile b/drivers/staging/media/cxd2099/Makefile
index b2905e65057c..30432c9aabc4 100644
--- a/drivers/staging/media/cxd2099/Makefile
+++ b/drivers/staging/media/cxd2099/Makefile
@@ -1,5 +1,4 @@
obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
-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 3e30f4864e2b..dc9cbd8f2104 100644
--- a/drivers/staging/media/cxd2099/cxd2099.c
+++ b/drivers/staging/media/cxd2099/cxd2099.c
@@ -3,23 +3,14 @@
*
* Copyright (C) 2010-2013 Digital Devices GmbH
*
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 only, as published by the Free Software Foundation.
*
- *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- *
- * 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
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*/
#include <linux/slab.h>
@@ -35,7 +26,7 @@
static int buffermode;
module_param(buffermode, int, 0444);
-MODULE_PARM_DESC(buffermode, "Enable use of the CXD2099AR buffer mode (default: disabled)");
+MODULE_PARM_DESC(buffermode, "Enable CXD2099AR buffer mode (default: disabled)");
static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount);
@@ -59,7 +50,7 @@ struct cxd {
int amem_read;
int cammode;
- struct mutex lock;
+ struct mutex lock; /* device access lock */
u8 rbuf[1028];
u8 wbuf[1028];
@@ -101,7 +92,7 @@ static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr,
.buf = val, .len = 1} };
if (i2c_transfer(adapter, msgs, 2) != 2) {
- dev_err(&adapter->dev, "error in i2c_read_reg\n");
+ dev_err(&adapter->dev, "error in %s()\n", __func__);
return -1;
}
return 0;
@@ -116,7 +107,7 @@ static int i2c_read(struct i2c_adapter *adapter, u8 adr,
.buf = data, .len = n} };
if (i2c_transfer(adapter, msgs, 2) != 2) {
- dev_err(&adapter->dev, "error in i2c_read\n");
+ dev_err(&adapter->dev, "error in %s()\n", __func__);
return -1;
}
return 0;
@@ -134,7 +125,7 @@ static int read_block(struct cxd *ci, u8 adr, u8 *data, u16 n)
while (n) {
int len = n;
- if (ci->cfg.max_i2c && (len > ci->cfg.max_i2c))
+ if (ci->cfg.max_i2c && len > ci->cfg.max_i2c)
len = ci->cfg.max_i2c;
status = i2c_read(ci->i2c, ci->cfg.adr, 1, data, len);
if (status)
@@ -527,7 +518,7 @@ static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
{
struct cxd *ci = ca->data;
- dev_info(&ci->i2c->dev, "%s\n", __func__);
+ dev_dbg(&ci->i2c->dev, "%s\n", __func__);
if (ci->cammode)
read_data(ca, slot, ci->rbuf, 0);
mutex_lock(&ci->lock);
@@ -591,7 +582,7 @@ static int campoll(struct cxd *ci)
}
}
if ((istat & 8) &&
- (ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT)) {
+ ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT) {
ci->ready = 1;
ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY;
}
@@ -677,7 +668,8 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
u8 val;
if (i2c_read_reg(i2c, cfg->adr, 0, &val) < 0) {
- dev_info(&i2c->dev, "No CXD2099 detected at %02x\n", cfg->adr);
+ dev_info(&i2c->dev, "No CXD2099AR detected at 0x%02x\n",
+ cfg->adr);
return NULL;
}
@@ -695,7 +687,7 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
ci->en = en_templ;
ci->en.data = ci;
init(ci);
- dev_info(&i2c->dev, "Attached CXD2099AR at %02x\n", ci->cfg.adr);
+ dev_info(&i2c->dev, "Attached CXD2099AR at 0x%02x\n", ci->cfg.adr);
if (!buffermode) {
ci->en.read_data = NULL;
@@ -708,6 +700,6 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
}
EXPORT_SYMBOL(cxd2099_attach);
-MODULE_DESCRIPTION("cxd2099");
+MODULE_DESCRIPTION("CXD2099AR Common Interface controller driver");
MODULE_AUTHOR("Ralph Metzler");
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/cxd2099/cxd2099.h b/drivers/staging/media/cxd2099/cxd2099.h
index f4b29b1d6eb8..253e3155a6df 100644
--- a/drivers/staging/media/cxd2099/cxd2099.h
+++ b/drivers/staging/media/cxd2099/cxd2099.h
@@ -3,29 +3,20 @@
*
* Copyright (C) 2010-2011 Digital Devices GmbH
*
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 only, as published by the Free Software Foundation.
*
- *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- *
- * 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
- * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*/
#ifndef _CXD2099_H_
#define _CXD2099_H_
-#include <dvb_ca_en50221.h>
+#include <media/dvb_ca_en50221.h>
struct cxd2099_cfg {
u32 bitrate;
@@ -42,8 +33,9 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
void *priv, struct i2c_adapter *i2c);
#else
-static inline struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
- void *priv, struct i2c_adapter *i2c)
+static inline struct
+dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg, void *priv,
+ struct i2c_adapter *i2c)
{
dev_warn(&i2c->dev, "%s: driver disabled by Kconfig\n", __func__);
return NULL;
diff --git a/drivers/staging/media/davinci_vpfe/TODO b/drivers/staging/media/davinci_vpfe/TODO
index 7015ab35ded5..3e5477e8cfa5 100644
--- a/drivers/staging/media/davinci_vpfe/TODO
+++ b/drivers/staging/media/davinci_vpfe/TODO
@@ -2,11 +2,11 @@ TODO (general):
==================================
- User space interface refinement
- - Controls should be used when possible rather than private ioctl
- - No enums should be used
- - Use of MC and V4L2 subdev APIs when applicable
- - Single interface header might suffice
- - Current interface forces to configure everything at once
+ - Controls should be used when possible rather than private ioctl
+ - No enums should be used
+ - Use of MC and V4L2 subdev APIs when applicable
+ - Single interface header might suffice
+ - Current interface forces to configure everything at once
- Get rid of the dm365_ipipe_hw.[ch] layer
- Active external sub-devices defined by link configuration; no strcmp
needed
diff --git a/drivers/staging/media/imx/TODO b/drivers/staging/media/imx/TODO
index 0bee3132b26f..9eb7326f3fc6 100644
--- a/drivers/staging/media/imx/TODO
+++ b/drivers/staging/media/imx/TODO
@@ -1,19 +1,14 @@
-- Clean up and move the ov5642 subdev driver to drivers/media/i2c, or
- merge support for OV5642 into drivers/media/i2c/ov5640.c, and create
- the binding docs for it.
-
- The Frame Interval Monitor could be exported to v4l2-core for
general use.
-- At driver load time, the device-tree node that is the original source
- (the "sensor"), is parsed to record its media bus configuration, and
- this info is required in imx-media-csi.c to setup the CSI.
- Laurent Pinchart argues that instead the CSI subdev should call its
- neighbor's g_mbus_config op (which should be propagated if necessary)
- to get this info. However Hans Verkuil is planning to remove the
- g_mbus_config op. For now this driver uses the parsed DT mbus config
- method until this issue is resolved.
+- The CSI subdevice parses its nearest upstream neighbor's device-tree
+ bus config in order to setup the CSI. Laurent Pinchart argues that
+ instead the CSI subdev should call its neighbor's g_mbus_config op
+ (which should be propagated if necessary) to get this info. However
+ Hans Verkuil is planning to remove the g_mbus_config op. For now this
+ driver uses the parsed DT bus config method until this issue is
+ resolved.
- This media driver supports inheriting V4L2 controls to the
video capture devices, from the subdevices in the capture device's
@@ -21,3 +16,47 @@
link_notify callback when the pipeline is modified. It should be
decided whether this feature is useful enough to make it generally
available by exporting to v4l2-core.
+
+- The OF graph is walked at probe time to form the list of fwnodes to
+ be passed to v4l2_async_notifier_register(), starting from the IPU
+ CSI ports. And after all async subdevices have been bound,
+ v4l2_fwnode_parse_link() is used to form the media links between
+ the entities discovered by walking the OF graph.
+
+ While this approach allows support for arbitrary OF graphs, there
+ are some assumptions for this to work:
+
+ 1. All port parent nodes reachable in the graph from the IPU CSI
+ ports bind to V4L2 async subdevice drivers.
+
+ If a device has mixed-use ports such as video plus audio, the
+ endpoints from the audio ports are followed to devices that must
+ bind to V4L2 subdevice drivers, and not for example, to an ALSA
+ driver or a non-V4L2 media driver. If the device were bound to
+ such a driver, imx-media would never get an async completion
+ notification because the device fwnode was added to the async
+ list, but the driver does not interface with the V4L2 async
+ framework.
+
+ 2. Every port reachable in the graph is treated as a media pad,
+ owned by the V4L2 subdevice that is bound to the port's parent.
+
+ This presents problems for devices that don't make this port = pad
+ assumption. Examples are SMIAPP compatible cameras which define only
+ a single output port node, but which define multiple pads owned
+ by multiple subdevices (pixel-array, binner, scaler). Or video
+ decoders (entity function MEDIA_ENT_F_ATV_DECODER), which also define
+ only a single output port node, but define multiple pads for video,
+ VBI, and audio out.
+
+ A workaround at present is to set the port reg properties to
+ correspond to the media pad index that the port represents. A
+ possible long-term solution is to implement a subdev API that
+ maps a port id to a media pad index.
+
+ 3. Every endpoint of a port reachable in the graph is treated as
+ a media link, between V4L2 subdevices that are bound to the
+ port parents of the local and remote endpoints.
+
+ Which means a port must not contain mixed-use endpoints, they
+ must all refer to media links between V4L2 subdevices.
diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c
index 9e41987f9884..c6d7e80932ad 100644
--- a/drivers/staging/media/imx/imx-ic-prp.c
+++ b/drivers/staging/media/imx/imx-ic-prp.c
@@ -300,7 +300,7 @@ static int prp_link_validate(struct v4l2_subdev *sd,
{
struct imx_ic_priv *ic_priv = v4l2_get_subdevdata(sd);
struct prp_priv *priv = ic_priv->prp_priv;
- struct imx_media_subdev *csi;
+ struct v4l2_subdev *csi;
int ret;
ret = v4l2_subdev_link_validate_default(sd, link,
@@ -333,7 +333,7 @@ static int prp_link_validate(struct v4l2_subdev *sd,
}
if (csi) {
- switch (csi->sd->grp_id) {
+ switch (csi->grp_id) {
case IMX_MEDIA_GRP_ID_CSI0:
priv->csi_id = 0;
break;
diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c
index ea145bafb880..576bdc7e9c42 100644
--- a/drivers/staging/media/imx/imx-media-capture.c
+++ b/drivers/staging/media/imx/imx-media-capture.c
@@ -449,9 +449,6 @@ static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
unsigned long flags;
int ret;
- if (vb2_is_streaming(vq))
- return 0;
-
ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
true);
if (ret) {
@@ -480,9 +477,6 @@ static void capture_stop_streaming(struct vb2_queue *vq)
unsigned long flags;
int ret;
- if (!vb2_is_streaming(vq))
- return;
-
spin_lock_irqsave(&priv->q_lock, flags);
priv->stop = true;
spin_unlock_irqrestore(&priv->q_lock, flags);
@@ -754,6 +748,8 @@ imx_media_capture_device_init(struct v4l2_subdev *src_sd, int pad)
vfd->queue = &priv->q;
priv->vdev.vfd = vfd;
+ INIT_LIST_HEAD(&priv->vdev.list);
+
video_set_drvdata(vfd, priv);
v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0);
diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c
index 26994b429cf2..eb7be5093a9d 100644
--- a/drivers/staging/media/imx/imx-media-csi.c
+++ b/drivers/staging/media/imx/imx-media-csi.c
@@ -13,6 +13,7 @@
#include <linux/gcd.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <media/v4l2-ctrls.h>
@@ -99,8 +100,8 @@ struct csi_priv {
/* the mipi virtual channel number at link validate */
int vc_num;
- /* the attached sensor at stream on */
- struct imx_media_subdev *sensor;
+ /* the upstream endpoint CSI is receiving from */
+ struct v4l2_fwnode_endpoint upstream_ep;
spinlock_t irqlock; /* protect eof_irq handler */
struct timer_list eof_timeout_timer;
@@ -120,6 +121,70 @@ static inline struct csi_priv *sd_to_dev(struct v4l2_subdev *sdev)
return container_of(sdev, struct csi_priv, sd);
}
+static inline bool is_parallel_16bit_bus(struct v4l2_fwnode_endpoint *ep)
+{
+ return ep->bus_type != V4L2_MBUS_CSI2 &&
+ ep->bus.parallel.bus_width >= 16;
+}
+
+/*
+ * Parses the fwnode endpoint from the source pad of the entity
+ * connected to this CSI. This will either be the entity directly
+ * upstream from the CSI-2 receiver, or directly upstream from the
+ * video mux. The endpoint is needed to determine the bus type and
+ * bus config coming into the CSI.
+ */
+static int csi_get_upstream_endpoint(struct csi_priv *priv,
+ struct v4l2_fwnode_endpoint *ep)
+{
+ struct device_node *endpoint, *port;
+ struct media_entity *src;
+ struct v4l2_subdev *sd;
+ struct media_pad *pad;
+
+ if (!priv->src_sd)
+ return -EPIPE;
+
+ src = &priv->src_sd->entity;
+
+ if (src->function == MEDIA_ENT_F_VID_MUX) {
+ /*
+ * CSI is connected directly to video mux, skip up to
+ * CSI-2 receiver if it is in the path, otherwise stay
+ * with video mux.
+ */
+ sd = imx_media_find_upstream_subdev(priv->md, src,
+ IMX_MEDIA_GRP_ID_CSI2);
+ if (!IS_ERR(sd))
+ src = &sd->entity;
+ }
+
+ /* get source pad of entity directly upstream from src */
+ pad = imx_media_find_upstream_pad(priv->md, src, 0);
+ if (IS_ERR(pad))
+ return PTR_ERR(pad);
+
+ sd = media_entity_to_v4l2_subdev(pad->entity);
+
+ /*
+ * NOTE: this assumes an OF-graph port id is the same as a
+ * media pad index.
+ */
+ port = of_graph_get_port_by_id(sd->dev->of_node, pad->index);
+ if (!port)
+ return -ENODEV;
+
+ endpoint = of_get_next_child(port, NULL);
+ of_node_put(port);
+ if (!endpoint)
+ return -ENODEV;
+
+ v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), ep);
+ of_node_put(endpoint);
+
+ return 0;
+}
+
static void csi_idmac_put_ipu_resources(struct csi_priv *priv)
{
if (priv->idmac_ch)
@@ -302,7 +367,6 @@ static void csi_idmac_unsetup_vb2_buf(struct csi_priv *priv,
static int csi_idmac_setup_channel(struct csi_priv *priv)
{
struct imx_media_video_dev *vdev = priv->vdev;
- struct v4l2_fwnode_endpoint *sensor_ep;
struct v4l2_mbus_framefmt *infmt;
struct ipu_image image;
u32 passthrough_bits;
@@ -312,7 +376,6 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
int ret;
infmt = &priv->format_mbus[CSI_SINK_PAD];
- sensor_ep = &priv->sensor->sensor_ep;
ipu_cpmem_zero(priv->idmac_ch);
@@ -330,14 +393,14 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
* Check for conditions that require the IPU to handle the
* data internally as generic data, aka passthrough mode:
* - raw bayer formats
- * - the sensor bus is 16-bit parallel
+ * - the CSI is receiving from a 16-bit parallel bus
*/
switch (image.pix.pixelformat) {
case V4L2_PIX_FMT_SBGGR8:
case V4L2_PIX_FMT_SGBRG8:
case V4L2_PIX_FMT_SGRBG8:
case V4L2_PIX_FMT_SRGGB8:
- burst_size = 8;
+ burst_size = 16;
passthrough = true;
passthrough_bits = 8;
break;
@@ -354,8 +417,7 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
burst_size = (image.pix.width & 0x3f) ?
((image.pix.width & 0x1f) ?
((image.pix.width & 0xf) ? 8 : 16) : 32) : 64;
- passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 &&
- sensor_ep->bus.parallel.bus_width >= 16);
+ passthrough = is_parallel_16bit_bus(&priv->upstream_ep);
passthrough_bits = 16;
/* Skip writing U and V components to odd rows */
ipu_cpmem_skip_odd_chroma_rows(priv->idmac_ch);
@@ -364,14 +426,12 @@ static int csi_idmac_setup_channel(struct csi_priv *priv)
case V4L2_PIX_FMT_UYVY:
burst_size = (image.pix.width & 0x1f) ?
((image.pix.width & 0xf) ? 8 : 16) : 32;
- passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 &&
- sensor_ep->bus.parallel.bus_width >= 16);
+ passthrough = is_parallel_16bit_bus(&priv->upstream_ep);
passthrough_bits = 16;
break;
default:
burst_size = (image.pix.width & 0xf) ? 8 : 16;
- passthrough = (sensor_ep->bus_type != V4L2_MBUS_CSI2 &&
- sensor_ep->bus.parallel.bus_width >= 16);
+ passthrough = is_parallel_16bit_bus(&priv->upstream_ep);
passthrough_bits = 16;
break;
}
@@ -568,22 +628,20 @@ static void csi_idmac_stop(struct csi_priv *priv)
static int csi_setup(struct csi_priv *priv)
{
struct v4l2_mbus_framefmt *infmt, *outfmt;
- struct v4l2_mbus_config sensor_mbus_cfg;
- struct v4l2_fwnode_endpoint *sensor_ep;
+ struct v4l2_mbus_config mbus_cfg;
struct v4l2_mbus_framefmt if_fmt;
infmt = &priv->format_mbus[CSI_SINK_PAD];
outfmt = &priv->format_mbus[priv->active_output_pad];
- sensor_ep = &priv->sensor->sensor_ep;
- /* compose mbus_config from sensor endpoint */
- sensor_mbus_cfg.type = sensor_ep->bus_type;
- sensor_mbus_cfg.flags = (sensor_ep->bus_type == V4L2_MBUS_CSI2) ?
- sensor_ep->bus.mipi_csi2.flags :
- sensor_ep->bus.parallel.flags;
+ /* compose mbus_config from the upstream endpoint */
+ mbus_cfg.type = priv->upstream_ep.bus_type;
+ mbus_cfg.flags = (priv->upstream_ep.bus_type == V4L2_MBUS_CSI2) ?
+ priv->upstream_ep.bus.mipi_csi2.flags :
+ priv->upstream_ep.bus.parallel.flags;
/*
- * we need to pass input sensor frame to CSI interface, but
+ * we need to pass input frame to CSI interface, but
* with translated field type from output format
*/
if_fmt = *infmt;
@@ -595,7 +653,7 @@ static int csi_setup(struct csi_priv *priv)
priv->crop.width == 2 * priv->compose.width,
priv->crop.height == 2 * priv->compose.height);
- ipu_csi_init_interface(priv->csi, &sensor_mbus_cfg, &if_fmt);
+ ipu_csi_init_interface(priv->csi, &mbus_cfg, &if_fmt);
ipu_csi_set_dest(priv->csi, priv->dest);
@@ -611,35 +669,11 @@ static int csi_setup(struct csi_priv *priv)
static int csi_start(struct csi_priv *priv)
{
struct v4l2_fract *output_fi, *input_fi;
- u32 bad_frames = 0;
int ret;
- if (!priv->sensor) {
- v4l2_err(&priv->sd, "no sensor attached\n");
- return -EINVAL;
- }
-
output_fi = &priv->frame_interval[priv->active_output_pad];
input_fi = &priv->frame_interval[CSI_SINK_PAD];
- ret = v4l2_subdev_call(priv->sensor->sd, sensor,
- g_skip_frames, &bad_frames);
- if (!ret && bad_frames) {
- u32 delay_usec;
-
- /*
- * This sensor has bad frames when it is turned on,
- * add a delay to avoid them before enabling the CSI
- * hardware. Especially for sensors with a bt.656 interface,
- * any shifts in the SAV/EAV sync codes will cause the CSI
- * to lose vert/horiz sync.
- */
- delay_usec = DIV_ROUND_UP_ULL(
- (u64)USEC_PER_SEC * input_fi->numerator * bad_frames,
- input_fi->denominator);
- usleep_range(delay_usec, delay_usec + 1000);
- }
-
if (priv->dest == IPU_CSI_DEST_IDMAC) {
ret = csi_idmac_start(priv);
if (ret)
@@ -971,9 +1005,8 @@ static int csi_link_validate(struct v4l2_subdev *sd,
struct v4l2_subdev_format *sink_fmt)
{
struct csi_priv *priv = v4l2_get_subdevdata(sd);
- struct v4l2_fwnode_endpoint *sensor_ep;
+ struct v4l2_fwnode_endpoint upstream_ep;
const struct imx_media_pixfmt *incc;
- struct imx_media_subdev *sensor;
bool is_csi2;
int ret;
@@ -982,22 +1015,20 @@ static int csi_link_validate(struct v4l2_subdev *sd,
if (ret)
return ret;
- sensor = __imx_media_find_sensor(priv->md, &priv->sd.entity);
- if (IS_ERR(sensor)) {
- v4l2_err(&priv->sd, "no sensor attached\n");
- return PTR_ERR(priv->sensor);
+ ret = csi_get_upstream_endpoint(priv, &upstream_ep);
+ if (ret) {
+ v4l2_err(&priv->sd, "failed to find upstream endpoint\n");
+ return ret;
}
mutex_lock(&priv->lock);
- priv->sensor = sensor;
- sensor_ep = &priv->sensor->sensor_ep;
- is_csi2 = (sensor_ep->bus_type == V4L2_MBUS_CSI2);
+ priv->upstream_ep = upstream_ep;
+ is_csi2 = (upstream_ep.bus_type == V4L2_MBUS_CSI2);
incc = priv->cc[CSI_SINK_PAD];
if (priv->dest != IPU_CSI_DEST_IDMAC &&
- (incc->bayer || (!is_csi2 &&
- sensor_ep->bus.parallel.bus_width >= 16))) {
+ (incc->bayer || is_parallel_16bit_bus(&upstream_ep))) {
v4l2_err(&priv->sd,
"bayer/16-bit parallel buses must go to IDMAC pad\n");
ret = -EINVAL;
@@ -1067,12 +1098,8 @@ static void csi_try_crop(struct csi_priv *priv,
struct v4l2_rect *crop,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_mbus_framefmt *infmt,
- struct imx_media_subdev *sensor)
+ struct v4l2_fwnode_endpoint *upstream_ep)
{
- struct v4l2_fwnode_endpoint *sensor_ep;
-
- sensor_ep = &sensor->sensor_ep;
-
crop->width = min_t(__u32, infmt->width, crop->width);
if (crop->left + crop->width > infmt->width)
crop->left = infmt->width - crop->width;
@@ -1086,7 +1113,7 @@ static void csi_try_crop(struct csi_priv *priv,
* sync, so fix it to NTSC/PAL active lines. NTSC contains
* 2 extra lines of active video that need to be cropped.
*/
- if (sensor_ep->bus_type == V4L2_MBUS_BT656 &&
+ if (upstream_ep->bus_type == V4L2_MBUS_BT656 &&
(V4L2_FIELD_HAS_BOTH(infmt->field) ||
infmt->field == V4L2_FIELD_ALTERNATE)) {
crop->height = infmt->height;
@@ -1236,7 +1263,7 @@ out:
}
static void csi_try_fmt(struct csi_priv *priv,
- struct imx_media_subdev *sensor,
+ struct v4l2_fwnode_endpoint *upstream_ep,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_format *sdformat,
struct v4l2_rect *crop,
@@ -1304,7 +1331,7 @@ static void csi_try_fmt(struct csi_priv *priv,
crop->top = 0;
crop->width = sdformat->format.width;
crop->height = sdformat->format.height;
- csi_try_crop(priv, crop, cfg, &sdformat->format, sensor);
+ csi_try_crop(priv, crop, cfg, &sdformat->format, upstream_ep);
compose->left = 0;
compose->top = 0;
compose->width = crop->width;
@@ -1333,20 +1360,20 @@ static int csi_set_fmt(struct v4l2_subdev *sd,
{
struct csi_priv *priv = v4l2_get_subdevdata(sd);
struct imx_media_video_dev *vdev = priv->vdev;
+ struct v4l2_fwnode_endpoint upstream_ep;
const struct imx_media_pixfmt *cc;
- struct imx_media_subdev *sensor;
struct v4l2_pix_format vdev_fmt;
struct v4l2_mbus_framefmt *fmt;
struct v4l2_rect *crop, *compose;
- int ret = 0;
+ int ret;
if (sdformat->pad >= CSI_NUM_PADS)
return -EINVAL;
- sensor = imx_media_find_sensor(priv->md, &priv->sd.entity);
- if (IS_ERR(sensor)) {
- v4l2_err(&priv->sd, "no sensor attached\n");
- return PTR_ERR(sensor);
+ ret = csi_get_upstream_endpoint(priv, &upstream_ep);
+ if (ret) {
+ v4l2_err(&priv->sd, "failed to find upstream endpoint\n");
+ return ret;
}
mutex_lock(&priv->lock);
@@ -1359,7 +1386,7 @@ static int csi_set_fmt(struct v4l2_subdev *sd,
crop = __csi_get_crop(priv, cfg, sdformat->which);
compose = __csi_get_compose(priv, cfg, sdformat->which);
- csi_try_fmt(priv, sensor, cfg, sdformat, crop, compose, &cc);
+ csi_try_fmt(priv, &upstream_ep, cfg, sdformat, crop, compose, &cc);
fmt = __csi_get_fmt(priv, cfg, sdformat->pad, sdformat->which);
*fmt = sdformat->format;
@@ -1376,8 +1403,8 @@ static int csi_set_fmt(struct v4l2_subdev *sd,
format.pad = pad;
format.which = sdformat->which;
format.format = sdformat->format;
- csi_try_fmt(priv, sensor, cfg, &format, NULL, compose,
- &outcc);
+ csi_try_fmt(priv, &upstream_ep, cfg, &format,
+ NULL, compose, &outcc);
outfmt = __csi_get_fmt(priv, cfg, pad, sdformat->which);
*outfmt = format.format;
@@ -1472,18 +1499,18 @@ static int csi_set_selection(struct v4l2_subdev *sd,
struct v4l2_subdev_selection *sel)
{
struct csi_priv *priv = v4l2_get_subdevdata(sd);
+ struct v4l2_fwnode_endpoint upstream_ep;
struct v4l2_mbus_framefmt *infmt;
struct v4l2_rect *crop, *compose;
- struct imx_media_subdev *sensor;
- int pad, ret = 0;
+ int pad, ret;
if (sel->pad != CSI_SINK_PAD)
return -EINVAL;
- sensor = imx_media_find_sensor(priv->md, &priv->sd.entity);
- if (IS_ERR(sensor)) {
- v4l2_err(&priv->sd, "no sensor attached\n");
- return PTR_ERR(sensor);
+ ret = csi_get_upstream_endpoint(priv, &upstream_ep);
+ if (ret) {
+ v4l2_err(&priv->sd, "failed to find upstream endpoint\n");
+ return ret;
}
mutex_lock(&priv->lock);
@@ -1511,7 +1538,7 @@ static int csi_set_selection(struct v4l2_subdev *sd,
goto out;
}
- csi_try_crop(priv, &sel->r, cfg, infmt, sensor);
+ csi_try_crop(priv, &sel->r, cfg, infmt, &upstream_ep);
*crop = sel->r;
diff --git a/drivers/staging/media/imx/imx-media-dev.c b/drivers/staging/media/imx/imx-media-dev.c
index 47c4c954fed5..289d775c4820 100644
--- a/drivers/staging/media/imx/imx-media-dev.c
+++ b/drivers/staging/media/imx/imx-media-dev.c
@@ -11,6 +11,7 @@
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/module.h>
+#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
@@ -32,29 +33,28 @@ static inline struct imx_media_dev *notifier2dev(struct v4l2_async_notifier *n)
}
/*
- * Find a subdev by device node or device name. This is called during
+ * Find an asd by fwnode or device name. This is called during
* driver load to form the async subdev list and bind them.
*/
-struct imx_media_subdev *
-imx_media_find_async_subdev(struct imx_media_dev *imxmd,
- struct device_node *np,
- const char *devname)
+static struct v4l2_async_subdev *
+find_async_subdev(struct imx_media_dev *imxmd,
+ struct fwnode_handle *fwnode,
+ const char *devname)
{
- struct fwnode_handle *fwnode = np ? of_fwnode_handle(np) : NULL;
- struct imx_media_subdev *imxsd;
- int i;
+ struct imx_media_async_subdev *imxasd;
+ struct v4l2_async_subdev *asd;
- for (i = 0; i < imxmd->subdev_notifier.num_subdevs; i++) {
- imxsd = &imxmd->subdev[i];
- switch (imxsd->asd.match_type) {
+ list_for_each_entry(imxasd, &imxmd->asd_list, list) {
+ asd = &imxasd->asd;
+ switch (asd->match_type) {
case V4L2_ASYNC_MATCH_FWNODE:
- if (fwnode && imxsd->asd.match.fwnode.fwnode == fwnode)
- return imxsd;
+ if (fwnode && asd->match.fwnode == fwnode)
+ return asd;
break;
case V4L2_ASYNC_MATCH_DEVNAME:
- if (devname &&
- !strcmp(imxsd->asd.match.device_name.name, devname))
- return imxsd;
+ if (devname && !strcmp(asd->match.device_name,
+ devname))
+ return asd;
break;
default:
break;
@@ -66,57 +66,53 @@ imx_media_find_async_subdev(struct imx_media_dev *imxmd,
/*
- * Adds a subdev to the async subdev list. If np is non-NULL, adds
+ * Adds a subdev to the async subdev list. If fwnode is non-NULL, adds
* the async as a V4L2_ASYNC_MATCH_FWNODE match type, otherwise as
* a V4L2_ASYNC_MATCH_DEVNAME match type using the dev_name of the
* given platform_device. This is called during driver load when
* forming the async subdev list.
*/
-struct imx_media_subdev *
-imx_media_add_async_subdev(struct imx_media_dev *imxmd,
- struct device_node *np,
- struct platform_device *pdev)
+int imx_media_add_async_subdev(struct imx_media_dev *imxmd,
+ struct fwnode_handle *fwnode,
+ struct platform_device *pdev)
{
- struct imx_media_subdev *imxsd;
+ struct device_node *np = to_of_node(fwnode);
+ struct imx_media_async_subdev *imxasd;
struct v4l2_async_subdev *asd;
const char *devname = NULL;
- int sd_idx;
+ int ret = 0;
mutex_lock(&imxmd->mutex);
if (pdev)
devname = dev_name(&pdev->dev);
- /* return -EEXIST if this subdev already added */
- if (imx_media_find_async_subdev(imxmd, np, devname)) {
+ /* return -EEXIST if this asd already added */
+ if (find_async_subdev(imxmd, fwnode, devname)) {
dev_dbg(imxmd->md.dev, "%s: already added %s\n",
__func__, np ? np->name : devname);
- imxsd = ERR_PTR(-EEXIST);
+ ret = -EEXIST;
goto out;
}
- sd_idx = imxmd->subdev_notifier.num_subdevs;
- if (sd_idx >= IMX_MEDIA_MAX_SUBDEVS) {
- dev_err(imxmd->md.dev, "%s: too many subdevs! can't add %s\n",
- __func__, np ? np->name : devname);
- imxsd = ERR_PTR(-ENOSPC);
+ imxasd = devm_kzalloc(imxmd->md.dev, sizeof(*imxasd), GFP_KERNEL);
+ if (!imxasd) {
+ ret = -ENOMEM;
goto out;
}
+ asd = &imxasd->asd;
- imxsd = &imxmd->subdev[sd_idx];
-
- asd = &imxsd->asd;
- if (np) {
+ if (fwnode) {
asd->match_type = V4L2_ASYNC_MATCH_FWNODE;
- asd->match.fwnode.fwnode = of_fwnode_handle(np);
+ asd->match.fwnode = fwnode;
} else {
asd->match_type = V4L2_ASYNC_MATCH_DEVNAME;
- strncpy(imxsd->devname, devname, sizeof(imxsd->devname));
- asd->match.device_name.name = imxsd->devname;
- imxsd->pdev = pdev;
+ asd->match.device_name = devname;
+ imxasd->pdev = pdev;
}
- imxmd->async_ptrs[sd_idx] = asd;
+ list_add_tail(&imxasd->list, &imxmd->asd_list);
+
imxmd->subdev_notifier.num_subdevs++;
dev_dbg(imxmd->md.dev, "%s: added %s, match type %s\n",
@@ -124,50 +120,6 @@ imx_media_add_async_subdev(struct imx_media_dev *imxmd,
out:
mutex_unlock(&imxmd->mutex);
- return imxsd;
-}
-
-/*
- * Adds an imx-media link to a subdev pad's link list. This is called
- * during driver load when forming the links between subdevs.
- *
- * @pad: the local pad
- * @remote_node: the device node of the remote subdev
- * @remote_devname: the device name of the remote subdev
- * @local_pad: local pad index
- * @remote_pad: remote pad index
- */
-int imx_media_add_pad_link(struct imx_media_dev *imxmd,
- struct imx_media_pad *pad,
- struct device_node *remote_node,
- const char *remote_devname,
- int local_pad, int remote_pad)
-{
- struct imx_media_link *link;
- int link_idx, ret = 0;
-
- mutex_lock(&imxmd->mutex);
-
- link_idx = pad->num_links;
- if (link_idx >= IMX_MEDIA_MAX_LINKS) {
- dev_err(imxmd->md.dev, "%s: too many links!\n", __func__);
- ret = -ENOSPC;
- goto out;
- }
-
- link = &pad->link[link_idx];
-
- link->remote_sd_node = remote_node;
- if (remote_devname)
- strncpy(link->remote_devname, remote_devname,
- sizeof(link->remote_devname));
-
- link->local_pad = local_pad;
- link->remote_pad = remote_pad;
-
- pad->num_links++;
-out:
- mutex_unlock(&imxmd->mutex);
return ret;
}
@@ -206,122 +158,66 @@ static int imx_media_subdev_bound(struct v4l2_async_notifier *notifier,
struct v4l2_async_subdev *asd)
{
struct imx_media_dev *imxmd = notifier2dev(notifier);
- struct device_node *np = to_of_node(sd->fwnode);
- struct imx_media_subdev *imxsd;
int ret = 0;
mutex_lock(&imxmd->mutex);
- imxsd = imx_media_find_async_subdev(imxmd, np, dev_name(sd->dev));
- if (!imxsd) {
- ret = -EINVAL;
- goto out;
- }
-
if (sd->grp_id & IMX_MEDIA_GRP_ID_CSI) {
ret = imx_media_get_ipu(imxmd, sd);
if (ret)
- goto out_unlock;
- } else if (sd->entity.function == MEDIA_ENT_F_VID_MUX) {
- /* this is a video mux */
- sd->grp_id = IMX_MEDIA_GRP_ID_VIDMUX;
- } else if (imxsd->num_sink_pads == 0) {
- /*
- * this is an original source of video frames, it
- * could be a camera sensor, an analog decoder, or
- * a bridge device (HDMI -> MIPI CSI-2 for example).
- * This group ID is used to locate the entity that
- * is the original source of video in a pipeline.
- */
- sd->grp_id = IMX_MEDIA_GRP_ID_SENSOR;
+ goto out;
}
- /* attach the subdev */
- imxsd->sd = sd;
+ v4l2_info(&imxmd->v4l2_dev, "subdev %s bound\n", sd->name);
out:
- if (ret)
- v4l2_warn(&imxmd->v4l2_dev,
- "Received unknown subdev %s\n", sd->name);
- else
- v4l2_info(&imxmd->v4l2_dev,
- "Registered subdev %s\n", sd->name);
-
-out_unlock:
mutex_unlock(&imxmd->mutex);
return ret;
}
/*
- * Create a single source->sink media link given a subdev and a single
- * link from one of its source pads. Called after all subdevs have
- * registered.
+ * create the media links for all subdevs that registered async.
+ * Called after all async subdevs have bound.
*/
-static int imx_media_create_link(struct imx_media_dev *imxmd,
- struct imx_media_subdev *src,
- struct imx_media_link *link)
+static int imx_media_create_links(struct v4l2_async_notifier *notifier)
{
- struct imx_media_subdev *sink;
- u16 source_pad, sink_pad;
+ struct imx_media_dev *imxmd = notifier2dev(notifier);
+ struct v4l2_subdev *sd;
int ret;
- sink = imx_media_find_async_subdev(imxmd, link->remote_sd_node,
- link->remote_devname);
- if (!sink) {
- v4l2_warn(&imxmd->v4l2_dev, "%s: no sink for %s:%d\n",
- __func__, src->sd->name, link->local_pad);
- return 0;
- }
-
- source_pad = link->local_pad;
- sink_pad = link->remote_pad;
-
- v4l2_info(&imxmd->v4l2_dev, "%s: %s:%d -> %s:%d\n", __func__,
- src->sd->name, source_pad, sink->sd->name, sink_pad);
-
- ret = media_create_pad_link(&src->sd->entity, source_pad,
- &sink->sd->entity, sink_pad, 0);
- if (ret)
- v4l2_err(&imxmd->v4l2_dev,
- "create_pad_link failed: %d\n", ret);
-
- return ret;
-}
-
-/*
- * create the media links from all imx-media pads and their links.
- * Called after all subdevs have registered.
- */
-static int imx_media_create_links(struct imx_media_dev *imxmd)
-{
- struct imx_media_subdev *imxsd;
- struct imx_media_link *link;
- struct imx_media_pad *pad;
- int num_pads, i, j, k;
- int ret = 0;
-
- for (i = 0; i < imxmd->num_subdevs; i++) {
- imxsd = &imxmd->subdev[i];
- num_pads = imxsd->num_sink_pads + imxsd->num_src_pads;
-
- for (j = 0; j < num_pads; j++) {
- pad = &imxsd->pad[j];
-
- /* only create the source->sink links */
- if (!(pad->pad.flags & MEDIA_PAD_FL_SOURCE))
- continue;
-
- for (k = 0; k < pad->num_links; k++) {
- link = &pad->link[k];
-
- ret = imx_media_create_link(imxmd, imxsd, link);
- if (ret)
- goto out;
- }
+ /*
+ * Only links are created between subdevices that are known
+ * to the async notifier. If there are other non-async subdevices,
+ * they were created internally by some subdevice (smiapp is one
+ * example). In those cases it is expected the subdevice is
+ * responsible for creating those internal links.
+ */
+ list_for_each_entry(sd, &notifier->done, async_list) {
+ switch (sd->grp_id) {
+ case IMX_MEDIA_GRP_ID_VDIC:
+ case IMX_MEDIA_GRP_ID_IC_PRP:
+ case IMX_MEDIA_GRP_ID_IC_PRPENC:
+ case IMX_MEDIA_GRP_ID_IC_PRPVF:
+ case IMX_MEDIA_GRP_ID_CSI0:
+ case IMX_MEDIA_GRP_ID_CSI1:
+ ret = imx_media_create_internal_links(imxmd, sd);
+ if (ret)
+ return ret;
+ /*
+ * the CSIs straddle between the external and the IPU
+ * internal entities, so create the external links
+ * to the CSI sink pads.
+ */
+ if (sd->grp_id & IMX_MEDIA_GRP_ID_CSI)
+ imx_media_create_csi_of_links(imxmd, sd);
+ break;
+ default:
+ /* this is an external fwnode subdev */
+ imx_media_create_of_links(imxmd, sd);
+ break;
}
}
-out:
- return ret;
+ return 0;
}
/*
@@ -333,39 +229,45 @@ static int imx_media_add_vdev_to_pad(struct imx_media_dev *imxmd,
struct media_pad *srcpad)
{
struct media_entity *entity = srcpad->entity;
- struct imx_media_subdev *imxsd;
- struct imx_media_pad *imxpad;
+ struct imx_media_pad_vdev *pad_vdev;
+ struct list_head *pad_vdev_list;
struct media_link *link;
struct v4l2_subdev *sd;
- int i, vdev_idx, ret;
+ int i, ret;
/* skip this entity if not a v4l2_subdev */
if (!is_media_entity_v4l2_subdev(entity))
return 0;
sd = media_entity_to_v4l2_subdev(entity);
- imxsd = imx_media_find_subdev_by_sd(imxmd, sd);
- if (IS_ERR(imxsd))
- return PTR_ERR(imxsd);
- imxpad = &imxsd->pad[srcpad->index];
- vdev_idx = imxpad->num_vdevs;
+ pad_vdev_list = to_pad_vdev_list(sd, srcpad->index);
+ if (!pad_vdev_list) {
+ v4l2_warn(&imxmd->v4l2_dev, "%s:%u has no vdev list!\n",
+ entity->name, srcpad->index);
+ /*
+ * shouldn't happen, but no reason to fail driver load,
+ * just skip this entity.
+ */
+ return 0;
+ }
/* just return if we've been here before */
- for (i = 0; i < vdev_idx; i++)
- if (vdev == imxpad->vdev[i])
+ list_for_each_entry(pad_vdev, pad_vdev_list, list) {
+ if (pad_vdev->vdev == vdev)
return 0;
-
- if (vdev_idx >= IMX_MEDIA_MAX_VDEVS) {
- dev_err(imxmd->md.dev, "can't add %s to pad %s:%u\n",
- vdev->vfd->entity.name, entity->name, srcpad->index);
- return -ENOSPC;
}
dev_dbg(imxmd->md.dev, "adding %s to pad %s:%u\n",
vdev->vfd->entity.name, entity->name, srcpad->index);
- imxpad->vdev[vdev_idx] = vdev;
- imxpad->num_vdevs++;
+
+ pad_vdev = devm_kzalloc(imxmd->md.dev, sizeof(*pad_vdev), GFP_KERNEL);
+ if (!pad_vdev)
+ return -ENOMEM;
+
+ /* attach this vdev to this pad */
+ pad_vdev->vdev = vdev;
+ list_add_tail(&pad_vdev->list, pad_vdev_list);
/* move upstream from this entity's sink pads */
for (i = 0; i < entity->num_pads; i++) {
@@ -387,15 +289,49 @@ static int imx_media_add_vdev_to_pad(struct imx_media_dev *imxmd,
return 0;
}
+/*
+ * For every subdevice, allocate an array of list_head's, one list_head
+ * for each pad, to hold the list of video devices reachable from that
+ * pad.
+ */
+static int imx_media_alloc_pad_vdev_lists(struct imx_media_dev *imxmd)
+{
+ struct list_head *vdev_lists;
+ struct media_entity *entity;
+ struct v4l2_subdev *sd;
+ int i;
+
+ list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
+ entity = &sd->entity;
+ vdev_lists = devm_kzalloc(
+ imxmd->md.dev,
+ entity->num_pads * sizeof(*vdev_lists),
+ GFP_KERNEL);
+ if (!vdev_lists)
+ return -ENOMEM;
+
+ /* attach to the subdev's host private pointer */
+ sd->host_priv = vdev_lists;
+
+ for (i = 0; i < entity->num_pads; i++)
+ INIT_LIST_HEAD(to_pad_vdev_list(sd, i));
+ }
+
+ return 0;
+}
+
/* form the vdev lists in all imx-media source pads */
static int imx_media_create_pad_vdev_lists(struct imx_media_dev *imxmd)
{
struct imx_media_video_dev *vdev;
struct media_link *link;
- int i, ret;
+ int ret;
+
+ ret = imx_media_alloc_pad_vdev_lists(imxmd);
+ if (ret)
+ return ret;
- for (i = 0; i < imxmd->num_vdevs; i++) {
- vdev = imxmd->vdev[i];
+ list_for_each_entry(vdev, &imxmd->vdev_list, list) {
link = list_first_entry(&vdev->vfd->entity.links,
struct media_link, list);
ret = imx_media_add_vdev_to_pad(imxmd, vdev, link->source);
@@ -410,20 +346,11 @@ static int imx_media_create_pad_vdev_lists(struct imx_media_dev *imxmd)
static int imx_media_probe_complete(struct v4l2_async_notifier *notifier)
{
struct imx_media_dev *imxmd = notifier2dev(notifier);
- int i, ret;
+ int ret;
mutex_lock(&imxmd->mutex);
- /* make sure all subdevs were bound */
- for (i = 0; i < imxmd->num_subdevs; i++) {
- if (!imxmd->subdev[i].sd) {
- v4l2_err(&imxmd->v4l2_dev, "unbound subdev!\n");
- ret = -ENODEV;
- goto unlock;
- }
- }
-
- ret = imx_media_create_links(imxmd);
+ ret = imx_media_create_links(notifier);
if (ret)
goto unlock;
@@ -492,12 +419,12 @@ static int imx_media_link_notify(struct media_link *link, u32 flags,
unsigned int notification)
{
struct media_entity *source = link->source->entity;
- struct imx_media_subdev *imxsd;
- struct imx_media_pad *imxpad;
+ struct imx_media_pad_vdev *pad_vdev;
+ struct list_head *pad_vdev_list;
struct imx_media_dev *imxmd;
struct video_device *vfd;
struct v4l2_subdev *sd;
- int i, pad_idx, ret;
+ int pad_idx, ret;
ret = v4l2_pipeline_link_notify(link, flags, notification);
if (ret)
@@ -512,10 +439,11 @@ static int imx_media_link_notify(struct media_link *link, u32 flags,
imxmd = dev_get_drvdata(sd->v4l2_dev->dev);
- imxsd = imx_media_find_subdev_by_sd(imxmd, sd);
- if (IS_ERR(imxsd))
- return PTR_ERR(imxsd);
- imxpad = &imxsd->pad[pad_idx];
+ pad_vdev_list = to_pad_vdev_list(sd, pad_idx);
+ if (!pad_vdev_list) {
+ /* shouldn't happen, but no reason to fail link setup */
+ return 0;
+ }
/*
* Before disabling a link, reset controls for all video
@@ -526,8 +454,8 @@ static int imx_media_link_notify(struct media_link *link, u32 flags,
*/
if (notification == MEDIA_DEV_NOTIFY_PRE_LINK_CH &&
!(flags & MEDIA_LNK_FL_ENABLED)) {
- for (i = 0; i < imxpad->num_vdevs; i++) {
- vfd = imxpad->vdev[i]->vfd;
+ list_for_each_entry(pad_vdev, pad_vdev_list, list) {
+ vfd = pad_vdev->vdev->vfd;
dev_dbg(imxmd->md.dev,
"reset controls for %s\n",
vfd->entity.name);
@@ -536,8 +464,8 @@ static int imx_media_link_notify(struct media_link *link, u32 flags,
}
} else if (notification == MEDIA_DEV_NOTIFY_POST_LINK_CH &&
(link->flags & MEDIA_LNK_FL_ENABLED)) {
- for (i = 0; i < imxpad->num_vdevs; i++) {
- vfd = imxpad->vdev[i]->vfd;
+ list_for_each_entry(pad_vdev, pad_vdev_list, list) {
+ vfd = pad_vdev->vdev->vfd;
dev_dbg(imxmd->md.dev,
"refresh controls for %s\n",
vfd->entity.name);
@@ -559,9 +487,10 @@ static int imx_media_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
- struct imx_media_subdev *csi[4] = {0};
+ struct imx_media_async_subdev *imxasd;
+ struct v4l2_async_subdev **subdevs;
struct imx_media_dev *imxmd;
- int ret;
+ int num_subdevs, i, ret;
imxmd = devm_kzalloc(dev, sizeof(*imxmd), GFP_KERNEL);
if (!imxmd)
@@ -590,29 +519,44 @@ static int imx_media_probe(struct platform_device *pdev)
dev_set_drvdata(imxmd->v4l2_dev.dev, imxmd);
- ret = imx_media_of_parse(imxmd, &csi, node);
+ INIT_LIST_HEAD(&imxmd->asd_list);
+ INIT_LIST_HEAD(&imxmd->vdev_list);
+
+ ret = imx_media_add_of_subdevs(imxmd, node);
if (ret) {
v4l2_err(&imxmd->v4l2_dev,
- "imx_media_of_parse failed with %d\n", ret);
+ "add_of_subdevs failed with %d\n", ret);
goto unreg_dev;
}
- ret = imx_media_add_internal_subdevs(imxmd, csi);
+ ret = imx_media_add_internal_subdevs(imxmd);
if (ret) {
v4l2_err(&imxmd->v4l2_dev,
"add_internal_subdevs failed with %d\n", ret);
goto unreg_dev;
}
+ num_subdevs = imxmd->subdev_notifier.num_subdevs;
+
/* no subdevs? just bail */
- imxmd->num_subdevs = imxmd->subdev_notifier.num_subdevs;
- if (imxmd->num_subdevs == 0) {
+ if (num_subdevs == 0) {
ret = -ENODEV;
goto unreg_dev;
}
+ subdevs = devm_kzalloc(imxmd->md.dev, sizeof(*subdevs) * num_subdevs,
+ GFP_KERNEL);
+ if (!subdevs) {
+ ret = -ENOMEM;
+ goto unreg_dev;
+ }
+
+ i = 0;
+ list_for_each_entry(imxasd, &imxmd->asd_list, list)
+ subdevs[i++] = &imxasd->asd;
+
/* prepare the async subdev notifier and register it */
- imxmd->subdev_notifier.subdevs = imxmd->async_ptrs;
+ imxmd->subdev_notifier.subdevs = subdevs;
imxmd->subdev_notifier.ops = &imx_media_subdev_ops;
ret = v4l2_async_notifier_register(&imxmd->v4l2_dev,
&imxmd->subdev_notifier);
diff --git a/drivers/staging/media/imx/imx-media-internal-sd.c b/drivers/staging/media/imx/imx-media-internal-sd.c
index cdfbf40dfcbe..70833fe503b5 100644
--- a/drivers/staging/media/imx/imx-media-internal-sd.c
+++ b/drivers/staging/media/imx/imx-media-internal-sd.c
@@ -60,73 +60,68 @@ static const struct internal_subdev_id {
},
};
+struct internal_subdev;
+
struct internal_link {
- const struct internal_subdev_id *remote_id;
+ const struct internal_subdev *remote;
+ int local_pad;
int remote_pad;
};
+/* max pads per internal-sd */
+#define MAX_INTERNAL_PADS 8
+/* max links per internal-sd pad */
+#define MAX_INTERNAL_LINKS 8
+
struct internal_pad {
- bool devnode; /* does this pad link to a device node */
- struct internal_link link[IMX_MEDIA_MAX_LINKS];
+ struct internal_link link[MAX_INTERNAL_LINKS];
};
static const struct internal_subdev {
const struct internal_subdev_id *id;
- struct internal_pad pad[IMX_MEDIA_MAX_PADS];
- int num_sink_pads;
- int num_src_pads;
-} internal_subdev[num_isd] = {
+ struct internal_pad pad[MAX_INTERNAL_PADS];
+} int_subdev[num_isd] = {
[isd_csi0] = {
.id = &isd_id[isd_csi0],
- .num_sink_pads = CSI_NUM_SINK_PADS,
- .num_src_pads = CSI_NUM_SRC_PADS,
.pad[CSI_SRC_PAD_DIRECT] = {
.link = {
{
- .remote_id = &isd_id[isd_ic_prp],
+ .local_pad = CSI_SRC_PAD_DIRECT,
+ .remote = &int_subdev[isd_ic_prp],
.remote_pad = PRP_SINK_PAD,
}, {
- .remote_id = &isd_id[isd_vdic],
+ .local_pad = CSI_SRC_PAD_DIRECT,
+ .remote = &int_subdev[isd_vdic],
.remote_pad = VDIC_SINK_PAD_DIRECT,
},
},
},
- .pad[CSI_SRC_PAD_IDMAC] = {
- .devnode = true,
- },
},
[isd_csi1] = {
.id = &isd_id[isd_csi1],
- .num_sink_pads = CSI_NUM_SINK_PADS,
- .num_src_pads = CSI_NUM_SRC_PADS,
.pad[CSI_SRC_PAD_DIRECT] = {
.link = {
{
- .remote_id = &isd_id[isd_ic_prp],
+ .local_pad = CSI_SRC_PAD_DIRECT,
+ .remote = &int_subdev[isd_ic_prp],
.remote_pad = PRP_SINK_PAD,
}, {
- .remote_id = &isd_id[isd_vdic],
+ .local_pad = CSI_SRC_PAD_DIRECT,
+ .remote = &int_subdev[isd_vdic],
.remote_pad = VDIC_SINK_PAD_DIRECT,
},
},
},
- .pad[CSI_SRC_PAD_IDMAC] = {
- .devnode = true,
- },
},
[isd_vdic] = {
.id = &isd_id[isd_vdic],
- .num_sink_pads = VDIC_NUM_SINK_PADS,
- .num_src_pads = VDIC_NUM_SRC_PADS,
- .pad[VDIC_SINK_PAD_IDMAC] = {
- .devnode = true,
- },
.pad[VDIC_SRC_PAD_DIRECT] = {
.link = {
{
- .remote_id = &isd_id[isd_ic_prp],
+ .local_pad = VDIC_SRC_PAD_DIRECT,
+ .remote = &int_subdev[isd_ic_prp],
.remote_pad = PRP_SINK_PAD,
},
},
@@ -135,12 +130,11 @@ static const struct internal_subdev {
[isd_ic_prp] = {
.id = &isd_id[isd_ic_prp],
- .num_sink_pads = PRP_NUM_SINK_PADS,
- .num_src_pads = PRP_NUM_SRC_PADS,
.pad[PRP_SRC_PAD_PRPENC] = {
.link = {
{
- .remote_id = &isd_id[isd_ic_prpenc],
+ .local_pad = PRP_SRC_PAD_PRPENC,
+ .remote = &int_subdev[isd_ic_prpenc],
.remote_pad = 0,
},
},
@@ -148,7 +142,8 @@ static const struct internal_subdev {
.pad[PRP_SRC_PAD_PRPVF] = {
.link = {
{
- .remote_id = &isd_id[isd_ic_prpvf],
+ .local_pad = PRP_SRC_PAD_PRPVF,
+ .remote = &int_subdev[isd_ic_prpvf],
.remote_pad = 0,
},
},
@@ -157,70 +152,111 @@ static const struct internal_subdev {
[isd_ic_prpenc] = {
.id = &isd_id[isd_ic_prpenc],
- .num_sink_pads = PRPENCVF_NUM_SINK_PADS,
- .num_src_pads = PRPENCVF_NUM_SRC_PADS,
- .pad[PRPENCVF_SRC_PAD] = {
- .devnode = true,
- },
},
[isd_ic_prpvf] = {
.id = &isd_id[isd_ic_prpvf],
- .num_sink_pads = PRPENCVF_NUM_SINK_PADS,
- .num_src_pads = PRPENCVF_NUM_SRC_PADS,
- .pad[PRPENCVF_SRC_PAD] = {
- .devnode = true,
- },
},
};
-/* form a device name given a group id and ipu id */
-static inline void isd_id_to_devname(char *devname, int sz,
- const struct internal_subdev_id *id,
- int ipu_id)
+/* form a device name given an internal subdev and ipu id */
+static inline void isd_to_devname(char *devname, int sz,
+ const struct internal_subdev *isd,
+ int ipu_id)
{
- int pdev_id = ipu_id * num_isd + id->index;
+ int pdev_id = ipu_id * num_isd + isd->id->index;
- snprintf(devname, sz, "%s.%d", id->name, pdev_id);
+ snprintf(devname, sz, "%s.%d", isd->id->name, pdev_id);
}
-/* adds the links from given internal subdev */
-static int add_internal_links(struct imx_media_dev *imxmd,
- const struct internal_subdev *isd,
- struct imx_media_subdev *imxsd,
- int ipu_id)
+static const struct internal_subdev *find_intsd_by_grp_id(u32 grp_id)
{
- int i, num_pads, ret;
+ enum isd_enum i;
- num_pads = isd->num_sink_pads + isd->num_src_pads;
+ for (i = 0; i < num_isd; i++) {
+ const struct internal_subdev *isd = &int_subdev[i];
- for (i = 0; i < num_pads; i++) {
- const struct internal_pad *intpad = &isd->pad[i];
- struct imx_media_pad *pad = &imxsd->pad[i];
- int j;
+ if (isd->id->grp_id == grp_id)
+ return isd;
+ }
- /* init the pad flags for this internal subdev */
- pad->pad.flags = (i < isd->num_sink_pads) ?
- MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
- /* export devnode pad flag to the subdevs */
- pad->devnode = intpad->devnode;
+ return NULL;
+}
- for (j = 0; ; j++) {
- const struct internal_link *link;
- char remote_devname[32];
+static struct v4l2_subdev *find_sink(struct imx_media_dev *imxmd,
+ struct v4l2_subdev *src,
+ const struct internal_link *link)
+{
+ char sink_devname[32];
+ int ipu_id;
+
+ /*
+ * retrieve IPU id from subdev name, note: can't get this from
+ * struct imx_media_internal_sd_platformdata because if src is
+ * a CSI, it has different struct ipu_client_platformdata which
+ * does not contain IPU id.
+ */
+ if (sscanf(src->name, "ipu%d", &ipu_id) != 1)
+ return NULL;
+
+ isd_to_devname(sink_devname, sizeof(sink_devname),
+ link->remote, ipu_id - 1);
+
+ return imx_media_find_subdev_by_devname(imxmd, sink_devname);
+}
+
+static int create_ipu_internal_link(struct imx_media_dev *imxmd,
+ struct v4l2_subdev *src,
+ const struct internal_link *link)
+{
+ struct v4l2_subdev *sink;
+ int ret;
+
+ sink = find_sink(imxmd, src, link);
+ if (!sink)
+ return -ENODEV;
+
+ v4l2_info(&imxmd->v4l2_dev, "%s:%d -> %s:%d\n",
+ src->name, link->local_pad,
+ sink->name, link->remote_pad);
+ ret = media_create_pad_link(&src->entity, link->local_pad,
+ &sink->entity, link->remote_pad, 0);
+ if (ret)
+ v4l2_err(&imxmd->v4l2_dev,
+ "create_pad_link failed: %d\n", ret);
+
+ return ret;
+}
+
+int imx_media_create_internal_links(struct imx_media_dev *imxmd,
+ struct v4l2_subdev *sd)
+{
+ const struct internal_subdev *intsd;
+ const struct internal_pad *intpad;
+ const struct internal_link *link;
+ struct media_pad *pad;
+ int i, j, ret;
+
+ intsd = find_intsd_by_grp_id(sd->grp_id);
+ if (!intsd)
+ return -ENODEV;
+
+ /* create the source->sink links */
+ for (i = 0; i < sd->entity.num_pads; i++) {
+ intpad = &intsd->pad[i];
+ pad = &sd->entity.pads[i];
+
+ if (!(pad->flags & MEDIA_PAD_FL_SOURCE))
+ continue;
+
+ for (j = 0; ; j++) {
link = &intpad->link[j];
- if (!link->remote_id)
+ if (!link->remote)
break;
- isd_id_to_devname(remote_devname,
- sizeof(remote_devname),
- link->remote_id, ipu_id);
-
- ret = imx_media_add_pad_link(imxmd, pad,
- NULL, remote_devname,
- i, link->remote_pad);
+ ret = create_ipu_internal_link(imxmd, sd, link);
if (ret)
return ret;
}
@@ -230,14 +266,12 @@ static int add_internal_links(struct imx_media_dev *imxmd,
}
/* register an internal subdev as a platform device */
-static struct imx_media_subdev *
-add_internal_subdev(struct imx_media_dev *imxmd,
- const struct internal_subdev *isd,
- int ipu_id)
+static int add_internal_subdev(struct imx_media_dev *imxmd,
+ const struct internal_subdev *isd,
+ int ipu_id)
{
struct imx_media_internal_sd_platformdata pdata;
struct platform_device_info pdevinfo = {0};
- struct imx_media_subdev *imxsd;
struct platform_device *pdev;
pdata.grp_id = isd->id->grp_id;
@@ -258,73 +292,51 @@ add_internal_subdev(struct imx_media_dev *imxmd,
pdev = platform_device_register_full(&pdevinfo);
if (IS_ERR(pdev))
- return ERR_CAST(pdev);
+ return PTR_ERR(pdev);
- imxsd = imx_media_add_async_subdev(imxmd, NULL, pdev);
- if (IS_ERR(imxsd))
- return imxsd;
-
- imxsd->num_sink_pads = isd->num_sink_pads;
- imxsd->num_src_pads = isd->num_src_pads;
-
- return imxsd;
+ return imx_media_add_async_subdev(imxmd, NULL, pdev);
}
/* adds the internal subdevs in one ipu */
-static int add_ipu_internal_subdevs(struct imx_media_dev *imxmd,
- struct imx_media_subdev *csi0,
- struct imx_media_subdev *csi1,
- int ipu_id)
+static int add_ipu_internal_subdevs(struct imx_media_dev *imxmd, int ipu_id)
{
enum isd_enum i;
- int ret;
for (i = 0; i < num_isd; i++) {
- const struct internal_subdev *isd = &internal_subdev[i];
- struct imx_media_subdev *imxsd;
+ const struct internal_subdev *isd = &int_subdev[i];
+ int ret;
/*
* the CSIs are represented in the device-tree, so those
- * devices are added already, and are added to the async
- * subdev list by of_parse_subdev(), so we are given those
- * subdevs as csi0 and csi1.
+ * devices are already added to the async subdev list by
+ * of_parse_subdev().
*/
switch (isd->id->grp_id) {
case IMX_MEDIA_GRP_ID_CSI0:
- imxsd = csi0;
- break;
case IMX_MEDIA_GRP_ID_CSI1:
- imxsd = csi1;
+ ret = 0;
break;
default:
- imxsd = add_internal_subdev(imxmd, isd, ipu_id);
+ ret = add_internal_subdev(imxmd, isd, ipu_id);
break;
}
- if (IS_ERR(imxsd))
- return PTR_ERR(imxsd);
-
- /* add the links from this subdev */
- if (imxsd) {
- ret = add_internal_links(imxmd, isd, imxsd, ipu_id);
- if (ret)
- return ret;
- }
+ if (ret)
+ return ret;
}
return 0;
}
-int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd,
- struct imx_media_subdev *csi[4])
+int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd)
{
int ret;
- ret = add_ipu_internal_subdevs(imxmd, csi[0], csi[1], 0);
+ ret = add_ipu_internal_subdevs(imxmd, 0);
if (ret)
goto remove;
- ret = add_ipu_internal_subdevs(imxmd, csi[2], csi[3], 1);
+ ret = add_ipu_internal_subdevs(imxmd, 1);
if (ret)
goto remove;
@@ -337,13 +349,12 @@ remove:
void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd)
{
- struct imx_media_subdev *imxsd;
- int i;
+ struct imx_media_async_subdev *imxasd;
- for (i = 0; i < imxmd->subdev_notifier.num_subdevs; i++) {
- imxsd = &imxmd->subdev[i];
- if (!imxsd->pdev)
+ list_for_each_entry(imxasd, &imxmd->asd_list, list) {
+ if (!imxasd->pdev)
continue;
- platform_device_unregister(imxsd->pdev);
+
+ platform_device_unregister(imxasd->pdev);
}
}
diff --git a/drivers/staging/media/imx/imx-media-of.c b/drivers/staging/media/imx/imx-media-of.c
index 12df09f52490..acde372c6795 100644
--- a/drivers/staging/media/imx/imx-media-of.c
+++ b/drivers/staging/media/imx/imx-media-of.c
@@ -20,34 +20,6 @@
#include <video/imx-ipu-v3.h>
#include "imx-media.h"
-static int of_add_pad_link(struct imx_media_dev *imxmd,
- struct imx_media_pad *pad,
- struct device_node *local_sd_node,
- struct device_node *remote_sd_node,
- int local_pad, int remote_pad)
-{
- dev_dbg(imxmd->md.dev, "%s: adding %s:%d -> %s:%d\n", __func__,
- local_sd_node->name, local_pad,
- remote_sd_node->name, remote_pad);
-
- return imx_media_add_pad_link(imxmd, pad, remote_sd_node, NULL,
- local_pad, remote_pad);
-}
-
-static void of_parse_sensor(struct imx_media_dev *imxmd,
- struct imx_media_subdev *sensor,
- struct device_node *sensor_np)
-{
- struct device_node *endpoint;
-
- endpoint = of_graph_get_next_endpoint(sensor_np, NULL);
- if (endpoint) {
- v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint),
- &sensor->sensor_ep);
- of_node_put(endpoint);
- }
-}
-
static int of_get_port_count(const struct device_node *np)
{
struct device_node *ports, *child;
@@ -67,15 +39,14 @@ static int of_get_port_count(const struct device_node *np)
}
/*
- * find the remote device node and remote port id (remote pad #)
- * given local endpoint node
+ * find the remote device node given local endpoint node
*/
-static void of_get_remote_pad(struct device_node *epnode,
- struct device_node **remote_node,
- int *remote_pad)
+static bool of_get_remote(struct device_node *epnode,
+ struct device_node **remote_node)
{
struct device_node *rp, *rpp;
struct device_node *remote;
+ bool is_csi_port;
rp = of_graph_get_remote_port(epnode);
rpp = of_graph_get_remote_port_parent(epnode);
@@ -83,13 +54,12 @@ static void of_get_remote_pad(struct device_node *epnode,
if (of_device_is_compatible(rpp, "fsl,imx6q-ipu")) {
/* the remote is one of the CSI ports */
remote = rp;
- *remote_pad = 0;
of_node_put(rpp);
+ is_csi_port = true;
} else {
remote = rpp;
- if (of_property_read_u32(rp, "reg", remote_pad))
- *remote_pad = 0;
of_node_put(rp);
+ is_csi_port = false;
}
if (!of_device_is_available(remote)) {
@@ -98,130 +68,66 @@ static void of_get_remote_pad(struct device_node *epnode,
} else {
*remote_node = remote;
}
+
+ return is_csi_port;
}
static int
of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np,
- bool is_csi_port, struct imx_media_subdev **subdev)
+ bool is_csi_port)
{
- struct imx_media_subdev *imxsd;
- int i, num_pads, ret;
+ int i, num_ports, ret;
if (!of_device_is_available(sd_np)) {
dev_dbg(imxmd->md.dev, "%s: %s not enabled\n", __func__,
sd_np->name);
- *subdev = NULL;
/* unavailable is not an error */
return 0;
}
/* register this subdev with async notifier */
- imxsd = imx_media_add_async_subdev(imxmd, sd_np, NULL);
- ret = PTR_ERR_OR_ZERO(imxsd);
+ ret = imx_media_add_async_subdev(imxmd, of_fwnode_handle(sd_np),
+ NULL);
if (ret) {
if (ret == -EEXIST) {
/* already added, everything is fine */
- *subdev = NULL;
return 0;
}
/* other error, can't continue */
return ret;
}
- *subdev = imxsd;
-
- if (is_csi_port) {
- /*
- * the ipu-csi has one sink port and two source ports.
- * The source ports are not represented in the device tree,
- * but are described by the internal pads and links later.
- */
- num_pads = CSI_NUM_PADS;
- imxsd->num_sink_pads = CSI_NUM_SINK_PADS;
- } else if (of_device_is_compatible(sd_np, "fsl,imx6-mipi-csi2")) {
- num_pads = of_get_port_count(sd_np);
- /* the mipi csi2 receiver has only one sink port */
- imxsd->num_sink_pads = 1;
- } else if (of_device_is_compatible(sd_np, "video-mux")) {
- num_pads = of_get_port_count(sd_np);
- /* for the video mux, all but the last port are sinks */
- imxsd->num_sink_pads = num_pads - 1;
- } else {
- num_pads = of_get_port_count(sd_np);
- if (num_pads != 1) {
- /* confused, but no reason to give up here */
- dev_warn(imxmd->md.dev,
- "%s: unknown device %s with %d ports\n",
- __func__, sd_np->name, num_pads);
- return 0;
- }
-
- /*
- * we got to this node from this single source port,
- * there are no sink pads.
- */
- imxsd->num_sink_pads = 0;
- }
-
- if (imxsd->num_sink_pads >= num_pads)
- return -EINVAL;
-
- imxsd->num_src_pads = num_pads - imxsd->num_sink_pads;
-
- dev_dbg(imxmd->md.dev, "%s: %s has %d pads (%d sink, %d src)\n",
- __func__, sd_np->name, num_pads,
- imxsd->num_sink_pads, imxsd->num_src_pads);
/*
- * With no sink, this subdev node is the original source
- * of video, parse it's media bus for use by the pipeline.
+ * the ipu-csi has one sink port. The source pads are not
+ * represented in the device tree by port nodes, but are
+ * described by the internal pads and links later.
*/
- if (imxsd->num_sink_pads == 0)
- of_parse_sensor(imxmd, imxsd, sd_np);
+ num_ports = is_csi_port ? 1 : of_get_port_count(sd_np);
- for (i = 0; i < num_pads; i++) {
+ for (i = 0; i < num_ports; i++) {
struct device_node *epnode = NULL, *port, *remote_np;
- struct imx_media_subdev *remote_imxsd;
- struct imx_media_pad *pad;
- int remote_pad;
-
- /* init this pad */
- pad = &imxsd->pad[i];
- pad->pad.flags = (i < imxsd->num_sink_pads) ?
- MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
-
- if (is_csi_port)
- port = (i < imxsd->num_sink_pads) ? sd_np : NULL;
- else
- port = of_graph_get_port_by_id(sd_np, i);
+
+ port = is_csi_port ? sd_np : of_graph_get_port_by_id(sd_np, i);
if (!port)
continue;
for_each_child_of_node(port, epnode) {
- of_get_remote_pad(epnode, &remote_np, &remote_pad);
+ bool remote_is_csi;
+
+ remote_is_csi = of_get_remote(epnode, &remote_np);
if (!remote_np)
continue;
- ret = of_add_pad_link(imxmd, pad, sd_np, remote_np,
- i, remote_pad);
+ ret = of_parse_subdev(imxmd, remote_np, remote_is_csi);
+ of_node_put(remote_np);
if (ret)
break;
-
- if (i < imxsd->num_sink_pads) {
- /* follow sink endpoints upstream */
- ret = of_parse_subdev(imxmd, remote_np,
- false, &remote_imxsd);
- if (ret)
- break;
- }
-
- of_node_put(remote_np);
}
if (port != sd_np)
of_node_put(port);
if (ret) {
- of_node_put(remote_np);
of_node_put(epnode);
break;
}
@@ -230,13 +136,10 @@ of_parse_subdev(struct imx_media_dev *imxmd, struct device_node *sd_np,
return ret;
}
-int imx_media_of_parse(struct imx_media_dev *imxmd,
- struct imx_media_subdev *(*csi)[4],
- struct device_node *np)
+int imx_media_add_of_subdevs(struct imx_media_dev *imxmd,
+ struct device_node *np)
{
- struct imx_media_subdev *lcsi;
struct device_node *csi_np;
- u32 ipu_id, csi_id;
int i, ret;
for (i = 0; ; i++) {
@@ -244,33 +147,120 @@ int imx_media_of_parse(struct imx_media_dev *imxmd,
if (!csi_np)
break;
- ret = of_parse_subdev(imxmd, csi_np, true, &lcsi);
+ ret = of_parse_subdev(imxmd, csi_np, true);
+ of_node_put(csi_np);
if (ret)
- goto err_put;
+ return ret;
+ }
- ret = of_property_read_u32(csi_np, "reg", &csi_id);
- if (ret) {
- dev_err(imxmd->md.dev,
- "%s: csi port missing reg property!\n",
- __func__);
- goto err_put;
- }
+ return 0;
+}
- ipu_id = of_alias_get_id(csi_np->parent, "ipu");
- of_node_put(csi_np);
+/*
+ * Create a single media link to/from sd using a fwnode link.
+ *
+ * NOTE: this function assumes an OF port node is equivalent to
+ * a media pad (port id equal to media pad index), and that an
+ * OF endpoint node is equivalent to a media link.
+ */
+static int create_of_link(struct imx_media_dev *imxmd,
+ struct v4l2_subdev *sd,
+ struct v4l2_fwnode_link *link)
+{
+ struct v4l2_subdev *remote, *src, *sink;
+ int src_pad, sink_pad;
- if (ipu_id > 1 || csi_id > 1) {
- dev_err(imxmd->md.dev,
- "%s: invalid ipu/csi id (%u/%u)\n",
- __func__, ipu_id, csi_id);
- return -EINVAL;
- }
+ if (link->local_port >= sd->entity.num_pads)
+ return -EINVAL;
+
+ remote = imx_media_find_subdev_by_fwnode(imxmd, link->remote_node);
+ if (!remote)
+ return 0;
+
+ if (sd->entity.pads[link->local_port].flags & MEDIA_PAD_FL_SINK) {
+ src = remote;
+ src_pad = link->remote_port;
+ sink = sd;
+ sink_pad = link->local_port;
+ } else {
+ src = sd;
+ src_pad = link->local_port;
+ sink = remote;
+ sink_pad = link->remote_port;
+ }
+
+ /* make sure link doesn't already exist before creating */
+ if (media_entity_find_link(&src->entity.pads[src_pad],
+ &sink->entity.pads[sink_pad]))
+ return 0;
+
+ v4l2_info(sd->v4l2_dev, "%s:%d -> %s:%d\n",
+ src->name, src_pad, sink->name, sink_pad);
+
+ return media_create_pad_link(&src->entity, src_pad,
+ &sink->entity, sink_pad, 0);
+}
+
+/*
+ * Create media links to/from sd using its device-tree endpoints.
+ */
+int imx_media_create_of_links(struct imx_media_dev *imxmd,
+ struct v4l2_subdev *sd)
+{
+ struct v4l2_fwnode_link link;
+ struct device_node *ep;
+ int ret;
+
+ for_each_endpoint_of_node(sd->dev->of_node, ep) {
+ ret = v4l2_fwnode_parse_link(of_fwnode_handle(ep), &link);
+ if (ret)
+ continue;
- (*csi)[ipu_id * 2 + csi_id] = lcsi;
+ ret = create_of_link(imxmd, sd, &link);
+ v4l2_fwnode_put_link(&link);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Create media links to the given CSI subdevice's sink pads,
+ * using its device-tree endpoints.
+ */
+int imx_media_create_csi_of_links(struct imx_media_dev *imxmd,
+ struct v4l2_subdev *csi)
+{
+ struct device_node *csi_np = csi->dev->of_node;
+ struct fwnode_handle *fwnode, *csi_ep;
+ struct v4l2_fwnode_link link;
+ struct device_node *ep;
+ int ret;
+
+ link.local_node = of_fwnode_handle(csi_np);
+ link.local_port = CSI_SINK_PAD;
+
+ for_each_child_of_node(csi_np, ep) {
+ csi_ep = of_fwnode_handle(ep);
+
+ fwnode = fwnode_graph_get_remote_endpoint(csi_ep);
+ if (!fwnode)
+ continue;
+
+ fwnode = fwnode_get_parent(fwnode);
+ fwnode_property_read_u32(fwnode, "reg", &link.remote_port);
+ fwnode = fwnode_get_next_parent(fwnode);
+ if (is_of_node(fwnode) &&
+ of_node_cmp(to_of_node(fwnode)->name, "ports") == 0)
+ fwnode = fwnode_get_next_parent(fwnode);
+ link.remote_node = fwnode;
+
+ ret = create_of_link(imxmd, csi, &link);
+ fwnode_handle_put(link.remote_node);
+ if (ret)
+ return ret;
}
return 0;
-err_put:
- of_node_put(csi_np);
- return ret;
}
diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c
index 59523872a886..13dafa77a2eb 100644
--- a/drivers/staging/media/imx/imx-media-utils.c
+++ b/drivers/staging/media/imx/imx-media-utils.c
@@ -668,38 +668,35 @@ void imx_media_grp_id_to_sd_name(char *sd_name, int sz, u32 grp_id, int ipu_id)
}
EXPORT_SYMBOL_GPL(imx_media_grp_id_to_sd_name);
-struct imx_media_subdev *
-imx_media_find_subdev_by_sd(struct imx_media_dev *imxmd,
- struct v4l2_subdev *sd)
+struct v4l2_subdev *
+imx_media_find_subdev_by_fwnode(struct imx_media_dev *imxmd,
+ struct fwnode_handle *fwnode)
{
- struct imx_media_subdev *imxsd;
- int i;
+ struct v4l2_subdev *sd;
- for (i = 0; i < imxmd->num_subdevs; i++) {
- imxsd = &imxmd->subdev[i];
- if (sd == imxsd->sd)
- return imxsd;
+ list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
+ if (sd->fwnode == fwnode)
+ return sd;
}
- return ERR_PTR(-ENODEV);
+ return NULL;
}
-EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_sd);
+EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_fwnode);
-struct imx_media_subdev *
-imx_media_find_subdev_by_id(struct imx_media_dev *imxmd, u32 grp_id)
+struct v4l2_subdev *
+imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd,
+ const char *devname)
{
- struct imx_media_subdev *imxsd;
- int i;
+ struct v4l2_subdev *sd;
- for (i = 0; i < imxmd->num_subdevs; i++) {
- imxsd = &imxmd->subdev[i];
- if (imxsd->sd && imxsd->sd->grp_id == grp_id)
- return imxsd;
+ list_for_each_entry(sd, &imxmd->v4l2_dev.subdevs, list) {
+ if (!strcmp(devname, dev_name(sd->dev)))
+ return sd;
}
- return ERR_PTR(-ENODEV);
+ return NULL;
}
-EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_id);
+EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_devname);
/*
* Adds a video device to the master video device list. This is called by
@@ -708,32 +705,21 @@ EXPORT_SYMBOL_GPL(imx_media_find_subdev_by_id);
int imx_media_add_video_device(struct imx_media_dev *imxmd,
struct imx_media_video_dev *vdev)
{
- int vdev_idx, ret = 0;
-
mutex_lock(&imxmd->mutex);
- vdev_idx = imxmd->num_vdevs;
- if (vdev_idx >= IMX_MEDIA_MAX_VDEVS) {
- dev_err(imxmd->md.dev,
- "%s: too many video devices! can't add %s\n",
- __func__, vdev->vfd->name);
- ret = -ENOSPC;
- goto out;
- }
+ list_add_tail(&vdev->list, &imxmd->vdev_list);
- imxmd->vdev[vdev_idx] = vdev;
- imxmd->num_vdevs++;
-out:
mutex_unlock(&imxmd->mutex);
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(imx_media_add_video_device);
/*
- * Search upstream or downstream for a subdevice in the current pipeline
+ * Search upstream/downstream for a subdevice in the current pipeline
* with given grp_id, starting from start_entity. Returns the subdev's
- * source/sink pad that it was reached from. Must be called with
- * mdev->graph_mutex held.
+ * source/sink pad that it was reached from. If grp_id is zero, just
+ * returns the nearest source/sink pad to start_entity. Must be called
+ * with mdev->graph_mutex held.
*/
static struct media_pad *
find_pipeline_pad(struct imx_media_dev *imxmd,
@@ -756,11 +742,16 @@ find_pipeline_pad(struct imx_media_dev *imxmd,
if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
continue;
- sd = media_entity_to_v4l2_subdev(pad->entity);
- if (sd->grp_id & grp_id)
- return pad;
+ if (grp_id != 0) {
+ sd = media_entity_to_v4l2_subdev(pad->entity);
+ if (sd->grp_id & grp_id)
+ return pad;
- return find_pipeline_pad(imxmd, pad->entity, grp_id, upstream);
+ return find_pipeline_pad(imxmd, pad->entity,
+ grp_id, upstream);
+ } else {
+ return pad;
+ }
}
return NULL;
@@ -789,7 +780,6 @@ find_upstream_subdev(struct imx_media_dev *imxmd,
return pad ? media_entity_to_v4l2_subdev(pad->entity) : NULL;
}
-
/*
* Find the upstream mipi-csi2 virtual channel reached from the given
* start entity in the current pipeline.
@@ -814,11 +804,30 @@ int imx_media_find_mipi_csi2_channel(struct imx_media_dev *imxmd,
EXPORT_SYMBOL_GPL(imx_media_find_mipi_csi2_channel);
/*
+ * Find a source pad reached upstream from the given start entity in
+ * the current pipeline. Must be called with mdev->graph_mutex held.
+ */
+struct media_pad *
+imx_media_find_upstream_pad(struct imx_media_dev *imxmd,
+ struct media_entity *start_entity,
+ u32 grp_id)
+{
+ struct media_pad *pad;
+
+ pad = find_pipeline_pad(imxmd, start_entity, grp_id, true);
+ if (!pad)
+ return ERR_PTR(-ENODEV);
+
+ return pad;
+}
+EXPORT_SYMBOL_GPL(imx_media_find_upstream_pad);
+
+/*
* Find a subdev reached upstream from the given start entity in
* the current pipeline.
* Must be called with mdev->graph_mutex held.
*/
-struct imx_media_subdev *
+struct v4l2_subdev *
imx_media_find_upstream_subdev(struct imx_media_dev *imxmd,
struct media_entity *start_entity,
u32 grp_id)
@@ -829,33 +838,10 @@ imx_media_find_upstream_subdev(struct imx_media_dev *imxmd,
if (!sd)
return ERR_PTR(-ENODEV);
- return imx_media_find_subdev_by_sd(imxmd, sd);
+ return sd;
}
EXPORT_SYMBOL_GPL(imx_media_find_upstream_subdev);
-struct imx_media_subdev *
-__imx_media_find_sensor(struct imx_media_dev *imxmd,
- struct media_entity *start_entity)
-{
- return imx_media_find_upstream_subdev(imxmd, start_entity,
- IMX_MEDIA_GRP_ID_SENSOR);
-}
-EXPORT_SYMBOL_GPL(__imx_media_find_sensor);
-
-struct imx_media_subdev *
-imx_media_find_sensor(struct imx_media_dev *imxmd,
- struct media_entity *start_entity)
-{
- struct imx_media_subdev *sensor;
-
- mutex_lock(&imxmd->md.graph_mutex);
- sensor = __imx_media_find_sensor(imxmd, start_entity);
- mutex_unlock(&imxmd->md.graph_mutex);
-
- return sensor;
-}
-EXPORT_SYMBOL_GPL(imx_media_find_sensor);
-
/*
* Turn current pipeline streaming on/off starting from entity.
*/
diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h
index ac3ab115394f..2fd6dfdf37d6 100644
--- a/drivers/staging/media/imx/imx-media.h
+++ b/drivers/staging/media/imx/imx-media.h
@@ -11,6 +11,7 @@
#ifndef _IMX_MEDIA_H
#define _IMX_MEDIA_H
+#include <linux/platform_device.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
@@ -19,26 +20,6 @@
#include <video/imx-ipu-v3.h>
/*
- * This is somewhat arbitrary, but we need at least:
- * - 4 video devices per IPU
- * - 3 IC subdevs per IPU
- * - 1 VDIC subdev per IPU
- * - 2 CSI subdevs per IPU
- * - 1 mipi-csi2 receiver subdev
- * - 2 video-mux subdevs
- * - 2 camera sensor subdevs per IPU (1 parallel, 1 mipi-csi2)
- *
- */
-/* max video devices */
-#define IMX_MEDIA_MAX_VDEVS 8
-/* max subdevices */
-#define IMX_MEDIA_MAX_SUBDEVS 32
-/* max pads per subdev */
-#define IMX_MEDIA_MAX_PADS 16
-/* max links per pad */
-#define IMX_MEDIA_MAX_LINKS 8
-
-/*
* Pad definitions for the subdevs with multiple source or
* sink pads
*/
@@ -51,9 +32,6 @@ enum {
CSI_NUM_PADS,
};
-#define CSI_NUM_SINK_PADS 1
-#define CSI_NUM_SRC_PADS 2
-
/* ipu_vdic */
enum {
VDIC_SINK_PAD_DIRECT = 0,
@@ -62,9 +40,6 @@ enum {
VDIC_NUM_PADS,
};
-#define VDIC_NUM_SINK_PADS 2
-#define VDIC_NUM_SRC_PADS 1
-
/* ipu_ic_prp */
enum {
PRP_SINK_PAD = 0,
@@ -73,9 +48,6 @@ enum {
PRP_NUM_PADS,
};
-#define PRP_NUM_SINK_PADS 1
-#define PRP_NUM_SRC_PADS 2
-
/* ipu_ic_prpencvf */
enum {
PRPENCVF_SINK_PAD = 0,
@@ -83,9 +55,6 @@ enum {
PRPENCVF_NUM_PADS,
};
-#define PRPENCVF_NUM_SINK_PADS 1
-#define PRPENCVF_NUM_SRC_PADS 1
-
/* How long to wait for EOF interrupts in the buffer-capture subdevs */
#define IMX_MEDIA_EOF_TIMEOUT 1000
@@ -110,6 +79,9 @@ struct imx_media_video_dev {
/* the user format */
struct v4l2_format fmt;
const struct imx_media_pixfmt *cc;
+
+ /* links this vdev to master list */
+ struct list_head list;
};
static inline struct imx_media_buffer *to_imx_media_vb(struct vb2_buffer *vb)
@@ -119,25 +91,24 @@ static inline struct imx_media_buffer *to_imx_media_vb(struct vb2_buffer *vb)
return container_of(vbuf, struct imx_media_buffer, vbuf);
}
-struct imx_media_link {
- struct device_node *remote_sd_node;
- char remote_devname[32];
- int local_pad;
- int remote_pad;
-};
+/*
+ * to support control inheritance to video devices, this
+ * retrieves a pad's list_head of video devices that can
+ * be reached from the pad. Note that only the lists in
+ * source pads get populated, sink pads have empty lists.
+ */
+static inline struct list_head *
+to_pad_vdev_list(struct v4l2_subdev *sd, int pad_index)
+{
+ struct list_head *vdev_list = sd->host_priv;
-struct imx_media_pad {
- struct media_pad pad;
- struct imx_media_link link[IMX_MEDIA_MAX_LINKS];
- bool devnode; /* does this pad link to a device node */
- int num_links;
-
- /*
- * list of video devices that can be reached from this pad,
- * list is only valid for source pads.
- */
- struct imx_media_video_dev *vdev[IMX_MEDIA_MAX_VDEVS];
- int num_vdevs;
+ return vdev_list ? &vdev_list[pad_index] : NULL;
+}
+
+/* an entry in a pad's video device list */
+struct imx_media_pad_vdev {
+ struct imx_media_video_dev *vdev;
+ struct list_head list;
};
struct imx_media_internal_sd_platformdata {
@@ -146,23 +117,20 @@ struct imx_media_internal_sd_platformdata {
int ipu_id;
};
-struct imx_media_subdev {
- struct v4l2_async_subdev asd;
- struct v4l2_subdev *sd; /* set when bound */
-
- struct imx_media_pad pad[IMX_MEDIA_MAX_PADS];
- int num_sink_pads;
- int num_src_pads;
- /* the platform device if this is an internal subdev */
+struct imx_media_async_subdev {
+ struct v4l2_async_subdev asd;
+ /* the platform device of IPU-internal subdevs */
struct platform_device *pdev;
- /* the devname is needed for async devname match */
- char devname[32];
-
- /* if this is a sensor */
- struct v4l2_fwnode_endpoint sensor_ep;
+ struct list_head list;
};
+static inline struct imx_media_async_subdev *
+to_imx_media_asd(struct v4l2_async_subdev *asd)
+{
+ return container_of(asd, struct imx_media_async_subdev, asd);
+}
+
struct imx_media_dev {
struct media_device md;
struct v4l2_device v4l2_dev;
@@ -172,19 +140,14 @@ struct imx_media_dev {
struct mutex mutex; /* protect elements below */
- /* master subdevice list */
- struct imx_media_subdev subdev[IMX_MEDIA_MAX_SUBDEVS];
- int num_subdevs;
-
/* master video device list */
- struct imx_media_video_dev *vdev[IMX_MEDIA_MAX_VDEVS];
- int num_vdevs;
+ struct list_head vdev_list;
/* IPUs this media driver control, valid after subdevs bound */
struct ipu_soc *ipu[2];
/* for async subdev registration */
- struct v4l2_async_subdev *async_ptrs[IMX_MEDIA_MAX_SUBDEVS];
+ struct list_head asd_list;
struct v4l2_async_notifier subdev_notifier;
};
@@ -194,6 +157,7 @@ enum codespace_sel {
CS_SEL_ANY,
};
+/* imx-media-utils.c */
const struct imx_media_pixfmt *
imx_media_find_format(u32 fourcc, enum codespace_sel cs_sel, bool allow_bayer);
int imx_media_enum_format(u32 *fourcc, u32 index, enum codespace_sel cs_sel);
@@ -205,7 +169,6 @@ int imx_media_enum_mbus_format(u32 *code, u32 index, enum codespace_sel cs_sel,
const struct imx_media_pixfmt *
imx_media_find_ipu_format(u32 code, enum codespace_sel cs_sel);
int imx_media_enum_ipu_format(u32 *code, u32 index, enum codespace_sel cs_sel);
-
int imx_media_init_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
u32 width, u32 height, u32 code, u32 field,
const struct imx_media_pixfmt **cc);
@@ -219,48 +182,26 @@ int imx_media_mbus_fmt_to_ipu_image(struct ipu_image *image,
struct v4l2_mbus_framefmt *mbus);
int imx_media_ipu_image_to_mbus_fmt(struct v4l2_mbus_framefmt *mbus,
struct ipu_image *image);
-
-struct imx_media_subdev *
-imx_media_find_async_subdev(struct imx_media_dev *imxmd,
- struct device_node *np,
- const char *devname);
-struct imx_media_subdev *
-imx_media_add_async_subdev(struct imx_media_dev *imxmd,
- struct device_node *np,
- struct platform_device *pdev);
-int imx_media_add_pad_link(struct imx_media_dev *imxmd,
- struct imx_media_pad *pad,
- struct device_node *remote_node,
- const char *remote_devname,
- int local_pad, int remote_pad);
-
void imx_media_grp_id_to_sd_name(char *sd_name, int sz,
u32 grp_id, int ipu_id);
-
-int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd,
- struct imx_media_subdev *csi[4]);
-void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd);
-
-struct imx_media_subdev *
-imx_media_find_subdev_by_sd(struct imx_media_dev *imxmd,
- struct v4l2_subdev *sd);
-struct imx_media_subdev *
-imx_media_find_subdev_by_id(struct imx_media_dev *imxmd,
- u32 grp_id);
+struct v4l2_subdev *
+imx_media_find_subdev_by_fwnode(struct imx_media_dev *imxmd,
+ struct fwnode_handle *fwnode);
+struct v4l2_subdev *
+imx_media_find_subdev_by_devname(struct imx_media_dev *imxmd,
+ const char *devname);
int imx_media_add_video_device(struct imx_media_dev *imxmd,
struct imx_media_video_dev *vdev);
int imx_media_find_mipi_csi2_channel(struct imx_media_dev *imxmd,
struct media_entity *start_entity);
-struct imx_media_subdev *
+struct media_pad *
+imx_media_find_upstream_pad(struct imx_media_dev *imxmd,
+ struct media_entity *start_entity,
+ u32 grp_id);
+struct v4l2_subdev *
imx_media_find_upstream_subdev(struct imx_media_dev *imxmd,
struct media_entity *start_entity,
u32 grp_id);
-struct imx_media_subdev *
-__imx_media_find_sensor(struct imx_media_dev *imxmd,
- struct media_entity *start_entity);
-struct imx_media_subdev *
-imx_media_find_sensor(struct imx_media_dev *imxmd,
- struct media_entity *start_entity);
struct imx_media_dma_buf {
void *virt;
@@ -278,6 +219,11 @@ int imx_media_pipeline_set_stream(struct imx_media_dev *imxmd,
struct media_entity *entity,
bool on);
+/* imx-media-dev.c */
+int imx_media_add_async_subdev(struct imx_media_dev *imxmd,
+ struct fwnode_handle *fwnode,
+ struct platform_device *pdev);
+
/* imx-media-fim.c */
struct imx_media_fim;
void imx_media_fim_eof_monitor(struct imx_media_fim *fim, ktime_t timestamp);
@@ -288,14 +234,19 @@ int imx_media_fim_add_controls(struct imx_media_fim *fim);
struct imx_media_fim *imx_media_fim_init(struct v4l2_subdev *sd);
void imx_media_fim_free(struct imx_media_fim *fim);
+/* imx-media-internal-sd.c */
+int imx_media_add_internal_subdevs(struct imx_media_dev *imxmd);
+int imx_media_create_internal_links(struct imx_media_dev *imxmd,
+ struct v4l2_subdev *sd);
+void imx_media_remove_internal_subdevs(struct imx_media_dev *imxmd);
+
/* imx-media-of.c */
-struct imx_media_subdev *
-imx_media_of_find_subdev(struct imx_media_dev *imxmd,
- struct device_node *np,
- const char *name);
-int imx_media_of_parse(struct imx_media_dev *dev,
- struct imx_media_subdev *(*csi)[4],
- struct device_node *np);
+int imx_media_add_of_subdevs(struct imx_media_dev *dev,
+ struct device_node *np);
+int imx_media_create_of_links(struct imx_media_dev *imxmd,
+ struct v4l2_subdev *sd);
+int imx_media_create_csi_of_links(struct imx_media_dev *imxmd,
+ struct v4l2_subdev *csi);
/* imx-media-capture.c */
struct imx_media_video_dev *
@@ -310,16 +261,14 @@ void imx_media_capture_device_set_format(struct imx_media_video_dev *vdev,
void imx_media_capture_device_error(struct imx_media_video_dev *vdev);
/* subdev group ids */
-#define IMX_MEDIA_GRP_ID_SENSOR (1 << 8)
-#define IMX_MEDIA_GRP_ID_VIDMUX (1 << 9)
-#define IMX_MEDIA_GRP_ID_CSI2 (1 << 10)
-#define IMX_MEDIA_GRP_ID_CSI_BIT 11
+#define IMX_MEDIA_GRP_ID_CSI2 BIT(8)
+#define IMX_MEDIA_GRP_ID_CSI_BIT 9
#define IMX_MEDIA_GRP_ID_CSI (0x3 << IMX_MEDIA_GRP_ID_CSI_BIT)
-#define IMX_MEDIA_GRP_ID_CSI0 (1 << IMX_MEDIA_GRP_ID_CSI_BIT)
+#define IMX_MEDIA_GRP_ID_CSI0 BIT(IMX_MEDIA_GRP_ID_CSI_BIT)
#define IMX_MEDIA_GRP_ID_CSI1 (2 << IMX_MEDIA_GRP_ID_CSI_BIT)
-#define IMX_MEDIA_GRP_ID_VDIC (1 << 13)
-#define IMX_MEDIA_GRP_ID_IC_PRP (1 << 14)
-#define IMX_MEDIA_GRP_ID_IC_PRPENC (1 << 15)
-#define IMX_MEDIA_GRP_ID_IC_PRPVF (1 << 16)
+#define IMX_MEDIA_GRP_ID_VDIC BIT(11)
+#define IMX_MEDIA_GRP_ID_IC_PRP BIT(12)
+#define IMX_MEDIA_GRP_ID_IC_PRPENC BIT(13)
+#define IMX_MEDIA_GRP_ID_IC_PRPVF BIT(14)
#endif
diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c
index 5061f3f524fd..477d191c568b 100644
--- a/drivers/staging/media/imx/imx6-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx6-mipi-csi2.c
@@ -252,8 +252,8 @@ static int csi2_dphy_wait_stopstate(struct csi2_dev *csi2)
u32 mask, reg;
int ret;
- mask = PHY_STOPSTATECLK |
- ((csi2->bus.num_data_lanes - 1) << PHY_STOPSTATEDATA_BIT);
+ mask = PHY_STOPSTATECLK | (((1 << csi2->bus.num_data_lanes) - 1) <<
+ PHY_STOPSTATEDATA_BIT);
ret = readl_poll_timeout(csi2->base + CSI2_PHY_STATE, reg,
(reg & mask) == mask, 0, 500000);
diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig
deleted file mode 100644
index 3e350a9922de..000000000000
--- a/drivers/staging/media/lirc/Kconfig
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# LIRC driver(s) configuration
-#
-menuconfig LIRC_STAGING
- bool "Linux Infrared Remote Control IR receiver/transmitter drivers"
- depends on LIRC
- help
- Say Y here, and all supported Linux Infrared Remote Control IR and
- RF receiver and transmitter drivers will be displayed. When paired
- with a remote control and the lirc daemon, the receiver drivers
- allow control of your Linux system via remote control.
-
-if LIRC_STAGING
-
-config LIRC_ZILOG
- tristate "Zilog/Hauppauge IR Transmitter"
- depends on LIRC && I2C
- help
- Driver for the Zilog/Hauppauge IR Transmitter, found on
- PVR-150/500, HVR-1200/1250/1700/1800, HD-PVR and other cards
-endif
diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile
deleted file mode 100644
index 665562436e30..000000000000
--- a/drivers/staging/media/lirc/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# Makefile for the lirc drivers.
-#
-
-# Each configuration option enables a list of files.
-
-obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o
diff --git a/drivers/staging/media/lirc/TODO b/drivers/staging/media/lirc/TODO
deleted file mode 100644
index a97800a8e127..000000000000
--- a/drivers/staging/media/lirc/TODO
+++ /dev/null
@@ -1,36 +0,0 @@
-1. Both ir-kbd-i2c and lirc_zilog provide support for RX events for
-the chips supported by lirc_zilog. Before moving lirc_zilog out of staging:
-
-a. ir-kbd-i2c needs a module parameter added to allow the user to tell
- ir-kbd-i2c to ignore Z8 IR units.
-
-b. lirc_zilog should provide Rx key presses to the rc core like ir-kbd-i2c
- does.
-
-
-2. lirc_zilog module ref-counting need examination. It has not been
-verified that cdev and lirc_dev will take the proper module references on
-lirc_zilog to prevent removal of lirc_zilog when the /dev/lircN device node
-is open.
-
-(The good news is ref-counting of lirc_zilog internal structures appears to be
-complete. Testing has shown the cx18 module can be unloaded out from under
-irw + lircd + lirc_dev, with the /dev/lirc0 device node open, with no adverse
-effects. The cx18 module could then be reloaded and irw properly began
-receiving button presses again and ir_send worked without error.)
-
-
-3. Bridge drivers, if able, should provide a chip reset() callback
-to lirc_zilog via struct IR_i2c_init_data. cx18 and ivtv already have routines
-to perform Z8 chip resets via GPIO manipulations. This would allow lirc_zilog
-to bring the chip back to normal when it hangs, in the same places the
-original lirc_pvr150 driver code does. This is not strictly needed, so it
-is not required to move lirc_zilog out of staging.
-
-Note: Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed
-and installed on Hauppauge products. When working on either module, developers
-must consider at least the following bridge drivers which mention an IR Rx unit
-at address 0x71 (indicative of a Z8):
-
- ivtv cx18 hdpvr pvrusb2 bt8xx cx88 saa7134
-
diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c
deleted file mode 100644
index a003603af725..000000000000
--- a/drivers/staging/media/lirc/lirc_zilog.c
+++ /dev/null
@@ -1,1653 +0,0 @@
-/*
- * i2c IR lirc driver for devices with zilog IR processors
- *
- * Copyright (c) 2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
- * modified for PixelView (BT878P+W/FM) by
- * Michal Kochanowicz <mkochano@pld.org.pl>
- * Christoph Bartelmus <lirc@bartelmus.de>
- * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by
- * Ulrich Mueller <ulrich.mueller42@web.de>
- * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by
- * Stefan Jahn <stefan@lkcc.org>
- * modified for inclusion into kernel sources by
- * Jerome Brock <jbrock@users.sourceforge.net>
- * modified for Leadtek Winfast PVR2000 by
- * Thomas Reitmayr (treitmayr@yahoo.com)
- * modified for Hauppauge PVR-150 IR TX device by
- * Mark Weaver <mark@npsl.co.uk>
- * changed name from lirc_pvr150 to lirc_zilog, works on more than pvr-150
- * Jarod Wilson <jarod@redhat.com>
- *
- * parts are cut&pasted from the lirc_i2c.c driver
- *
- * Numerous changes updating lirc_zilog.c in kernel 2.6.38 and later are
- * Copyright (C) 2011 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/module.h>
-#include <linux/kmod.h>
-#include <linux/kernel.h>
-#include <linux/sched/signal.h>
-#include <linux/fs.h>
-#include <linux/poll.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/completion.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/firmware.h>
-#include <linux/vmalloc.h>
-
-#include <linux/mutex.h>
-#include <linux/kthread.h>
-
-#include <media/lirc_dev.h>
-#include <media/lirc.h>
-
-/* Max transfer size done by I2C transfer functions */
-#define MAX_XFER_SIZE 64
-
-struct IR;
-
-struct IR_rx {
- struct kref ref;
- struct IR *ir;
-
- /* RX device */
- struct mutex client_lock;
- struct i2c_client *c;
-
- /* RX polling thread data */
- struct task_struct *task;
-
- /* RX read data */
- unsigned char b[3];
- bool hdpvr_data_fmt;
-};
-
-struct IR_tx {
- struct kref ref;
- struct IR *ir;
-
- /* TX device */
- struct mutex client_lock;
- struct i2c_client *c;
-
- /* TX additional actions needed */
- int need_boot;
- bool post_tx_ready_poll;
-};
-
-struct IR {
- struct kref ref;
- struct list_head list;
-
- /* FIXME spinlock access to l->features */
- struct lirc_dev *l;
- struct lirc_buffer rbuf;
-
- struct mutex ir_lock;
- atomic_t open_count;
-
- struct device *dev;
- struct i2c_adapter *adapter;
-
- spinlock_t rx_ref_lock; /* struct IR_rx kref get()/put() */
- struct IR_rx *rx;
-
- spinlock_t tx_ref_lock; /* struct IR_tx kref get()/put() */
- struct IR_tx *tx;
-};
-
-/* IR transceiver instance object list */
-/*
- * This lock is used for the following:
- * a. ir_devices_list access, insertions, deletions
- * b. struct IR kref get()s and put()s
- * c. serialization of ir_probe() for the two i2c_clients for a Z8
- */
-static DEFINE_MUTEX(ir_devices_lock);
-static LIST_HEAD(ir_devices_list);
-
-/* Block size for IR transmitter */
-#define TX_BLOCK_SIZE 99
-
-/* Hauppauge IR transmitter data */
-struct tx_data_struct {
- /* Boot block */
- unsigned char *boot_data;
-
- /* Start of binary data block */
- unsigned char *datap;
-
- /* End of binary data block */
- unsigned char *endp;
-
- /* Number of installed codesets */
- unsigned int num_code_sets;
-
- /* Pointers to codesets */
- unsigned char **code_sets;
-
- /* Global fixed data template */
- int fixed[TX_BLOCK_SIZE];
-};
-
-static struct tx_data_struct *tx_data;
-static struct mutex tx_data_lock;
-
-
-/* module parameters */
-static bool debug; /* debug output */
-static bool tx_only; /* only handle the IR Tx function */
-
-
-/* struct IR reference counting */
-static struct IR *get_ir_device(struct IR *ir, bool ir_devices_lock_held)
-{
- if (ir_devices_lock_held) {
- kref_get(&ir->ref);
- } else {
- mutex_lock(&ir_devices_lock);
- kref_get(&ir->ref);
- mutex_unlock(&ir_devices_lock);
- }
- return ir;
-}
-
-static void release_ir_device(struct kref *ref)
-{
- struct IR *ir = container_of(ref, struct IR, ref);
-
- /*
- * Things should be in this state by now:
- * ir->rx set to NULL and deallocated - happens before ir->rx->ir put()
- * ir->rx->task kthread stopped - happens before ir->rx->ir put()
- * ir->tx set to NULL and deallocated - happens before ir->tx->ir put()
- * ir->open_count == 0 - happens on final close()
- * ir_lock, tx_ref_lock, rx_ref_lock, all released
- */
- if (ir->l)
- lirc_unregister_device(ir->l);
-
- if (kfifo_initialized(&ir->rbuf.fifo))
- lirc_buffer_free(&ir->rbuf);
- list_del(&ir->list);
- kfree(ir);
-}
-
-static int put_ir_device(struct IR *ir, bool ir_devices_lock_held)
-{
- int released;
-
- if (ir_devices_lock_held)
- return kref_put(&ir->ref, release_ir_device);
-
- mutex_lock(&ir_devices_lock);
- released = kref_put(&ir->ref, release_ir_device);
- mutex_unlock(&ir_devices_lock);
-
- return released;
-}
-
-/* struct IR_rx reference counting */
-static struct IR_rx *get_ir_rx(struct IR *ir)
-{
- struct IR_rx *rx;
-
- spin_lock(&ir->rx_ref_lock);
- rx = ir->rx;
- if (rx)
- kref_get(&rx->ref);
- spin_unlock(&ir->rx_ref_lock);
- return rx;
-}
-
-static void destroy_rx_kthread(struct IR_rx *rx, bool ir_devices_lock_held)
-{
- /* end up polling thread */
- if (!IS_ERR_OR_NULL(rx->task)) {
- kthread_stop(rx->task);
- rx->task = NULL;
- /* Put the ir ptr that ir_probe() gave to the rx poll thread */
- put_ir_device(rx->ir, ir_devices_lock_held);
- }
-}
-
-static void release_ir_rx(struct kref *ref)
-{
- struct IR_rx *rx = container_of(ref, struct IR_rx, ref);
- struct IR *ir = rx->ir;
-
- /*
- * This release function can't do all the work, as we want
- * to keep the rx_ref_lock a spinlock, and killing the poll thread
- * and releasing the ir reference can cause a sleep. That work is
- * performed by put_ir_rx()
- */
- ir->l->features &= ~LIRC_CAN_REC_LIRCCODE;
- /* Don't put_ir_device(rx->ir) here; lock can't be freed yet */
- ir->rx = NULL;
- /* Don't do the kfree(rx) here; we still need to kill the poll thread */
-}
-
-static int put_ir_rx(struct IR_rx *rx, bool ir_devices_lock_held)
-{
- int released;
- struct IR *ir = rx->ir;
-
- spin_lock(&ir->rx_ref_lock);
- released = kref_put(&rx->ref, release_ir_rx);
- spin_unlock(&ir->rx_ref_lock);
- /* Destroy the rx kthread while not holding the spinlock */
- if (released) {
- destroy_rx_kthread(rx, ir_devices_lock_held);
- kfree(rx);
- /* Make sure we're not still in a poll_table somewhere */
- wake_up_interruptible(&ir->rbuf.wait_poll);
- }
- /* Do a reference put() for the rx->ir reference, if we released rx */
- if (released)
- put_ir_device(ir, ir_devices_lock_held);
- return released;
-}
-
-/* struct IR_tx reference counting */
-static struct IR_tx *get_ir_tx(struct IR *ir)
-{
- struct IR_tx *tx;
-
- spin_lock(&ir->tx_ref_lock);
- tx = ir->tx;
- if (tx)
- kref_get(&tx->ref);
- spin_unlock(&ir->tx_ref_lock);
- return tx;
-}
-
-static void release_ir_tx(struct kref *ref)
-{
- struct IR_tx *tx = container_of(ref, struct IR_tx, ref);
- struct IR *ir = tx->ir;
-
- ir->l->features &= ~LIRC_CAN_SEND_LIRCCODE;
- /* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */
- ir->tx = NULL;
- kfree(tx);
-}
-
-static int put_ir_tx(struct IR_tx *tx, bool ir_devices_lock_held)
-{
- int released;
- struct IR *ir = tx->ir;
-
- spin_lock(&ir->tx_ref_lock);
- released = kref_put(&tx->ref, release_ir_tx);
- spin_unlock(&ir->tx_ref_lock);
- /* Do a reference put() for the tx->ir reference, if we released tx */
- if (released)
- put_ir_device(ir, ir_devices_lock_held);
- return released;
-}
-
-static int add_to_buf(struct IR *ir)
-{
- __u16 code;
- unsigned char codes[2];
- unsigned char keybuf[6];
- int got_data = 0;
- int ret;
- int failures = 0;
- unsigned char sendbuf[1] = { 0 };
- struct lirc_buffer *rbuf = ir->l->buf;
- struct IR_rx *rx;
- struct IR_tx *tx;
-
- if (lirc_buffer_full(rbuf)) {
- dev_dbg(ir->dev, "buffer overflow\n");
- return -EOVERFLOW;
- }
-
- rx = get_ir_rx(ir);
- if (!rx)
- return -ENXIO;
-
- /* Ensure our rx->c i2c_client remains valid for the duration */
- mutex_lock(&rx->client_lock);
- if (!rx->c) {
- mutex_unlock(&rx->client_lock);
- put_ir_rx(rx, false);
- return -ENXIO;
- }
-
- tx = get_ir_tx(ir);
-
- /*
- * service the device as long as it is returning
- * data and we have space
- */
- do {
- if (kthread_should_stop()) {
- ret = -ENODATA;
- break;
- }
-
- /*
- * Lock i2c bus for the duration. RX/TX chips interfere so
- * this is worth it
- */
- mutex_lock(&ir->ir_lock);
-
- if (kthread_should_stop()) {
- mutex_unlock(&ir->ir_lock);
- ret = -ENODATA;
- break;
- }
-
- /*
- * Send random "poll command" (?) Windows driver does this
- * and it is a good point to detect chip failure.
- */
- ret = i2c_master_send(rx->c, sendbuf, 1);
- if (ret != 1) {
- dev_err(ir->dev, "i2c_master_send failed with %d\n",
- ret);
- if (failures >= 3) {
- mutex_unlock(&ir->ir_lock);
- dev_err(ir->dev,
- "unable to read from the IR chip after 3 resets, giving up\n");
- break;
- }
-
- /* Looks like the chip crashed, reset it */
- dev_err(ir->dev,
- "polling the IR receiver chip failed, trying reset\n");
-
- set_current_state(TASK_UNINTERRUPTIBLE);
- if (kthread_should_stop()) {
- mutex_unlock(&ir->ir_lock);
- ret = -ENODATA;
- break;
- }
- schedule_timeout((100 * HZ + 999) / 1000);
- if (tx)
- tx->need_boot = 1;
-
- ++failures;
- mutex_unlock(&ir->ir_lock);
- ret = 0;
- continue;
- }
-
- if (kthread_should_stop()) {
- mutex_unlock(&ir->ir_lock);
- ret = -ENODATA;
- break;
- }
- ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf));
- mutex_unlock(&ir->ir_lock);
- if (ret != sizeof(keybuf)) {
- dev_err(ir->dev,
- "i2c_master_recv failed with %d -- keeping last read buffer\n",
- ret);
- } else {
- rx->b[0] = keybuf[3];
- rx->b[1] = keybuf[4];
- rx->b[2] = keybuf[5];
- dev_dbg(ir->dev,
- "key (0x%02x/0x%02x)\n",
- rx->b[0], rx->b[1]);
- }
-
- /* key pressed ? */
- if (rx->hdpvr_data_fmt) {
- if (got_data && (keybuf[0] == 0x80)) {
- ret = 0;
- break;
- } else if (got_data && (keybuf[0] == 0x00)) {
- ret = -ENODATA;
- break;
- }
- } else if ((rx->b[0] & 0x80) == 0) {
- ret = got_data ? 0 : -ENODATA;
- break;
- }
-
- /* look what we have */
- code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2);
-
- codes[0] = (code >> 8) & 0xff;
- codes[1] = code & 0xff;
-
- /* return it */
- lirc_buffer_write(rbuf, codes);
- ++got_data;
- ret = 0;
- } while (!lirc_buffer_full(rbuf));
-
- mutex_unlock(&rx->client_lock);
- if (tx)
- put_ir_tx(tx, false);
- put_ir_rx(rx, false);
- return ret;
-}
-
-/*
- * Main function of the polling thread -- from lirc_dev.
- * We don't fit the LIRC model at all anymore. This is horrible, but
- * basically we have a single RX/TX device with a nasty failure mode
- * that needs to be accounted for across the pair. lirc lets us provide
- * fops, but prevents us from using the internal polling, etc. if we do
- * so. Hence the replication. Might be neater to extend the LIRC model
- * to account for this but I'd think it's a very special case of seriously
- * messed up hardware.
- */
-static int lirc_thread(void *arg)
-{
- struct IR *ir = arg;
- struct lirc_buffer *rbuf = ir->l->buf;
-
- dev_dbg(ir->dev, "poll thread started\n");
-
- while (!kthread_should_stop()) {
- set_current_state(TASK_INTERRUPTIBLE);
-
- /* if device not opened, we can sleep half a second */
- if (atomic_read(&ir->open_count) == 0) {
- schedule_timeout(HZ / 2);
- continue;
- }
-
- /*
- * This is ~113*2 + 24 + jitter (2*repeat gap + code length).
- * We use this interval as the chip resets every time you poll
- * it (bad!). This is therefore just sufficient to catch all
- * of the button presses. It makes the remote much more
- * responsive. You can see the difference by running irw and
- * holding down a button. With 100ms, the old polling
- * interval, you'll notice breaks in the repeat sequence
- * corresponding to lost keypresses.
- */
- schedule_timeout((260 * HZ) / 1000);
- if (kthread_should_stop())
- break;
- if (!add_to_buf(ir))
- wake_up_interruptible(&rbuf->wait_poll);
- }
-
- dev_dbg(ir->dev, "poll thread ended\n");
- return 0;
-}
-
-/* safe read of a uint32 (always network byte order) */
-static int read_uint32(unsigned char **data,
- unsigned char *endp, unsigned int *val)
-{
- if (*data + 4 > endp)
- return 0;
- *val = ((*data)[0] << 24) | ((*data)[1] << 16) |
- ((*data)[2] << 8) | (*data)[3];
- *data += 4;
- return 1;
-}
-
-/* safe read of a uint8 */
-static int read_uint8(unsigned char **data,
- unsigned char *endp, unsigned char *val)
-{
- if (*data + 1 > endp)
- return 0;
- *val = *((*data)++);
- return 1;
-}
-
-/* safe skipping of N bytes */
-static int skip(unsigned char **data,
- unsigned char *endp, unsigned int distance)
-{
- if (*data + distance > endp)
- return 0;
- *data += distance;
- return 1;
-}
-
-/* decompress key data into the given buffer */
-static int get_key_data(unsigned char *buf,
- unsigned int codeset, unsigned int key)
-{
- unsigned char *data, *endp, *diffs, *key_block;
- unsigned char keys, ndiffs, id;
- unsigned int base, lim, pos, i;
-
- /* Binary search for the codeset */
- for (base = 0, lim = tx_data->num_code_sets; lim; lim >>= 1) {
- pos = base + (lim >> 1);
- data = tx_data->code_sets[pos];
-
- if (!read_uint32(&data, tx_data->endp, &i))
- goto corrupt;
-
- if (i == codeset) {
- break;
- } else if (codeset > i) {
- base = pos + 1;
- --lim;
- }
- }
- /* Not found? */
- if (!lim)
- return -EPROTO;
-
- /* Set end of data block */
- endp = pos < tx_data->num_code_sets - 1 ?
- tx_data->code_sets[pos + 1] : tx_data->endp;
-
- /* Read the block header */
- if (!read_uint8(&data, endp, &keys) ||
- !read_uint8(&data, endp, &ndiffs) ||
- ndiffs > TX_BLOCK_SIZE || keys == 0)
- goto corrupt;
-
- /* Save diffs & skip */
- diffs = data;
- if (!skip(&data, endp, ndiffs))
- goto corrupt;
-
- /* Read the id of the first key */
- if (!read_uint8(&data, endp, &id))
- goto corrupt;
-
- /* Unpack the first key's data */
- for (i = 0; i < TX_BLOCK_SIZE; ++i) {
- if (tx_data->fixed[i] == -1) {
- if (!read_uint8(&data, endp, &buf[i]))
- goto corrupt;
- } else {
- buf[i] = (unsigned char)tx_data->fixed[i];
- }
- }
-
- /* Early out key found/not found */
- if (key == id)
- return 0;
- if (keys == 1)
- return -EPROTO;
-
- /* Sanity check */
- key_block = data;
- if (!skip(&data, endp, (keys - 1) * (ndiffs + 1)))
- goto corrupt;
-
- /* Binary search for the key */
- for (base = 0, lim = keys - 1; lim; lim >>= 1) {
- /* Seek to block */
- unsigned char *key_data;
-
- pos = base + (lim >> 1);
- key_data = key_block + (ndiffs + 1) * pos;
-
- if (*key_data == key) {
- /* skip key id */
- ++key_data;
-
- /* found, so unpack the diffs */
- for (i = 0; i < ndiffs; ++i) {
- unsigned char val;
-
- if (!read_uint8(&key_data, endp, &val) ||
- diffs[i] >= TX_BLOCK_SIZE)
- goto corrupt;
- buf[diffs[i]] = val;
- }
-
- return 0;
- } else if (key > *key_data) {
- base = pos + 1;
- --lim;
- }
- }
- /* Key not found */
- return -EPROTO;
-
-corrupt:
- pr_err("firmware is corrupt\n");
- return -EFAULT;
-}
-
-/* send a block of data to the IR TX device */
-static int send_data_block(struct IR_tx *tx, unsigned char *data_block)
-{
- int i, j, ret;
- unsigned char buf[5];
-
- for (i = 0; i < TX_BLOCK_SIZE;) {
- int tosend = TX_BLOCK_SIZE - i;
-
- if (tosend > 4)
- tosend = 4;
- buf[0] = (unsigned char)(i + 1);
- for (j = 0; j < tosend; ++j)
- buf[1 + j] = data_block[i + j];
- dev_dbg(tx->ir->dev, "%*ph", 5, buf);
- ret = i2c_master_send(tx->c, buf, tosend + 1);
- if (ret != tosend + 1) {
- dev_err(tx->ir->dev,
- "i2c_master_send failed with %d\n", ret);
- return ret < 0 ? ret : -EFAULT;
- }
- i += tosend;
- }
- return 0;
-}
-
-/* send boot data to the IR TX device */
-static int send_boot_data(struct IR_tx *tx)
-{
- int ret, i;
- unsigned char buf[4];
-
- /* send the boot block */
- ret = send_data_block(tx, tx_data->boot_data);
- if (ret != 0)
- return ret;
-
- /* Hit the go button to activate the new boot data */
- buf[0] = 0x00;
- buf[1] = 0x20;
- ret = i2c_master_send(tx->c, buf, 2);
- if (ret != 2) {
- dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret);
- return ret < 0 ? ret : -EFAULT;
- }
-
- /*
- * Wait for zilog to settle after hitting go post boot block upload.
- * Without this delay, the HD-PVR and HVR-1950 both return an -EIO
- * upon attempting to get firmware revision, and tx probe thus fails.
- */
- for (i = 0; i < 10; i++) {
- ret = i2c_master_send(tx->c, buf, 1);
- if (ret == 1)
- break;
- udelay(100);
- }
-
- if (ret != 1) {
- dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret);
- return ret < 0 ? ret : -EFAULT;
- }
-
- /* Here comes the firmware version... (hopefully) */
- ret = i2c_master_recv(tx->c, buf, 4);
- if (ret != 4) {
- dev_err(tx->ir->dev, "i2c_master_recv failed with %d\n", ret);
- return 0;
- }
- if ((buf[0] != 0x80) && (buf[0] != 0xa0)) {
- dev_err(tx->ir->dev, "unexpected IR TX init response: %02x\n",
- buf[0]);
- return 0;
- }
- dev_notice(tx->ir->dev,
- "Zilog/Hauppauge IR blaster firmware version %d.%d.%d loaded\n",
- buf[1], buf[2], buf[3]);
-
- return 0;
-}
-
-/* unload "firmware", lock held */
-static void fw_unload_locked(void)
-{
- if (tx_data) {
- vfree(tx_data->code_sets);
-
- vfree(tx_data->datap);
-
- vfree(tx_data);
- tx_data = NULL;
- pr_debug("successfully unloaded IR blaster firmware\n");
- }
-}
-
-/* unload "firmware" for the IR TX device */
-static void fw_unload(void)
-{
- mutex_lock(&tx_data_lock);
- fw_unload_locked();
- mutex_unlock(&tx_data_lock);
-}
-
-/* load "firmware" for the IR TX device */
-static int fw_load(struct IR_tx *tx)
-{
- int ret;
- unsigned int i;
- unsigned char *data, version, num_global_fixed;
- const struct firmware *fw_entry;
-
- /* Already loaded? */
- mutex_lock(&tx_data_lock);
- if (tx_data) {
- ret = 0;
- goto out;
- }
-
- /* Request codeset data file */
- ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->dev);
- if (ret != 0) {
- dev_err(tx->ir->dev,
- "firmware haup-ir-blaster.bin not available (%d)\n",
- ret);
- ret = ret < 0 ? ret : -EFAULT;
- goto out;
- }
- dev_dbg(tx->ir->dev, "firmware of size %zu loaded\n", fw_entry->size);
-
- /* Parse the file */
- tx_data = vmalloc(sizeof(*tx_data));
- if (!tx_data) {
- release_firmware(fw_entry);
- ret = -ENOMEM;
- goto out;
- }
- tx_data->code_sets = NULL;
-
- /* Copy the data so hotplug doesn't get confused and timeout */
- tx_data->datap = vmalloc(fw_entry->size);
- if (!tx_data->datap) {
- release_firmware(fw_entry);
- vfree(tx_data);
- ret = -ENOMEM;
- goto out;
- }
- memcpy(tx_data->datap, fw_entry->data, fw_entry->size);
- tx_data->endp = tx_data->datap + fw_entry->size;
- release_firmware(fw_entry); fw_entry = NULL;
-
- /* Check version */
- data = tx_data->datap;
- if (!read_uint8(&data, tx_data->endp, &version))
- goto corrupt;
- if (version != 1) {
- dev_err(tx->ir->dev,
- "unsupported code set file version (%u, expected 1) -- please upgrade to a newer driver\n",
- version);
- fw_unload_locked();
- ret = -EFAULT;
- goto out;
- }
-
- /* Save boot block for later */
- tx_data->boot_data = data;
- if (!skip(&data, tx_data->endp, TX_BLOCK_SIZE))
- goto corrupt;
-
- if (!read_uint32(&data, tx_data->endp,
- &tx_data->num_code_sets))
- goto corrupt;
-
- dev_dbg(tx->ir->dev, "%u IR blaster codesets loaded\n",
- tx_data->num_code_sets);
-
- tx_data->code_sets = vmalloc(
- tx_data->num_code_sets * sizeof(char *));
- if (!tx_data->code_sets) {
- fw_unload_locked();
- ret = -ENOMEM;
- goto out;
- }
-
- for (i = 0; i < TX_BLOCK_SIZE; ++i)
- tx_data->fixed[i] = -1;
-
- /* Read global fixed data template */
- if (!read_uint8(&data, tx_data->endp, &num_global_fixed) ||
- num_global_fixed > TX_BLOCK_SIZE)
- goto corrupt;
- for (i = 0; i < num_global_fixed; ++i) {
- unsigned char pos, val;
-
- if (!read_uint8(&data, tx_data->endp, &pos) ||
- !read_uint8(&data, tx_data->endp, &val) ||
- pos >= TX_BLOCK_SIZE)
- goto corrupt;
- tx_data->fixed[pos] = (int)val;
- }
-
- /* Filch out the position of each code set */
- for (i = 0; i < tx_data->num_code_sets; ++i) {
- unsigned int id;
- unsigned char keys;
- unsigned char ndiffs;
-
- /* Save the codeset position */
- tx_data->code_sets[i] = data;
-
- /* Read header */
- if (!read_uint32(&data, tx_data->endp, &id) ||
- !read_uint8(&data, tx_data->endp, &keys) ||
- !read_uint8(&data, tx_data->endp, &ndiffs) ||
- ndiffs > TX_BLOCK_SIZE || keys == 0)
- goto corrupt;
-
- /* skip diff positions */
- if (!skip(&data, tx_data->endp, ndiffs))
- goto corrupt;
-
- /*
- * After the diffs we have the first key id + data -
- * global fixed
- */
- if (!skip(&data, tx_data->endp,
- 1 + TX_BLOCK_SIZE - num_global_fixed))
- goto corrupt;
-
- /* Then we have keys-1 blocks of key id+diffs */
- if (!skip(&data, tx_data->endp,
- (ndiffs + 1) * (keys - 1)))
- goto corrupt;
- }
- ret = 0;
- goto out;
-
-corrupt:
- dev_err(tx->ir->dev, "firmware is corrupt\n");
- fw_unload_locked();
- ret = -EFAULT;
-
-out:
- mutex_unlock(&tx_data_lock);
- return ret;
-}
-
-/* copied from lirc_dev */
-static ssize_t read(struct file *filep, char __user *outbuf, size_t n,
- loff_t *ppos)
-{
- struct IR *ir = lirc_get_pdata(filep);
- struct IR_rx *rx;
- struct lirc_buffer *rbuf = ir->l->buf;
- int ret = 0, written = 0, retries = 0;
- unsigned int m;
- DECLARE_WAITQUEUE(wait, current);
-
- dev_dbg(ir->dev, "read called\n");
- if (n % rbuf->chunk_size) {
- dev_dbg(ir->dev, "read result = -EINVAL\n");
- return -EINVAL;
- }
-
- rx = get_ir_rx(ir);
- if (!rx)
- return -ENXIO;
-
- /*
- * we add ourselves to the task queue before buffer check
- * to avoid losing scan code (in case when queue is awaken somewhere
- * between while condition checking and scheduling)
- */
- add_wait_queue(&rbuf->wait_poll, &wait);
- set_current_state(TASK_INTERRUPTIBLE);
-
- /*
- * while we didn't provide 'length' bytes, device is opened in blocking
- * mode and 'copy_to_user' is happy, wait for data.
- */
- while (written < n && ret == 0) {
- if (lirc_buffer_empty(rbuf)) {
- /*
- * According to the read(2) man page, 'written' can be
- * returned as less than 'n', instead of blocking
- * again, returning -EWOULDBLOCK, or returning
- * -ERESTARTSYS
- */
- if (written)
- break;
- if (filep->f_flags & O_NONBLOCK) {
- ret = -EWOULDBLOCK;
- break;
- }
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
- schedule();
- set_current_state(TASK_INTERRUPTIBLE);
- } else {
- unsigned char buf[MAX_XFER_SIZE];
-
- if (rbuf->chunk_size > sizeof(buf)) {
- dev_err(ir->dev,
- "chunk_size is too big (%d)!\n",
- rbuf->chunk_size);
- ret = -EINVAL;
- break;
- }
- m = lirc_buffer_read(rbuf, buf);
- if (m == rbuf->chunk_size) {
- ret = copy_to_user(outbuf + written, buf,
- rbuf->chunk_size);
- written += rbuf->chunk_size;
- } else {
- retries++;
- }
- if (retries >= 5) {
- dev_err(ir->dev, "Buffer read failed!\n");
- ret = -EIO;
- }
- }
- }
-
- remove_wait_queue(&rbuf->wait_poll, &wait);
- put_ir_rx(rx, false);
- set_current_state(TASK_RUNNING);
-
- dev_dbg(ir->dev, "read result = %d (%s)\n", ret,
- ret ? "Error" : "OK");
-
- return ret ? ret : written;
-}
-
-/* send a keypress to the IR TX device */
-static int send_code(struct IR_tx *tx, unsigned int code, unsigned int key)
-{
- unsigned char data_block[TX_BLOCK_SIZE];
- unsigned char buf[2];
- int i, ret;
-
- /* Get data for the codeset/key */
- ret = get_key_data(data_block, code, key);
-
- if (ret == -EPROTO) {
- dev_err(tx->ir->dev,
- "failed to get data for code %u, key %u -- check lircd.conf entries\n",
- code, key);
- return ret;
- } else if (ret != 0) {
- return ret;
- }
-
- /* Send the data block */
- ret = send_data_block(tx, data_block);
- if (ret != 0)
- return ret;
-
- /* Send data block length? */
- buf[0] = 0x00;
- buf[1] = 0x40;
- ret = i2c_master_send(tx->c, buf, 2);
- if (ret != 2) {
- dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret);
- return ret < 0 ? ret : -EFAULT;
- }
-
- /* Give the z8 a moment to process data block */
- for (i = 0; i < 10; i++) {
- ret = i2c_master_send(tx->c, buf, 1);
- if (ret == 1)
- break;
- udelay(100);
- }
-
- if (ret != 1) {
- dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret);
- return ret < 0 ? ret : -EFAULT;
- }
-
- /* Send finished download? */
- ret = i2c_master_recv(tx->c, buf, 1);
- if (ret != 1) {
- dev_err(tx->ir->dev, "i2c_master_recv failed with %d\n", ret);
- return ret < 0 ? ret : -EFAULT;
- }
- if (buf[0] != 0xA0) {
- dev_err(tx->ir->dev, "unexpected IR TX response #1: %02x\n",
- buf[0]);
- return -EFAULT;
- }
-
- /* Send prepare command? */
- buf[0] = 0x00;
- buf[1] = 0x80;
- ret = i2c_master_send(tx->c, buf, 2);
- if (ret != 2) {
- dev_err(tx->ir->dev, "i2c_master_send failed with %d\n", ret);
- return ret < 0 ? ret : -EFAULT;
- }
-
- /*
- * The sleep bits aren't necessary on the HD PVR, and in fact, the
- * last i2c_master_recv always fails with a -5, so for now, we're
- * going to skip this whole mess and say we're done on the HD PVR
- */
- if (!tx->post_tx_ready_poll) {
- dev_dbg(tx->ir->dev, "sent code %u, key %u\n", code, key);
- return 0;
- }
-
- /*
- * This bit NAKs until the device is ready, so we retry it
- * sleeping a bit each time. This seems to be what the windows
- * driver does, approximately.
- * Try for up to 1s.
- */
- for (i = 0; i < 20; ++i) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((50 * HZ + 999) / 1000);
- ret = i2c_master_send(tx->c, buf, 1);
- if (ret == 1)
- break;
- dev_dbg(tx->ir->dev,
- "NAK expected: i2c_master_send failed with %d (try %d)\n",
- ret, i + 1);
- }
- if (ret != 1) {
- dev_err(tx->ir->dev,
- "IR TX chip never got ready: last i2c_master_send failed with %d\n",
- ret);
- return ret < 0 ? ret : -EFAULT;
- }
-
- /* Seems to be an 'ok' response */
- i = i2c_master_recv(tx->c, buf, 1);
- if (i != 1) {
- dev_err(tx->ir->dev, "i2c_master_recv failed with %d\n", ret);
- return -EFAULT;
- }
- if (buf[0] != 0x80) {
- dev_err(tx->ir->dev, "unexpected IR TX response #2: %02x\n",
- buf[0]);
- return -EFAULT;
- }
-
- /* Oh good, it worked */
- dev_dbg(tx->ir->dev, "sent code %u, key %u\n", code, key);
- return 0;
-}
-
-/*
- * Write a code to the device. We take in a 32-bit number (an int) and then
- * decode this to a codeset/key index. The key data is then decompressed and
- * sent to the device. We have a spin lock as per i2c documentation to prevent
- * multiple concurrent sends which would probably cause the device to explode.
- */
-static ssize_t write(struct file *filep, const char __user *buf, size_t n,
- loff_t *ppos)
-{
- struct IR *ir = lirc_get_pdata(filep);
- struct IR_tx *tx;
- size_t i;
- int failures = 0;
-
- /* Validate user parameters */
- if (n % sizeof(int))
- return -EINVAL;
-
- /* Get a struct IR_tx reference */
- tx = get_ir_tx(ir);
- if (!tx)
- return -ENXIO;
-
- /* Ensure our tx->c i2c_client remains valid for the duration */
- mutex_lock(&tx->client_lock);
- if (!tx->c) {
- mutex_unlock(&tx->client_lock);
- put_ir_tx(tx, false);
- return -ENXIO;
- }
-
- /* Lock i2c bus for the duration */
- mutex_lock(&ir->ir_lock);
-
- /* Send each keypress */
- for (i = 0; i < n;) {
- int ret = 0;
- int command;
-
- if (copy_from_user(&command, buf + i, sizeof(command))) {
- mutex_unlock(&ir->ir_lock);
- mutex_unlock(&tx->client_lock);
- put_ir_tx(tx, false);
- return -EFAULT;
- }
-
- /* Send boot data first if required */
- if (tx->need_boot == 1) {
- /* Make sure we have the 'firmware' loaded, first */
- ret = fw_load(tx);
- if (ret != 0) {
- mutex_unlock(&ir->ir_lock);
- mutex_unlock(&tx->client_lock);
- put_ir_tx(tx, false);
- if (ret != -ENOMEM)
- ret = -EIO;
- return ret;
- }
- /* Prep the chip for transmitting codes */
- ret = send_boot_data(tx);
- if (ret == 0)
- tx->need_boot = 0;
- }
-
- /* Send the code */
- if (ret == 0) {
- ret = send_code(tx, (unsigned int)command >> 16,
- (unsigned int)command & 0xFFFF);
- if (ret == -EPROTO) {
- mutex_unlock(&ir->ir_lock);
- mutex_unlock(&tx->client_lock);
- put_ir_tx(tx, false);
- return ret;
- }
- }
-
- /*
- * Hmm, a failure. If we've had a few then give up, otherwise
- * try a reset
- */
- if (ret != 0) {
- /* Looks like the chip crashed, reset it */
- dev_err(tx->ir->dev,
- "sending to the IR transmitter chip failed, trying reset\n");
-
- if (failures >= 3) {
- dev_err(tx->ir->dev,
- "unable to send to the IR chip after 3 resets, giving up\n");
- mutex_unlock(&ir->ir_lock);
- mutex_unlock(&tx->client_lock);
- put_ir_tx(tx, false);
- return ret;
- }
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout((100 * HZ + 999) / 1000);
- tx->need_boot = 1;
- ++failures;
- } else {
- i += sizeof(int);
- }
- }
-
- /* Release i2c bus */
- mutex_unlock(&ir->ir_lock);
-
- mutex_unlock(&tx->client_lock);
-
- /* Give back our struct IR_tx reference */
- put_ir_tx(tx, false);
-
- /* All looks good */
- return n;
-}
-
-/* copied from lirc_dev */
-static __poll_t poll(struct file *filep, poll_table *wait)
-{
- struct IR *ir = lirc_get_pdata(filep);
- struct IR_rx *rx;
- struct lirc_buffer *rbuf = ir->l->buf;
- __poll_t ret;
-
- dev_dbg(ir->dev, "%s called\n", __func__);
-
- rx = get_ir_rx(ir);
- if (!rx) {
- /*
- * Revisit this, if our poll function ever reports writeable
- * status for Tx
- */
- dev_dbg(ir->dev, "%s result = POLLERR\n", __func__);
- return POLLERR;
- }
-
- /*
- * Add our lirc_buffer's wait_queue to the poll_table. A wake up on
- * that buffer's wait queue indicates we may have a new poll status.
- */
- poll_wait(filep, &rbuf->wait_poll, wait);
-
- /* Indicate what ops could happen immediately without blocking */
- ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN | POLLRDNORM);
-
- dev_dbg(ir->dev, "%s result = %s\n", __func__,
- ret ? "POLLIN|POLLRDNORM" : "none");
- return ret;
-}
-
-static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
-{
- struct IR *ir = lirc_get_pdata(filep);
- unsigned long __user *uptr = (unsigned long __user *)arg;
- int result;
- unsigned long mode, features;
-
- features = ir->l->features;
-
- switch (cmd) {
- case LIRC_GET_LENGTH:
- result = put_user(13UL, uptr);
- break;
- case LIRC_GET_FEATURES:
- result = put_user(features, uptr);
- break;
- case LIRC_GET_REC_MODE:
- if (!(features & LIRC_CAN_REC_MASK))
- return -ENOTTY;
-
- result = put_user(LIRC_REC2MODE
- (features & LIRC_CAN_REC_MASK),
- uptr);
- break;
- case LIRC_SET_REC_MODE:
- if (!(features & LIRC_CAN_REC_MASK))
- return -ENOTTY;
-
- result = get_user(mode, uptr);
- if (!result && !(LIRC_MODE2REC(mode) & features))
- result = -ENOTTY;
- break;
- case LIRC_GET_SEND_MODE:
- if (!(features & LIRC_CAN_SEND_MASK))
- return -ENOTTY;
-
- result = put_user(LIRC_MODE_LIRCCODE, uptr);
- break;
- case LIRC_SET_SEND_MODE:
- if (!(features & LIRC_CAN_SEND_MASK))
- return -ENOTTY;
-
- result = get_user(mode, uptr);
- if (!result && mode != LIRC_MODE_LIRCCODE)
- return -EINVAL;
- break;
- default:
- return -EINVAL;
- }
- return result;
-}
-
-/*
- * Open the IR device.
- */
-static int open(struct inode *node, struct file *filep)
-{
- struct IR *ir;
-
- lirc_init_pdata(node, filep);
- ir = lirc_get_pdata(filep);
-
- atomic_inc(&ir->open_count);
-
- nonseekable_open(node, filep);
- return 0;
-}
-
-/* Close the IR device */
-static int close(struct inode *node, struct file *filep)
-{
- struct IR *ir = lirc_get_pdata(filep);
-
- atomic_dec(&ir->open_count);
-
- put_ir_device(ir, false);
- return 0;
-}
-
-static int ir_remove(struct i2c_client *client);
-static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id);
-
-#define ID_FLAG_TX 0x01
-#define ID_FLAG_HDPVR 0x02
-
-static const struct i2c_device_id ir_transceiver_id[] = {
- { "ir_tx_z8f0811_haup", ID_FLAG_TX },
- { "ir_rx_z8f0811_haup", 0 },
- { "ir_tx_z8f0811_hdpvr", ID_FLAG_HDPVR | ID_FLAG_TX },
- { "ir_rx_z8f0811_hdpvr", ID_FLAG_HDPVR },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ir_transceiver_id);
-
-static struct i2c_driver driver = {
- .driver = {
- .name = "Zilog/Hauppauge i2c IR",
- },
- .probe = ir_probe,
- .remove = ir_remove,
- .id_table = ir_transceiver_id,
-};
-
-static const struct file_operations lirc_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .read = read,
- .write = write,
- .poll = poll,
- .unlocked_ioctl = ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = ioctl,
-#endif
- .open = open,
- .release = close
-};
-
-static int ir_remove(struct i2c_client *client)
-{
- if (strncmp("ir_tx_z8", client->name, 8) == 0) {
- struct IR_tx *tx = i2c_get_clientdata(client);
-
- if (tx) {
- mutex_lock(&tx->client_lock);
- tx->c = NULL;
- mutex_unlock(&tx->client_lock);
- put_ir_tx(tx, false);
- }
- } else if (strncmp("ir_rx_z8", client->name, 8) == 0) {
- struct IR_rx *rx = i2c_get_clientdata(client);
-
- if (rx) {
- mutex_lock(&rx->client_lock);
- rx->c = NULL;
- mutex_unlock(&rx->client_lock);
- put_ir_rx(rx, false);
- }
- }
- return 0;
-}
-
-/* ir_devices_lock must be held */
-static struct IR *get_ir_device_by_adapter(struct i2c_adapter *adapter)
-{
- struct IR *ir;
-
- if (list_empty(&ir_devices_list))
- return NULL;
-
- list_for_each_entry(ir, &ir_devices_list, list)
- if (ir->adapter == adapter) {
- get_ir_device(ir, true);
- return ir;
- }
-
- return NULL;
-}
-
-static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
- struct IR *ir;
- struct IR_tx *tx;
- struct IR_rx *rx;
- struct i2c_adapter *adap = client->adapter;
- int ret;
- bool tx_probe = false;
-
- dev_dbg(&client->dev, "%s: %s on i2c-%d (%s), client addr=0x%02x\n",
- __func__, id->name, adap->nr, adap->name, client->addr);
-
- /*
- * The IR receiver is at i2c address 0x71.
- * The IR transmitter is at i2c address 0x70.
- */
-
- if (id->driver_data & ID_FLAG_TX)
- tx_probe = true;
- else if (tx_only) /* module option */
- return -ENXIO;
-
- pr_info("probing IR %s on %s (i2c-%d)\n",
- tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
-
- mutex_lock(&ir_devices_lock);
-
- /* Use a single struct IR instance for both the Rx and Tx functions */
- ir = get_ir_device_by_adapter(adap);
- if (!ir) {
- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- if (!ir) {
- ret = -ENOMEM;
- goto out_no_ir;
- }
- kref_init(&ir->ref);
-
- /* store for use in ir_probe() again, and open() later on */
- INIT_LIST_HEAD(&ir->list);
- list_add_tail(&ir->list, &ir_devices_list);
-
- ir->adapter = adap;
- ir->dev = &adap->dev;
- mutex_init(&ir->ir_lock);
- atomic_set(&ir->open_count, 0);
- spin_lock_init(&ir->tx_ref_lock);
- spin_lock_init(&ir->rx_ref_lock);
-
- /* set lirc_dev stuff */
- ir->l = lirc_allocate_device();
- if (!ir->l) {
- ret = -ENOMEM;
- goto out_put_ir;
- }
-
- snprintf(ir->l->name, sizeof(ir->l->name), "lirc_zilog");
- ir->l->code_length = 13;
- ir->l->fops = &lirc_fops;
- ir->l->owner = THIS_MODULE;
- ir->l->dev.parent = &adap->dev;
-
- /*
- * FIXME this is a pointer reference to us, but no refcount.
- *
- * This OK for now, since lirc_dev currently won't touch this
- * buffer as we provide our own lirc_fops.
- *
- * Currently our own lirc_fops rely on this ir->l->buf pointer
- */
- ir->l->buf = &ir->rbuf;
- /* This will be returned by lirc_get_pdata() */
- ir->l->data = ir;
- ret = lirc_buffer_init(ir->l->buf, 2, BUFLEN / 2);
- if (ret) {
- lirc_free_device(ir->l);
- ir->l = NULL;
- goto out_put_ir;
- }
- }
-
- if (tx_probe) {
- /* Get the IR_rx instance for later, if already allocated */
- rx = get_ir_rx(ir);
-
- /* Set up a struct IR_tx instance */
- tx = kzalloc(sizeof(*tx), GFP_KERNEL);
- if (!tx) {
- ret = -ENOMEM;
- goto out_put_xx;
- }
- kref_init(&tx->ref);
- ir->tx = tx;
-
- ir->l->features |= LIRC_CAN_SEND_LIRCCODE;
- mutex_init(&tx->client_lock);
- tx->c = client;
- tx->need_boot = 1;
- tx->post_tx_ready_poll =
- (id->driver_data & ID_FLAG_HDPVR) ? false : true;
-
- /* An ir ref goes to the struct IR_tx instance */
- tx->ir = get_ir_device(ir, true);
-
- /* A tx ref goes to the i2c_client */
- i2c_set_clientdata(client, get_ir_tx(ir));
-
- /*
- * Load the 'firmware'. We do this before registering with
- * lirc_dev, so the first firmware load attempt does not happen
- * after a open() or write() call on the device.
- *
- * Failure here is not deemed catastrophic, so the receiver will
- * still be usable. Firmware load will be retried in write(),
- * if it is needed.
- */
- fw_load(tx);
-
- /* Proceed only if the Rx client is also ready or not needed */
- if (!rx && !tx_only) {
- dev_info(tx->ir->dev,
- "probe of IR Tx on %s (i2c-%d) done. Waiting on IR Rx.\n",
- adap->name, adap->nr);
- goto out_ok;
- }
- } else {
- /* Get the IR_tx instance for later, if already allocated */
- tx = get_ir_tx(ir);
-
- /* Set up a struct IR_rx instance */
- rx = kzalloc(sizeof(*rx), GFP_KERNEL);
- if (!rx) {
- ret = -ENOMEM;
- goto out_put_xx;
- }
- kref_init(&rx->ref);
- ir->rx = rx;
-
- ir->l->features |= LIRC_CAN_REC_LIRCCODE;
- mutex_init(&rx->client_lock);
- rx->c = client;
- rx->hdpvr_data_fmt =
- (id->driver_data & ID_FLAG_HDPVR) ? true : false;
-
- /* An ir ref goes to the struct IR_rx instance */
- rx->ir = get_ir_device(ir, true);
-
- /* An rx ref goes to the i2c_client */
- i2c_set_clientdata(client, get_ir_rx(ir));
-
- /*
- * Start the polling thread.
- * It will only perform an empty loop around schedule_timeout()
- * until we register with lirc_dev and the first user open()
- */
- /* An ir ref goes to the new rx polling kthread */
- rx->task = kthread_run(lirc_thread, get_ir_device(ir, true),
- "zilog-rx-i2c-%d", adap->nr);
- if (IS_ERR(rx->task)) {
- ret = PTR_ERR(rx->task);
- dev_err(tx->ir->dev,
- "%s: could not start IR Rx polling thread\n",
- __func__);
- /* Failed kthread, so put back the ir ref */
- put_ir_device(ir, true);
- /* Failure exit, so put back rx ref from i2c_client */
- i2c_set_clientdata(client, NULL);
- put_ir_rx(rx, true);
- ir->l->features &= ~LIRC_CAN_REC_LIRCCODE;
- goto out_put_tx;
- }
-
- /* Proceed only if the Tx client is also ready */
- if (!tx) {
- pr_info("probe of IR Rx on %s (i2c-%d) done. Waiting on IR Tx.\n",
- adap->name, adap->nr);
- goto out_ok;
- }
- }
-
- /* register with lirc */
- ret = lirc_register_device(ir->l);
- if (ret < 0) {
- dev_err(tx->ir->dev,
- "%s: lirc_register_device() failed: %i\n",
- __func__, ret);
- lirc_free_device(ir->l);
- ir->l = NULL;
- goto out_put_xx;
- }
-
- dev_info(ir->dev,
- "IR unit on %s (i2c-%d) registered as lirc%d and ready\n",
- adap->name, adap->nr, ir->l->minor);
-
-out_ok:
- if (rx)
- put_ir_rx(rx, true);
- if (tx)
- put_ir_tx(tx, true);
- put_ir_device(ir, true);
- dev_info(ir->dev,
- "probe of IR %s on %s (i2c-%d) done\n",
- tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
- mutex_unlock(&ir_devices_lock);
- return 0;
-
-out_put_xx:
- if (rx)
- put_ir_rx(rx, true);
-out_put_tx:
- if (tx)
- put_ir_tx(tx, true);
-out_put_ir:
- put_ir_device(ir, true);
-out_no_ir:
- dev_err(&client->dev,
- "%s: probing IR %s on %s (i2c-%d) failed with %d\n",
- __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr, ret);
- mutex_unlock(&ir_devices_lock);
- return ret;
-}
-
-static int __init zilog_init(void)
-{
- int ret;
-
- pr_notice("Zilog/Hauppauge IR driver initializing\n");
-
- mutex_init(&tx_data_lock);
-
- request_module("firmware_class");
-
- ret = i2c_add_driver(&driver);
- if (ret)
- pr_err("initialization failed\n");
- else
- pr_notice("initialization complete\n");
-
- return ret;
-}
-
-static void __exit zilog_exit(void)
-{
- i2c_del_driver(&driver);
- /* if loaded */
- fw_unload();
- pr_notice("Zilog/Hauppauge IR driver unloaded\n");
-}
-
-module_init(zilog_init);
-module_exit(zilog_exit);
-
-MODULE_DESCRIPTION("Zilog/Hauppauge infrared transmitter driver (i2c stack)");
-MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller, Stefan Jahn, Jerome Brock, Mark Weaver, Andy Walls");
-MODULE_LICENSE("GPL");
-/* for compat with old name, which isn't all that accurate anymore */
-MODULE_ALIAS("lirc_pvr150");
-
-module_param(debug, bool, 0644);
-MODULE_PARM_DESC(debug, "Enable debugging messages");
-
-module_param(tx_only, bool, 0644);
-MODULE_PARM_DESC(tx_only, "Only handle the IR transmit function");
diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c
index c26c99fd4a24..b1036baebb03 100644
--- a/drivers/staging/media/omap4iss/iss.c
+++ b/drivers/staging/media/omap4iss/iss.c
@@ -893,7 +893,7 @@ void omap4iss_put(struct iss_device *iss)
return;
mutex_lock(&iss->iss_mutex);
- BUG_ON(iss->ref_count == 0);
+ WARN_ON(iss->ref_count == 0);
if (--iss->ref_count == 0) {
iss_disable_interrupts(iss);
/* Reset the ISS if an entity has failed to stop. This is the
diff --git a/drivers/staging/media/tegra-vde/Kconfig b/drivers/staging/media/tegra-vde/Kconfig
new file mode 100644
index 000000000000..5c4914674468
--- /dev/null
+++ b/drivers/staging/media/tegra-vde/Kconfig
@@ -0,0 +1,8 @@
+config TEGRA_VDE
+ tristate "NVIDIA Tegra Video Decoder Engine driver"
+ depends on ARCH_TEGRA || COMPILE_TEST
+ select DMA_SHARED_BUFFER
+ select SRAM
+ help
+ Say Y here to enable support for the NVIDIA Tegra video decoder
+ driver.
diff --git a/drivers/staging/media/tegra-vde/Makefile b/drivers/staging/media/tegra-vde/Makefile
new file mode 100644
index 000000000000..444c1d62daa1
--- /dev/null
+++ b/drivers/staging/media/tegra-vde/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TEGRA_VDE) += tegra-vde.o
diff --git a/drivers/staging/media/tegra-vde/TODO b/drivers/staging/media/tegra-vde/TODO
new file mode 100644
index 000000000000..31aaa3e66d80
--- /dev/null
+++ b/drivers/staging/media/tegra-vde/TODO
@@ -0,0 +1,4 @@
+TODO:
+ - Implement V4L2 API once it gains support for stateless decoders.
+
+Contact: Dmitry Osipenko <digetx@gmail.com>
diff --git a/drivers/staging/media/tegra-vde/tegra-vde.c b/drivers/staging/media/tegra-vde/tegra-vde.c
new file mode 100644
index 000000000000..c47659e96089
--- /dev/null
+++ b/drivers/staging/media/tegra-vde/tegra-vde.c
@@ -0,0 +1,1213 @@
+/*
+ * NVIDIA Tegra Video decoder driver
+ *
+ * Copyright (C) 2016-2017 Dmitry Osipenko <digetx@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-buf.h>
+#include <linux/genalloc.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include <soc/tegra/pmc.h>
+
+#include "uapi.h"
+
+#define ICMDQUE_WR 0x00
+#define CMDQUE_CONTROL 0x08
+#define INTR_STATUS 0x18
+#define BSE_INT_ENB 0x40
+#define BSE_CONFIG 0x44
+
+#define BSE_ICMDQUE_EMPTY BIT(3)
+#define BSE_DMA_BUSY BIT(23)
+
+#define VDE_WR(__data, __addr) \
+do { \
+ dev_dbg(vde->miscdev.parent, \
+ "%s: %d: 0x%08X => " #__addr ")\n", \
+ __func__, __LINE__, (u32)(__data)); \
+ writel_relaxed(__data, __addr); \
+} while (0)
+
+struct video_frame {
+ struct dma_buf_attachment *y_dmabuf_attachment;
+ struct dma_buf_attachment *cb_dmabuf_attachment;
+ struct dma_buf_attachment *cr_dmabuf_attachment;
+ struct dma_buf_attachment *aux_dmabuf_attachment;
+ struct sg_table *y_sgt;
+ struct sg_table *cb_sgt;
+ struct sg_table *cr_sgt;
+ struct sg_table *aux_sgt;
+ dma_addr_t y_addr;
+ dma_addr_t cb_addr;
+ dma_addr_t cr_addr;
+ dma_addr_t aux_addr;
+ u32 frame_num;
+ u32 flags;
+};
+
+struct tegra_vde {
+ void __iomem *sxe;
+ void __iomem *bsev;
+ void __iomem *mbe;
+ void __iomem *ppe;
+ void __iomem *mce;
+ void __iomem *tfe;
+ void __iomem *ppb;
+ void __iomem *vdma;
+ void __iomem *frameid;
+ struct mutex lock;
+ struct miscdevice miscdev;
+ struct reset_control *rst;
+ struct gen_pool *iram_pool;
+ struct completion decode_completion;
+ struct clk *clk;
+ dma_addr_t iram_lists_addr;
+ u32 *iram;
+};
+
+static void tegra_vde_set_bits(struct tegra_vde *vde,
+ u32 mask, void __iomem *regs)
+{
+ u32 value = readl_relaxed(regs);
+
+ VDE_WR(value | mask, regs);
+}
+
+static int tegra_vde_wait_mbe(struct tegra_vde *vde)
+{
+ u32 tmp;
+
+ return readl_relaxed_poll_timeout(vde->mbe + 0x8C, tmp,
+ (tmp >= 0x10), 1, 100);
+}
+
+static int tegra_vde_setup_mbe_frame_idx(struct tegra_vde *vde,
+ unsigned int refs_nb,
+ bool setup_refs)
+{
+ u32 frame_idx_enb_mask = 0;
+ u32 value;
+ unsigned int frame_idx;
+ unsigned int idx;
+ int err;
+
+ VDE_WR(0xD0000000 | (0 << 23), vde->mbe + 0x80);
+ VDE_WR(0xD0200000 | (0 << 23), vde->mbe + 0x80);
+
+ err = tegra_vde_wait_mbe(vde);
+ if (err)
+ return err;
+
+ if (!setup_refs)
+ return 0;
+
+ for (idx = 0, frame_idx = 1; idx < refs_nb; idx++, frame_idx++) {
+ VDE_WR(0xD0000000 | (frame_idx << 23), vde->mbe + 0x80);
+ VDE_WR(0xD0200000 | (frame_idx << 23), vde->mbe + 0x80);
+
+ frame_idx_enb_mask |= frame_idx << (6 * (idx % 4));
+
+ if (idx % 4 == 3 || idx == refs_nb - 1) {
+ value = 0xC0000000;
+ value |= (idx >> 2) << 24;
+ value |= frame_idx_enb_mask;
+
+ VDE_WR(value, vde->mbe + 0x80);
+
+ err = tegra_vde_wait_mbe(vde);
+ if (err)
+ return err;
+
+ frame_idx_enb_mask = 0;
+ }
+ }
+
+ return 0;
+}
+
+static void tegra_vde_mbe_set_0xa_reg(struct tegra_vde *vde, int reg, u32 val)
+{
+ VDE_WR(0xA0000000 | (reg << 24) | (val & 0xFFFF), vde->mbe + 0x80);
+ VDE_WR(0xA0000000 | ((reg + 1) << 24) | (val >> 16), vde->mbe + 0x80);
+}
+
+static int tegra_vde_wait_bsev(struct tegra_vde *vde, bool wait_dma)
+{
+ struct device *dev = vde->miscdev.parent;
+ u32 value;
+ int err;
+
+ err = readl_relaxed_poll_timeout(vde->bsev + INTR_STATUS, value,
+ !(value & BIT(2)), 1, 100);
+ if (err) {
+ dev_err(dev, "BSEV unknown bit timeout\n");
+ return err;
+ }
+
+ err = readl_relaxed_poll_timeout(vde->bsev + INTR_STATUS, value,
+ (value & BSE_ICMDQUE_EMPTY), 1, 100);
+ if (err) {
+ dev_err(dev, "BSEV ICMDQUE flush timeout\n");
+ return err;
+ }
+
+ if (!wait_dma)
+ return 0;
+
+ err = readl_relaxed_poll_timeout(vde->bsev + INTR_STATUS, value,
+ !(value & BSE_DMA_BUSY), 1, 100);
+ if (err) {
+ dev_err(dev, "BSEV DMA timeout\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int tegra_vde_push_to_bsev_icmdqueue(struct tegra_vde *vde,
+ u32 value, bool wait_dma)
+{
+ VDE_WR(value, vde->bsev + ICMDQUE_WR);
+
+ return tegra_vde_wait_bsev(vde, wait_dma);
+}
+
+static void tegra_vde_setup_frameid(struct tegra_vde *vde,
+ struct video_frame *frame,
+ unsigned int frameid,
+ u32 mbs_width, u32 mbs_height)
+{
+ u32 y_addr = frame ? frame->y_addr : 0x6CDEAD00;
+ u32 cb_addr = frame ? frame->cb_addr : 0x6CDEAD00;
+ u32 cr_addr = frame ? frame->cr_addr : 0x6CDEAD00;
+ u32 value1 = frame ? ((mbs_width << 16) | mbs_height) : 0;
+ u32 value2 = frame ? ((((mbs_width + 1) >> 1) << 6) | 1) : 0;
+
+ VDE_WR(y_addr >> 8, vde->frameid + 0x000 + frameid * 4);
+ VDE_WR(cb_addr >> 8, vde->frameid + 0x100 + frameid * 4);
+ VDE_WR(cr_addr >> 8, vde->frameid + 0x180 + frameid * 4);
+ VDE_WR(value1, vde->frameid + 0x080 + frameid * 4);
+ VDE_WR(value2, vde->frameid + 0x280 + frameid * 4);
+}
+
+static void tegra_setup_frameidx(struct tegra_vde *vde,
+ struct video_frame *frames,
+ unsigned int frames_nb,
+ u32 mbs_width, u32 mbs_height)
+{
+ unsigned int idx;
+
+ for (idx = 0; idx < frames_nb; idx++)
+ tegra_vde_setup_frameid(vde, &frames[idx], idx,
+ mbs_width, mbs_height);
+
+ for (; idx < 17; idx++)
+ tegra_vde_setup_frameid(vde, NULL, idx, 0, 0);
+}
+
+static void tegra_vde_setup_iram_entry(struct tegra_vde *vde,
+ unsigned int table,
+ unsigned int row,
+ u32 value1, u32 value2)
+{
+ u32 *iram_tables = vde->iram;
+
+ dev_dbg(vde->miscdev.parent, "IRAM table %u: row %u: 0x%08X 0x%08X\n",
+ table, row, value1, value2);
+
+ iram_tables[0x20 * table + row * 2] = value1;
+ iram_tables[0x20 * table + row * 2 + 1] = value2;
+}
+
+static void tegra_vde_setup_iram_tables(struct tegra_vde *vde,
+ struct video_frame *dpb_frames,
+ unsigned int ref_frames_nb,
+ unsigned int with_earlier_poc_nb)
+{
+ struct video_frame *frame;
+ u32 value, aux_addr;
+ int with_later_poc_nb;
+ unsigned int i, k;
+
+ dev_dbg(vde->miscdev.parent, "DPB: Frame 0: frame_num = %d\n",
+ dpb_frames[0].frame_num);
+
+ dev_dbg(vde->miscdev.parent, "REF L0:\n");
+
+ for (i = 0; i < 16; i++) {
+ if (i < ref_frames_nb) {
+ frame = &dpb_frames[i + 1];
+
+ aux_addr = frame->aux_addr;
+
+ value = (i + 1) << 26;
+ value |= !(frame->flags & FLAG_B_FRAME) << 25;
+ value |= 1 << 24;
+ value |= frame->frame_num;
+
+ dev_dbg(vde->miscdev.parent,
+ "\tFrame %d: frame_num = %d B_frame = %d\n",
+ i + 1, frame->frame_num,
+ (frame->flags & FLAG_B_FRAME));
+ } else {
+ aux_addr = 0x6ADEAD00;
+ value = 0;
+ }
+
+ tegra_vde_setup_iram_entry(vde, 0, i, value, aux_addr);
+ tegra_vde_setup_iram_entry(vde, 1, i, value, aux_addr);
+ tegra_vde_setup_iram_entry(vde, 2, i, value, aux_addr);
+ tegra_vde_setup_iram_entry(vde, 3, i, value, aux_addr);
+ }
+
+ if (!(dpb_frames[0].flags & FLAG_B_FRAME))
+ return;
+
+ if (with_earlier_poc_nb >= ref_frames_nb)
+ return;
+
+ with_later_poc_nb = ref_frames_nb - with_earlier_poc_nb;
+
+ dev_dbg(vde->miscdev.parent,
+ "REF L1: with_later_poc_nb %d with_earlier_poc_nb %d\n",
+ with_later_poc_nb, with_earlier_poc_nb);
+
+ for (i = 0, k = with_earlier_poc_nb; i < with_later_poc_nb; i++, k++) {
+ frame = &dpb_frames[k + 1];
+
+ aux_addr = frame->aux_addr;
+
+ value = (k + 1) << 26;
+ value |= !(frame->flags & FLAG_B_FRAME) << 25;
+ value |= 1 << 24;
+ value |= frame->frame_num;
+
+ dev_dbg(vde->miscdev.parent,
+ "\tFrame %d: frame_num = %d\n",
+ k + 1, frame->frame_num);
+
+ tegra_vde_setup_iram_entry(vde, 2, i, value, aux_addr);
+ }
+
+ for (k = 0; i < ref_frames_nb; i++, k++) {
+ frame = &dpb_frames[k + 1];
+
+ aux_addr = frame->aux_addr;
+
+ value = (k + 1) << 26;
+ value |= !(frame->flags & FLAG_B_FRAME) << 25;
+ value |= 1 << 24;
+ value |= frame->frame_num;
+
+ dev_dbg(vde->miscdev.parent,
+ "\tFrame %d: frame_num = %d\n",
+ k + 1, frame->frame_num);
+
+ tegra_vde_setup_iram_entry(vde, 2, i, value, aux_addr);
+ }
+}
+
+static int tegra_vde_setup_hw_context(struct tegra_vde *vde,
+ struct tegra_vde_h264_decoder_ctx *ctx,
+ struct video_frame *dpb_frames,
+ dma_addr_t bitstream_data_addr,
+ size_t bitstream_data_size,
+ unsigned int macroblocks_nb)
+{
+ struct device *dev = vde->miscdev.parent;
+ u32 value;
+ int err;
+
+ tegra_vde_set_bits(vde, 0x000A, vde->sxe + 0xF0);
+ tegra_vde_set_bits(vde, 0x000B, vde->bsev + CMDQUE_CONTROL);
+ tegra_vde_set_bits(vde, 0x8002, vde->mbe + 0x50);
+ tegra_vde_set_bits(vde, 0x000A, vde->mbe + 0xA0);
+ tegra_vde_set_bits(vde, 0x000A, vde->ppe + 0x14);
+ tegra_vde_set_bits(vde, 0x000A, vde->ppe + 0x28);
+ tegra_vde_set_bits(vde, 0x0A00, vde->mce + 0x08);
+ tegra_vde_set_bits(vde, 0x000A, vde->tfe + 0x00);
+ tegra_vde_set_bits(vde, 0x0005, vde->vdma + 0x04);
+
+ VDE_WR(0x00000000, vde->vdma + 0x1C);
+ VDE_WR(0x00000000, vde->vdma + 0x00);
+ VDE_WR(0x00000007, vde->vdma + 0x04);
+ VDE_WR(0x00000007, vde->frameid + 0x200);
+ VDE_WR(0x00000005, vde->tfe + 0x04);
+ VDE_WR(0x00000000, vde->mbe + 0x84);
+ VDE_WR(0x00000010, vde->sxe + 0x08);
+ VDE_WR(0x00000150, vde->sxe + 0x54);
+ VDE_WR(0x0000054C, vde->sxe + 0x58);
+ VDE_WR(0x00000E34, vde->sxe + 0x5C);
+ VDE_WR(0x063C063C, vde->mce + 0x10);
+ VDE_WR(0x0003FC00, vde->bsev + INTR_STATUS);
+ VDE_WR(0x0000150D, vde->bsev + BSE_CONFIG);
+ VDE_WR(0x00000100, vde->bsev + BSE_INT_ENB);
+ VDE_WR(0x00000000, vde->bsev + 0x98);
+ VDE_WR(0x00000060, vde->bsev + 0x9C);
+
+ memset(vde->iram + 128, 0, macroblocks_nb / 2);
+
+ tegra_setup_frameidx(vde, dpb_frames, ctx->dpb_frames_nb,
+ ctx->pic_width_in_mbs, ctx->pic_height_in_mbs);
+
+ tegra_vde_setup_iram_tables(vde, dpb_frames,
+ ctx->dpb_frames_nb - 1,
+ ctx->dpb_ref_frames_with_earlier_poc_nb);
+ wmb();
+
+ VDE_WR(0x00000000, vde->bsev + 0x8C);
+ VDE_WR(bitstream_data_addr + bitstream_data_size,
+ vde->bsev + 0x54);
+
+ value = ctx->pic_width_in_mbs << 11 | ctx->pic_height_in_mbs << 3;
+
+ VDE_WR(value, vde->bsev + 0x88);
+
+ err = tegra_vde_wait_bsev(vde, false);
+ if (err)
+ return err;
+
+ err = tegra_vde_push_to_bsev_icmdqueue(vde, 0x800003FC, false);
+ if (err)
+ return err;
+
+ value = 0x01500000;
+ value |= ((vde->iram_lists_addr + 512) >> 2) & 0xFFFF;
+
+ err = tegra_vde_push_to_bsev_icmdqueue(vde, value, true);
+ if (err)
+ return err;
+
+ err = tegra_vde_push_to_bsev_icmdqueue(vde, 0x840F054C, false);
+ if (err)
+ return err;
+
+ err = tegra_vde_push_to_bsev_icmdqueue(vde, 0x80000080, false);
+ if (err)
+ return err;
+
+ value = 0x0E340000 | ((vde->iram_lists_addr >> 2) & 0xFFFF);
+
+ err = tegra_vde_push_to_bsev_icmdqueue(vde, value, true);
+ if (err)
+ return err;
+
+ value = 0x00800005;
+ value |= ctx->pic_width_in_mbs << 11;
+ value |= ctx->pic_height_in_mbs << 3;
+
+ VDE_WR(value, vde->sxe + 0x10);
+
+ value = !ctx->baseline_profile << 17;
+ value |= ctx->level_idc << 13;
+ value |= ctx->log2_max_pic_order_cnt_lsb << 7;
+ value |= ctx->pic_order_cnt_type << 5;
+ value |= ctx->log2_max_frame_num;
+
+ VDE_WR(value, vde->sxe + 0x40);
+
+ value = ctx->pic_init_qp << 25;
+ value |= !!(ctx->deblocking_filter_control_present_flag) << 2;
+ value |= !!ctx->pic_order_present_flag;
+
+ VDE_WR(value, vde->sxe + 0x44);
+
+ value = ctx->chroma_qp_index_offset;
+ value |= ctx->num_ref_idx_l0_active_minus1 << 5;
+ value |= ctx->num_ref_idx_l1_active_minus1 << 10;
+ value |= !!ctx->constrained_intra_pred_flag << 15;
+
+ VDE_WR(value, vde->sxe + 0x48);
+
+ value = 0x0C000000;
+ value |= !!(dpb_frames[0].flags & FLAG_B_FRAME) << 24;
+
+ VDE_WR(value, vde->sxe + 0x4C);
+
+ value = 0x03800000;
+ value |= min_t(size_t, bitstream_data_size, SZ_1M);
+
+ VDE_WR(value, vde->sxe + 0x68);
+
+ VDE_WR(bitstream_data_addr, vde->sxe + 0x6C);
+
+ value = 0x10000005;
+ value |= ctx->pic_width_in_mbs << 11;
+ value |= ctx->pic_height_in_mbs << 3;
+
+ VDE_WR(value, vde->mbe + 0x80);
+
+ value = 0x26800000;
+ value |= ctx->level_idc << 4;
+ value |= !ctx->baseline_profile << 1;
+ value |= !!ctx->direct_8x8_inference_flag;
+
+ VDE_WR(value, vde->mbe + 0x80);
+
+ VDE_WR(0xF4000001, vde->mbe + 0x80);
+ VDE_WR(0x20000000, vde->mbe + 0x80);
+ VDE_WR(0xF4000101, vde->mbe + 0x80);
+
+ value = 0x20000000;
+ value |= ctx->chroma_qp_index_offset << 8;
+
+ VDE_WR(value, vde->mbe + 0x80);
+
+ err = tegra_vde_setup_mbe_frame_idx(vde,
+ ctx->dpb_frames_nb - 1,
+ ctx->pic_order_cnt_type == 0);
+ if (err) {
+ dev_err(dev, "MBE frames setup failed %d\n", err);
+ return err;
+ }
+
+ tegra_vde_mbe_set_0xa_reg(vde, 0, 0x000009FC);
+ tegra_vde_mbe_set_0xa_reg(vde, 2, 0x61DEAD00);
+ tegra_vde_mbe_set_0xa_reg(vde, 4, 0x62DEAD00);
+ tegra_vde_mbe_set_0xa_reg(vde, 6, 0x63DEAD00);
+ tegra_vde_mbe_set_0xa_reg(vde, 8, dpb_frames[0].aux_addr);
+
+ value = 0xFC000000;
+ value |= !!(dpb_frames[0].flags & FLAG_B_FRAME) << 2;
+
+ if (!ctx->baseline_profile)
+ value |= !!(dpb_frames[0].flags & FLAG_REFERENCE) << 1;
+
+ VDE_WR(value, vde->mbe + 0x80);
+
+ err = tegra_vde_wait_mbe(vde);
+ if (err) {
+ dev_err(dev, "MBE programming failed %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static void tegra_vde_decode_frame(struct tegra_vde *vde,
+ unsigned int macroblocks_nb)
+{
+ reinit_completion(&vde->decode_completion);
+
+ VDE_WR(0x00000001, vde->bsev + 0x8C);
+ VDE_WR(0x20000000 | (macroblocks_nb - 1), vde->sxe + 0x00);
+}
+
+static void tegra_vde_detach_and_put_dmabuf(struct dma_buf_attachment *a,
+ struct sg_table *sgt,
+ enum dma_data_direction dma_dir)
+{
+ struct dma_buf *dmabuf = a->dmabuf;
+
+ dma_buf_unmap_attachment(a, sgt, dma_dir);
+ dma_buf_detach(dmabuf, a);
+ dma_buf_put(dmabuf);
+}
+
+static int tegra_vde_attach_dmabuf(struct device *dev,
+ int fd,
+ unsigned long offset,
+ unsigned int min_size,
+ struct dma_buf_attachment **a,
+ dma_addr_t *addr,
+ struct sg_table **s,
+ size_t *size,
+ enum dma_data_direction dma_dir)
+{
+ struct dma_buf_attachment *attachment;
+ struct dma_buf *dmabuf;
+ struct sg_table *sgt;
+ int err;
+
+ dmabuf = dma_buf_get(fd);
+ if (IS_ERR(dmabuf)) {
+ dev_err(dev, "Invalid dmabuf FD\n");
+ return PTR_ERR(dmabuf);
+ }
+
+ if ((u64)offset + min_size > dmabuf->size) {
+ dev_err(dev, "Too small dmabuf size %zu @0x%lX, "
+ "should be at least %d\n",
+ dmabuf->size, offset, min_size);
+ return -EINVAL;
+ }
+
+ attachment = dma_buf_attach(dmabuf, dev);
+ if (IS_ERR(attachment)) {
+ dev_err(dev, "Failed to attach dmabuf\n");
+ err = PTR_ERR(attachment);
+ goto err_put;
+ }
+
+ sgt = dma_buf_map_attachment(attachment, dma_dir);
+ if (IS_ERR(sgt)) {
+ dev_err(dev, "Failed to get dmabufs sg_table\n");
+ err = PTR_ERR(sgt);
+ goto err_detach;
+ }
+
+ if (sgt->nents != 1) {
+ dev_err(dev, "Sparse DMA region is unsupported\n");
+ err = -EINVAL;
+ goto err_unmap;
+ }
+
+ *addr = sg_dma_address(sgt->sgl) + offset;
+ *a = attachment;
+ *s = sgt;
+
+ if (size)
+ *size = dmabuf->size - offset;
+
+ return 0;
+
+err_unmap:
+ dma_buf_unmap_attachment(attachment, sgt, dma_dir);
+err_detach:
+ dma_buf_detach(dmabuf, attachment);
+err_put:
+ dma_buf_put(dmabuf);
+
+ return err;
+}
+
+static int tegra_vde_attach_dmabufs_to_frame(struct device *dev,
+ struct video_frame *frame,
+ struct tegra_vde_h264_frame *src,
+ enum dma_data_direction dma_dir,
+ bool baseline_profile,
+ size_t csize)
+{
+ int err;
+
+ err = tegra_vde_attach_dmabuf(dev, src->y_fd,
+ src->y_offset, csize * 4,
+ &frame->y_dmabuf_attachment,
+ &frame->y_addr,
+ &frame->y_sgt,
+ NULL, dma_dir);
+ if (err)
+ return err;
+
+ err = tegra_vde_attach_dmabuf(dev, src->cb_fd,
+ src->cb_offset, csize,
+ &frame->cb_dmabuf_attachment,
+ &frame->cb_addr,
+ &frame->cb_sgt,
+ NULL, dma_dir);
+ if (err)
+ goto err_release_y;
+
+ err = tegra_vde_attach_dmabuf(dev, src->cr_fd,
+ src->cr_offset, csize,
+ &frame->cr_dmabuf_attachment,
+ &frame->cr_addr,
+ &frame->cr_sgt,
+ NULL, dma_dir);
+ if (err)
+ goto err_release_cb;
+
+ if (baseline_profile) {
+ frame->aux_addr = 0x64DEAD00;
+ return 0;
+ }
+
+ err = tegra_vde_attach_dmabuf(dev, src->aux_fd,
+ src->aux_offset, csize,
+ &frame->aux_dmabuf_attachment,
+ &frame->aux_addr,
+ &frame->aux_sgt,
+ NULL, dma_dir);
+ if (err)
+ goto err_release_cr;
+
+ return 0;
+
+err_release_cr:
+ tegra_vde_detach_and_put_dmabuf(frame->cr_dmabuf_attachment,
+ frame->cr_sgt, dma_dir);
+err_release_cb:
+ tegra_vde_detach_and_put_dmabuf(frame->cb_dmabuf_attachment,
+ frame->cb_sgt, dma_dir);
+err_release_y:
+ tegra_vde_detach_and_put_dmabuf(frame->y_dmabuf_attachment,
+ frame->y_sgt, dma_dir);
+
+ return err;
+}
+
+static void tegra_vde_release_frame_dmabufs(struct video_frame *frame,
+ enum dma_data_direction dma_dir,
+ bool baseline_profile)
+{
+ if (!baseline_profile)
+ tegra_vde_detach_and_put_dmabuf(frame->aux_dmabuf_attachment,
+ frame->aux_sgt, dma_dir);
+
+ tegra_vde_detach_and_put_dmabuf(frame->cr_dmabuf_attachment,
+ frame->cr_sgt, dma_dir);
+
+ tegra_vde_detach_and_put_dmabuf(frame->cb_dmabuf_attachment,
+ frame->cb_sgt, dma_dir);
+
+ tegra_vde_detach_and_put_dmabuf(frame->y_dmabuf_attachment,
+ frame->y_sgt, dma_dir);
+}
+
+static int tegra_vde_validate_frame(struct device *dev,
+ struct tegra_vde_h264_frame *frame)
+{
+ if (frame->frame_num > 0x7FFFFF) {
+ dev_err(dev, "Bad frame_num %u\n", frame->frame_num);
+ return -EINVAL;
+ }
+
+ if (frame->y_offset & 0xFF) {
+ dev_err(dev, "Bad y_offset 0x%X\n", frame->y_offset);
+ return -EINVAL;
+ }
+
+ if (frame->cb_offset & 0xFF) {
+ dev_err(dev, "Bad cb_offset 0x%X\n", frame->cb_offset);
+ return -EINVAL;
+ }
+
+ if (frame->cr_offset & 0xFF) {
+ dev_err(dev, "Bad cr_offset 0x%X\n", frame->cr_offset);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int tegra_vde_validate_h264_ctx(struct device *dev,
+ struct tegra_vde_h264_decoder_ctx *ctx)
+{
+ if (ctx->dpb_frames_nb == 0 || ctx->dpb_frames_nb > 17) {
+ dev_err(dev, "Bad DPB size %u\n", ctx->dpb_frames_nb);
+ return -EINVAL;
+ }
+
+ if (ctx->level_idc > 15) {
+ dev_err(dev, "Bad level value %u\n", ctx->level_idc);
+ return -EINVAL;
+ }
+
+ if (ctx->pic_init_qp > 52) {
+ dev_err(dev, "Bad pic_init_qp value %u\n", ctx->pic_init_qp);
+ return -EINVAL;
+ }
+
+ if (ctx->log2_max_pic_order_cnt_lsb > 16) {
+ dev_err(dev, "Bad log2_max_pic_order_cnt_lsb value %u\n",
+ ctx->log2_max_pic_order_cnt_lsb);
+ return -EINVAL;
+ }
+
+ if (ctx->log2_max_frame_num > 16) {
+ dev_err(dev, "Bad log2_max_frame_num value %u\n",
+ ctx->log2_max_frame_num);
+ return -EINVAL;
+ }
+
+ if (ctx->chroma_qp_index_offset > 31) {
+ dev_err(dev, "Bad chroma_qp_index_offset value %u\n",
+ ctx->chroma_qp_index_offset);
+ return -EINVAL;
+ }
+
+ if (ctx->pic_order_cnt_type > 2) {
+ dev_err(dev, "Bad pic_order_cnt_type value %u\n",
+ ctx->pic_order_cnt_type);
+ return -EINVAL;
+ }
+
+ if (ctx->num_ref_idx_l0_active_minus1 > 15) {
+ dev_err(dev, "Bad num_ref_idx_l0_active_minus1 value %u\n",
+ ctx->num_ref_idx_l0_active_minus1);
+ return -EINVAL;
+ }
+
+ if (ctx->num_ref_idx_l1_active_minus1 > 15) {
+ dev_err(dev, "Bad num_ref_idx_l1_active_minus1 value %u\n",
+ ctx->num_ref_idx_l1_active_minus1);
+ return -EINVAL;
+ }
+
+ if (!ctx->pic_width_in_mbs || ctx->pic_width_in_mbs > 127) {
+ dev_err(dev, "Bad pic_width_in_mbs value %u\n",
+ ctx->pic_width_in_mbs);
+ return -EINVAL;
+ }
+
+ if (!ctx->pic_height_in_mbs || ctx->pic_height_in_mbs > 127) {
+ dev_err(dev, "Bad pic_height_in_mbs value %u\n",
+ ctx->pic_height_in_mbs);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int tegra_vde_ioctl_decode_h264(struct tegra_vde *vde,
+ unsigned long vaddr)
+{
+ struct device *dev = vde->miscdev.parent;
+ struct tegra_vde_h264_decoder_ctx ctx;
+ struct tegra_vde_h264_frame frames[17];
+ struct tegra_vde_h264_frame __user *frames_user;
+ struct video_frame *dpb_frames;
+ struct dma_buf_attachment *bitstream_data_dmabuf_attachment;
+ struct sg_table *bitstream_sgt;
+ enum dma_data_direction dma_dir;
+ dma_addr_t bitstream_data_addr;
+ dma_addr_t bsev_ptr;
+ size_t bitstream_data_size;
+ unsigned int macroblocks_nb;
+ unsigned int read_bytes;
+ unsigned int i;
+ long timeout;
+ int ret, err;
+
+ if (copy_from_user(&ctx, (void __user *)vaddr, sizeof(ctx)))
+ return -EFAULT;
+
+ ret = tegra_vde_validate_h264_ctx(dev, &ctx);
+ if (ret)
+ return ret;
+
+ ret = tegra_vde_attach_dmabuf(dev, ctx.bitstream_data_fd,
+ ctx.bitstream_data_offset, 0,
+ &bitstream_data_dmabuf_attachment,
+ &bitstream_data_addr,
+ &bitstream_sgt,
+ &bitstream_data_size,
+ DMA_TO_DEVICE);
+ if (ret)
+ return ret;
+
+ dpb_frames = kcalloc(ctx.dpb_frames_nb, sizeof(*dpb_frames),
+ GFP_KERNEL);
+ if (!dpb_frames) {
+ ret = -ENOMEM;
+ goto release_bitstream_dmabuf;
+ }
+
+ macroblocks_nb = ctx.pic_width_in_mbs * ctx.pic_height_in_mbs;
+ frames_user = u64_to_user_ptr(ctx.dpb_frames_ptr);
+
+ if (copy_from_user(frames, frames_user,
+ ctx.dpb_frames_nb * sizeof(*frames))) {
+ ret = -EFAULT;
+ goto free_dpb_frames;
+ }
+
+ for (i = 0; i < ctx.dpb_frames_nb; i++) {
+ ret = tegra_vde_validate_frame(dev, &frames[i]);
+ if (ret)
+ goto release_dpb_frames;
+
+ dpb_frames[i].flags = frames[i].flags;
+ dpb_frames[i].frame_num = frames[i].frame_num;
+
+ dma_dir = (i == 0) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+ ret = tegra_vde_attach_dmabufs_to_frame(dev, &dpb_frames[i],
+ &frames[i], dma_dir,
+ ctx.baseline_profile,
+ macroblocks_nb * 64);
+ if (ret)
+ goto release_dpb_frames;
+ }
+
+ ret = mutex_lock_interruptible(&vde->lock);
+ if (ret)
+ goto release_dpb_frames;
+
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0)
+ goto unlock;
+
+ /*
+ * We rely on the VDE registers reset value, otherwise VDE
+ * causes bus lockup.
+ */
+ ret = reset_control_reset(vde->rst);
+ if (ret) {
+ dev_err(dev, "Failed to reset HW: %d\n", ret);
+ goto put_runtime_pm;
+ }
+
+ ret = tegra_vde_setup_hw_context(vde, &ctx, dpb_frames,
+ bitstream_data_addr,
+ bitstream_data_size,
+ macroblocks_nb);
+ if (ret)
+ goto put_runtime_pm;
+
+ tegra_vde_decode_frame(vde, macroblocks_nb);
+
+ timeout = wait_for_completion_interruptible_timeout(
+ &vde->decode_completion, msecs_to_jiffies(1000));
+ if (timeout == 0) {
+ bsev_ptr = readl_relaxed(vde->bsev + 0x10);
+ macroblocks_nb = readl_relaxed(vde->sxe + 0xC8) & 0x1FFF;
+ read_bytes = bsev_ptr ? bsev_ptr - bitstream_data_addr : 0;
+
+ dev_err(dev, "Decoding failed: "
+ "read 0x%X bytes, %u macroblocks parsed\n",
+ read_bytes, macroblocks_nb);
+
+ ret = -EIO;
+ } else if (timeout < 0) {
+ ret = timeout;
+ }
+
+ err = reset_control_assert(vde->rst);
+ if (err)
+ dev_err(dev, "Failed to assert HW reset: %d\n", err);
+
+put_runtime_pm:
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+
+unlock:
+ mutex_unlock(&vde->lock);
+
+release_dpb_frames:
+ while (i--) {
+ dma_dir = (i == 0) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+ tegra_vde_release_frame_dmabufs(&dpb_frames[i], dma_dir,
+ ctx.baseline_profile);
+ }
+
+free_dpb_frames:
+ kfree(dpb_frames);
+
+release_bitstream_dmabuf:
+ tegra_vde_detach_and_put_dmabuf(bitstream_data_dmabuf_attachment,
+ bitstream_sgt, DMA_TO_DEVICE);
+
+ return ret;
+}
+
+static long tegra_vde_unlocked_ioctl(struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ struct miscdevice *miscdev = filp->private_data;
+ struct tegra_vde *vde = container_of(miscdev, struct tegra_vde,
+ miscdev);
+
+ switch (cmd) {
+ case TEGRA_VDE_IOCTL_DECODE_H264:
+ return tegra_vde_ioctl_decode_h264(vde, arg);
+ }
+
+ dev_err(miscdev->parent, "Invalid IOCTL command %u\n", cmd);
+
+ return -ENOTTY;
+}
+
+static const struct file_operations tegra_vde_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = tegra_vde_unlocked_ioctl,
+};
+
+static irqreturn_t tegra_vde_isr(int irq, void *data)
+{
+ struct tegra_vde *vde = data;
+
+ tegra_vde_set_bits(vde, 0, vde->frameid + 0x208);
+ complete(&vde->decode_completion);
+
+ return IRQ_HANDLED;
+}
+
+static int tegra_vde_runtime_suspend(struct device *dev)
+{
+ struct tegra_vde *vde = dev_get_drvdata(dev);
+ int err;
+
+ err = tegra_powergate_power_off(TEGRA_POWERGATE_VDEC);
+ if (err) {
+ dev_err(dev, "Failed to power down HW: %d\n", err);
+ return err;
+ }
+
+ clk_disable_unprepare(vde->clk);
+
+ return 0;
+}
+
+static int tegra_vde_runtime_resume(struct device *dev)
+{
+ struct tegra_vde *vde = dev_get_drvdata(dev);
+ int err;
+
+ err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_VDEC,
+ vde->clk, vde->rst);
+ if (err) {
+ dev_err(dev, "Failed to power up HW : %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int tegra_vde_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *regs;
+ struct tegra_vde *vde;
+ int irq, err;
+
+ vde = devm_kzalloc(dev, sizeof(*vde), GFP_KERNEL);
+ if (!vde)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, vde);
+
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sxe");
+ if (!regs)
+ return -ENODEV;
+
+ vde->sxe = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(vde->sxe))
+ return PTR_ERR(vde->sxe);
+
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bsev");
+ if (!regs)
+ return -ENODEV;
+
+ vde->bsev = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(vde->bsev))
+ return PTR_ERR(vde->bsev);
+
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mbe");
+ if (!regs)
+ return -ENODEV;
+
+ vde->mbe = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(vde->mbe))
+ return PTR_ERR(vde->mbe);
+
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppe");
+ if (!regs)
+ return -ENODEV;
+
+ vde->ppe = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(vde->ppe))
+ return PTR_ERR(vde->ppe);
+
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mce");
+ if (!regs)
+ return -ENODEV;
+
+ vde->mce = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(vde->mce))
+ return PTR_ERR(vde->mce);
+
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tfe");
+ if (!regs)
+ return -ENODEV;
+
+ vde->tfe = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(vde->tfe))
+ return PTR_ERR(vde->tfe);
+
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ppb");
+ if (!regs)
+ return -ENODEV;
+
+ vde->ppb = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(vde->ppb))
+ return PTR_ERR(vde->ppb);
+
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vdma");
+ if (!regs)
+ return -ENODEV;
+
+ vde->vdma = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(vde->vdma))
+ return PTR_ERR(vde->vdma);
+
+ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "frameid");
+ if (!regs)
+ return -ENODEV;
+
+ vde->frameid = devm_ioremap_resource(dev, regs);
+ if (IS_ERR(vde->frameid))
+ return PTR_ERR(vde->frameid);
+
+ vde->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(vde->clk)) {
+ err = PTR_ERR(vde->clk);
+ dev_err(dev, "Could not get VDE clk %d\n", err);
+ return err;
+ }
+
+ vde->rst = devm_reset_control_get(dev, NULL);
+ if (IS_ERR(vde->rst)) {
+ err = PTR_ERR(vde->rst);
+ dev_err(dev, "Could not get VDE reset %d\n", err);
+ return err;
+ }
+
+ irq = platform_get_irq_byname(pdev, "sync-token");
+ if (irq < 0)
+ return irq;
+
+ err = devm_request_irq(dev, irq, tegra_vde_isr, 0,
+ dev_name(dev), vde);
+ if (err) {
+ dev_err(dev, "Could not request IRQ %d\n", err);
+ return err;
+ }
+
+ vde->iram_pool = of_gen_pool_get(dev->of_node, "iram", 0);
+ if (!vde->iram_pool) {
+ dev_err(dev, "Could not get IRAM pool\n");
+ return -EPROBE_DEFER;
+ }
+
+ vde->iram = gen_pool_dma_alloc(vde->iram_pool,
+ gen_pool_size(vde->iram_pool),
+ &vde->iram_lists_addr);
+ if (!vde->iram) {
+ dev_err(dev, "Could not reserve IRAM\n");
+ return -ENOMEM;
+ }
+
+ mutex_init(&vde->lock);
+ init_completion(&vde->decode_completion);
+
+ vde->miscdev.minor = MISC_DYNAMIC_MINOR;
+ vde->miscdev.name = "tegra_vde";
+ vde->miscdev.fops = &tegra_vde_fops;
+ vde->miscdev.parent = dev;
+
+ err = misc_register(&vde->miscdev);
+ if (err) {
+ dev_err(dev, "Failed to register misc device: %d\n", err);
+ goto err_gen_free;
+ }
+
+ pm_runtime_enable(dev);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_set_autosuspend_delay(dev, 300);
+
+ if (!pm_runtime_enabled(dev)) {
+ err = tegra_vde_runtime_resume(dev);
+ if (err)
+ goto err_misc_unreg;
+ }
+
+ return 0;
+
+err_misc_unreg:
+ misc_deregister(&vde->miscdev);
+
+err_gen_free:
+ gen_pool_free(vde->iram_pool, (unsigned long)vde->iram,
+ gen_pool_size(vde->iram_pool));
+
+ return err;
+}
+
+static int tegra_vde_remove(struct platform_device *pdev)
+{
+ struct tegra_vde *vde = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
+ int err;
+
+ if (!pm_runtime_enabled(dev)) {
+ err = tegra_vde_runtime_suspend(dev);
+ if (err)
+ return err;
+ }
+
+ pm_runtime_dont_use_autosuspend(dev);
+ pm_runtime_disable(dev);
+
+ misc_deregister(&vde->miscdev);
+
+ gen_pool_free(vde->iram_pool, (unsigned long)vde->iram,
+ gen_pool_size(vde->iram_pool));
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tegra_vde_pm_suspend(struct device *dev)
+{
+ struct tegra_vde *vde = dev_get_drvdata(dev);
+ int err;
+
+ mutex_lock(&vde->lock);
+
+ err = pm_runtime_force_suspend(dev);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int tegra_vde_pm_resume(struct device *dev)
+{
+ struct tegra_vde *vde = dev_get_drvdata(dev);
+ int err;
+
+ err = pm_runtime_force_resume(dev);
+ if (err < 0)
+ return err;
+
+ mutex_unlock(&vde->lock);
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops tegra_vde_pm_ops = {
+ SET_RUNTIME_PM_OPS(tegra_vde_runtime_suspend,
+ tegra_vde_runtime_resume,
+ NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(tegra_vde_pm_suspend,
+ tegra_vde_pm_resume)
+};
+
+static const struct of_device_id tegra_vde_of_match[] = {
+ { .compatible = "nvidia,tegra20-vde", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, tegra_vde_of_match);
+
+static struct platform_driver tegra_vde_driver = {
+ .probe = tegra_vde_probe,
+ .remove = tegra_vde_remove,
+ .driver = {
+ .name = "tegra-vde",
+ .of_match_table = tegra_vde_of_match,
+ .pm = &tegra_vde_pm_ops,
+ },
+};
+module_platform_driver(tegra_vde_driver);
+
+MODULE_DESCRIPTION("NVIDIA Tegra Video Decoder driver");
+MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/media/tegra-vde/uapi.h b/drivers/staging/media/tegra-vde/uapi.h
new file mode 100644
index 000000000000..a50c7bcae057
--- /dev/null
+++ b/drivers/staging/media/tegra-vde/uapi.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016-2017 Dmitry Osipenko <digetx@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _UAPI_TEGRA_VDE_H_
+#define _UAPI_TEGRA_VDE_H_
+
+#include <linux/types.h>
+#include <asm/ioctl.h>
+
+#define FLAG_B_FRAME (1 << 0)
+#define FLAG_REFERENCE (1 << 1)
+
+struct tegra_vde_h264_frame {
+ __s32 y_fd;
+ __s32 cb_fd;
+ __s32 cr_fd;
+ __s32 aux_fd;
+ __u32 y_offset;
+ __u32 cb_offset;
+ __u32 cr_offset;
+ __u32 aux_offset;
+ __u32 frame_num;
+ __u32 flags;
+
+ __u32 reserved;
+} __attribute__((packed));
+
+struct tegra_vde_h264_decoder_ctx {
+ __s32 bitstream_data_fd;
+ __u32 bitstream_data_offset;
+
+ __u64 dpb_frames_ptr;
+ __u8 dpb_frames_nb;
+ __u8 dpb_ref_frames_with_earlier_poc_nb;
+
+ // SPS
+ __u8 baseline_profile;
+ __u8 level_idc;
+ __u8 log2_max_pic_order_cnt_lsb;
+ __u8 log2_max_frame_num;
+ __u8 pic_order_cnt_type;
+ __u8 direct_8x8_inference_flag;
+ __u8 pic_width_in_mbs;
+ __u8 pic_height_in_mbs;
+
+ // PPS
+ __u8 pic_init_qp;
+ __u8 deblocking_filter_control_present_flag;
+ __u8 constrained_intra_pred_flag;
+ __u8 chroma_qp_index_offset;
+ __u8 pic_order_present_flag;
+
+ // Slice header
+ __u8 num_ref_idx_l0_active_minus1;
+ __u8 num_ref_idx_l1_active_minus1;
+
+ __u32 reserved;
+} __attribute__((packed));
+
+#define VDE_IOCTL_BASE ('v' + 0x20)
+
+#define VDE_IO(nr) _IO(VDE_IOCTL_BASE, nr)
+#define VDE_IOR(nr, type) _IOR(VDE_IOCTL_BASE, nr, type)
+#define VDE_IOW(nr, type) _IOW(VDE_IOCTL_BASE, nr, type)
+#define VDE_IOWR(nr, type) _IOWR(VDE_IOCTL_BASE, nr, type)
+
+#define TEGRA_VDE_DECODE_H264 0x00
+
+#define TEGRA_VDE_IOCTL_DECODE_H264 \
+ VDE_IOW(TEGRA_VDE_DECODE_H264, struct tegra_vde_h264_decoder_ctx)
+
+#endif // _UAPI_TEGRA_VDE_H_
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 315ae2926e20..b6adc54b96f1 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -301,13 +301,13 @@ config DB8500_THERMAL
thermal zone if trip points reached.
config ARMADA_THERMAL
- tristate "Armada 370/XP thermal management"
+ tristate "Marvell EBU Armada SoCs thermal management"
depends on ARCH_MVEBU || COMPILE_TEST
depends on HAS_IOMEM
depends on OF
help
Enable this option if you want to have support for thermal management
- controller present in Armada 370 and Armada XP SoC.
+ controller present in Marvell EBU Armada SoCs (370,375,XP,38x,7K,8K).
config DA9062_THERMAL
tristate "DA9062/DA9061 Dialog Semiconductor thermal driver"
diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c
index 706d74798cbe..4c275ec10ac5 100644
--- a/drivers/thermal/armada_thermal.c
+++ b/drivers/thermal/armada_thermal.c
@@ -1,5 +1,5 @@
/*
- * Marvell Armada 370/XP thermal sensor driver
+ * Marvell EBU Armada SoCs thermal sensor driver
*
* Copyright (C) 2013 Marvell
*
@@ -23,8 +23,7 @@
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/thermal.h>
-
-#define THERMAL_VALID_MASK 0x1
+#include <linux/iopoll.h>
/* Thermal Manager Control and Status Register */
#define PMU_TDC0_SW_RST_MASK (0x1 << 1)
@@ -39,14 +38,38 @@
#define A375_UNIT_CONTROL_MASK 0x7
#define A375_READOUT_INVERT BIT(15)
#define A375_HW_RESETn BIT(8)
-#define A380_HW_RESET BIT(8)
+
+/* Legacy bindings */
+#define LEGACY_CONTROL_MEM_LEN 0x4
+
+/* Current bindings with the 2 control registers under the same memory area */
+#define LEGACY_CONTROL1_OFFSET 0x0
+#define CONTROL0_OFFSET 0x0
+#define CONTROL1_OFFSET 0x4
+
+/* Errata fields */
+#define CONTROL0_TSEN_TC_TRIM_MASK 0x7
+#define CONTROL0_TSEN_TC_TRIM_VAL 0x3
+
+/* TSEN refers to the temperature sensors within the AP */
+#define CONTROL0_TSEN_START BIT(0)
+#define CONTROL0_TSEN_RESET BIT(1)
+#define CONTROL0_TSEN_ENABLE BIT(2)
+
+/* EXT_TSEN refers to the external temperature sensors, out of the AP */
+#define CONTROL1_EXT_TSEN_SW_RESET BIT(7)
+#define CONTROL1_EXT_TSEN_HW_RESETn BIT(8)
+
+#define STATUS_POLL_PERIOD_US 1000
+#define STATUS_POLL_TIMEOUT_US 100000
struct armada_thermal_data;
/* Marvell EBU Thermal Sensor Dev Structure */
struct armada_thermal_priv {
- void __iomem *sensor;
- void __iomem *control;
+ void __iomem *status;
+ void __iomem *control0;
+ void __iomem *control1;
struct armada_thermal_data *data;
};
@@ -59,107 +82,142 @@ struct armada_thermal_data {
bool (*is_valid)(struct armada_thermal_priv *);
/* Formula coeficients: temp = (b - m * reg) / div */
- unsigned long coef_b;
- unsigned long coef_m;
- unsigned long coef_div;
+ s64 coef_b;
+ s64 coef_m;
+ u32 coef_div;
bool inverted;
+ bool signed_sample;
/* Register shift and mask to access the sensor temperature */
unsigned int temp_shift;
unsigned int temp_mask;
- unsigned int is_valid_shift;
+ u32 is_valid_bit;
+ bool needs_control0;
};
static void armadaxp_init_sensor(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
- unsigned long reg;
+ u32 reg;
- reg = readl_relaxed(priv->control);
+ reg = readl_relaxed(priv->control1);
reg |= PMU_TDC0_OTF_CAL_MASK;
- writel(reg, priv->control);
+ writel(reg, priv->control1);
/* Reference calibration value */
reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
- writel(reg, priv->control);
+ writel(reg, priv->control1);
/* Reset the sensor */
- reg = readl_relaxed(priv->control);
- writel((reg | PMU_TDC0_SW_RST_MASK), priv->control);
+ reg = readl_relaxed(priv->control1);
+ writel((reg | PMU_TDC0_SW_RST_MASK), priv->control1);
- writel(reg, priv->control);
+ writel(reg, priv->control1);
/* Enable the sensor */
- reg = readl_relaxed(priv->sensor);
+ reg = readl_relaxed(priv->status);
reg &= ~PMU_TM_DISABLE_MASK;
- writel(reg, priv->sensor);
+ writel(reg, priv->status);
}
static void armada370_init_sensor(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
- unsigned long reg;
+ u32 reg;
- reg = readl_relaxed(priv->control);
+ reg = readl_relaxed(priv->control1);
reg |= PMU_TDC0_OTF_CAL_MASK;
- writel(reg, priv->control);
+ writel(reg, priv->control1);
/* Reference calibration value */
reg &= ~PMU_TDC0_REF_CAL_CNT_MASK;
reg |= (0xf1 << PMU_TDC0_REF_CAL_CNT_OFFS);
- writel(reg, priv->control);
+ writel(reg, priv->control1);
reg &= ~PMU_TDC0_START_CAL_MASK;
- writel(reg, priv->control);
+ writel(reg, priv->control1);
- mdelay(10);
+ msleep(10);
}
static void armada375_init_sensor(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
- unsigned long reg;
+ u32 reg;
- reg = readl(priv->control + 4);
+ reg = readl(priv->control1);
reg &= ~(A375_UNIT_CONTROL_MASK << A375_UNIT_CONTROL_SHIFT);
reg &= ~A375_READOUT_INVERT;
reg &= ~A375_HW_RESETn;
- writel(reg, priv->control + 4);
- mdelay(20);
+ writel(reg, priv->control1);
+ msleep(20);
reg |= A375_HW_RESETn;
- writel(reg, priv->control + 4);
- mdelay(50);
+ writel(reg, priv->control1);
+ msleep(50);
+}
+
+static void armada_wait_sensor_validity(struct armada_thermal_priv *priv)
+{
+ u32 reg;
+
+ readl_relaxed_poll_timeout(priv->status, reg,
+ reg & priv->data->is_valid_bit,
+ STATUS_POLL_PERIOD_US,
+ STATUS_POLL_TIMEOUT_US);
}
static void armada380_init_sensor(struct platform_device *pdev,
struct armada_thermal_priv *priv)
{
- unsigned long reg = readl_relaxed(priv->control);
-
- /* Reset hardware once */
- if (!(reg & A380_HW_RESET)) {
- reg |= A380_HW_RESET;
- writel(reg, priv->control);
- mdelay(10);
+ u32 reg = readl_relaxed(priv->control1);
+
+ /* Disable the HW/SW reset */
+ reg |= CONTROL1_EXT_TSEN_HW_RESETn;
+ reg &= ~CONTROL1_EXT_TSEN_SW_RESET;
+ writel(reg, priv->control1);
+
+ /* Set Tsen Tc Trim to correct default value (errata #132698) */
+ if (priv->control0) {
+ reg = readl_relaxed(priv->control0);
+ reg &= ~CONTROL0_TSEN_TC_TRIM_MASK;
+ reg |= CONTROL0_TSEN_TC_TRIM_VAL;
+ writel(reg, priv->control0);
}
+
+ /* Wait the sensors to be valid or the core will warn the user */
+ armada_wait_sensor_validity(priv);
+}
+
+static void armada_ap806_init_sensor(struct platform_device *pdev,
+ struct armada_thermal_priv *priv)
+{
+ u32 reg;
+
+ reg = readl_relaxed(priv->control0);
+ reg &= ~CONTROL0_TSEN_RESET;
+ reg |= CONTROL0_TSEN_START | CONTROL0_TSEN_ENABLE;
+ writel(reg, priv->control0);
+
+ /* Wait the sensors to be valid or the core will warn the user */
+ armada_wait_sensor_validity(priv);
}
static bool armada_is_valid(struct armada_thermal_priv *priv)
{
- unsigned long reg = readl_relaxed(priv->sensor);
+ u32 reg = readl_relaxed(priv->status);
- return (reg >> priv->data->is_valid_shift) & THERMAL_VALID_MASK;
+ return reg & priv->data->is_valid_bit;
}
static int armada_get_temp(struct thermal_zone_device *thermal,
- int *temp)
+ int *temp)
{
struct armada_thermal_priv *priv = thermal->devdata;
- unsigned long reg;
- unsigned long m, b, div;
+ u32 reg, div;
+ s64 sample, b, m;
/* Valid check */
if (priv->data->is_valid && !priv->data->is_valid(priv)) {
@@ -168,8 +226,13 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
return -EIO;
}
- reg = readl_relaxed(priv->sensor);
+ reg = readl_relaxed(priv->status);
reg = (reg >> priv->data->temp_shift) & priv->data->temp_mask;
+ if (priv->data->signed_sample)
+ /* The most significant bit is the sign bit */
+ sample = sign_extend32(reg, fls(priv->data->temp_mask) - 1);
+ else
+ sample = reg;
/* Get formula coeficients */
b = priv->data->coef_b;
@@ -177,9 +240,10 @@ static int armada_get_temp(struct thermal_zone_device *thermal,
div = priv->data->coef_div;
if (priv->data->inverted)
- *temp = ((m * reg) - b) / div;
+ *temp = div_s64((m * sample) - b, div);
else
- *temp = (b - (m * reg)) / div;
+ *temp = div_s64(b - (m * sample), div);
+
return 0;
}
@@ -191,45 +255,73 @@ static const struct armada_thermal_data armadaxp_data = {
.init_sensor = armadaxp_init_sensor,
.temp_shift = 10,
.temp_mask = 0x1ff,
- .coef_b = 3153000000UL,
- .coef_m = 10000000UL,
+ .coef_b = 3153000000ULL,
+ .coef_m = 10000000ULL,
.coef_div = 13825,
};
static const struct armada_thermal_data armada370_data = {
.is_valid = armada_is_valid,
.init_sensor = armada370_init_sensor,
- .is_valid_shift = 9,
+ .is_valid_bit = BIT(9),
.temp_shift = 10,
.temp_mask = 0x1ff,
- .coef_b = 3153000000UL,
- .coef_m = 10000000UL,
+ .coef_b = 3153000000ULL,
+ .coef_m = 10000000ULL,
.coef_div = 13825,
};
static const struct armada_thermal_data armada375_data = {
.is_valid = armada_is_valid,
.init_sensor = armada375_init_sensor,
- .is_valid_shift = 10,
+ .is_valid_bit = BIT(10),
.temp_shift = 0,
.temp_mask = 0x1ff,
- .coef_b = 3171900000UL,
- .coef_m = 10000000UL,
+ .coef_b = 3171900000ULL,
+ .coef_m = 10000000ULL,
.coef_div = 13616,
+ .needs_control0 = true,
};
static const struct armada_thermal_data armada380_data = {
.is_valid = armada_is_valid,
.init_sensor = armada380_init_sensor,
- .is_valid_shift = 10,
+ .is_valid_bit = BIT(10),
.temp_shift = 0,
.temp_mask = 0x3ff,
- .coef_b = 1172499100UL,
- .coef_m = 2000096UL,
+ .coef_b = 1172499100ULL,
+ .coef_m = 2000096ULL,
.coef_div = 4201,
.inverted = true,
};
+static const struct armada_thermal_data armada_ap806_data = {
+ .is_valid = armada_is_valid,
+ .init_sensor = armada_ap806_init_sensor,
+ .is_valid_bit = BIT(16),
+ .temp_shift = 0,
+ .temp_mask = 0x3ff,
+ .coef_b = -150000LL,
+ .coef_m = 423ULL,
+ .coef_div = 1,
+ .inverted = true,
+ .signed_sample = true,
+ .needs_control0 = true,
+};
+
+static const struct armada_thermal_data armada_cp110_data = {
+ .is_valid = armada_is_valid,
+ .init_sensor = armada380_init_sensor,
+ .is_valid_bit = BIT(10),
+ .temp_shift = 0,
+ .temp_mask = 0x3ff,
+ .coef_b = 1172499100ULL,
+ .coef_m = 2000096ULL,
+ .coef_div = 4201,
+ .inverted = true,
+ .needs_control0 = true,
+};
+
static const struct of_device_id armada_thermal_id_table[] = {
{
.compatible = "marvell,armadaxp-thermal",
@@ -248,6 +340,14 @@ static const struct of_device_id armada_thermal_id_table[] = {
.data = &armada380_data,
},
{
+ .compatible = "marvell,armada-ap806-thermal",
+ .data = &armada_ap806_data,
+ },
+ {
+ .compatible = "marvell,armada-cp110-thermal",
+ .data = &armada_cp110_data,
+ },
+ {
/* sentinel */
},
};
@@ -255,6 +355,7 @@ MODULE_DEVICE_TABLE(of, armada_thermal_id_table);
static int armada_thermal_probe(struct platform_device *pdev)
{
+ void __iomem *control = NULL;
struct thermal_zone_device *thermal;
const struct of_device_id *match;
struct armada_thermal_priv *priv;
@@ -269,20 +370,40 @@ static int armada_thermal_probe(struct platform_device *pdev)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- priv->sensor = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(priv->sensor))
- return PTR_ERR(priv->sensor);
+ priv->status = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(priv->status))
+ return PTR_ERR(priv->status);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- priv->control = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(priv->control))
- return PTR_ERR(priv->control);
+ control = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(control))
+ return PTR_ERR(control);
priv->data = (struct armada_thermal_data *)match->data;
+
+ /*
+ * Legacy DT bindings only described "control1" register (also referred
+ * as "control MSB" on old documentation). New bindings cover
+ * "control0/control LSB" and "control1/control MSB" registers within
+ * the same resource, which is then of size 8 instead of 4.
+ */
+ if (resource_size(res) == LEGACY_CONTROL_MEM_LEN) {
+ /* ->control0 unavailable in this configuration */
+ if (priv->data->needs_control0) {
+ dev_err(&pdev->dev, "No access to control0 register\n");
+ return -EINVAL;
+ }
+
+ priv->control1 = control + LEGACY_CONTROL1_OFFSET;
+ } else {
+ priv->control0 = control + CONTROL0_OFFSET;
+ priv->control1 = control + CONTROL1_OFFSET;
+ }
+
priv->data->init_sensor(pdev, priv);
- thermal = thermal_zone_device_register("armada_thermal", 0, 0,
- priv, &ops, NULL, 0, 0);
+ thermal = thermal_zone_device_register(dev_name(&pdev->dev), 0, 0, priv,
+ &ops, NULL, 0, 0);
if (IS_ERR(thermal)) {
dev_err(&pdev->dev,
"Failed to register thermal zone device\n");
@@ -316,5 +437,5 @@ static struct platform_driver armada_thermal_driver = {
module_platform_driver(armada_thermal_driver);
MODULE_AUTHOR("Ezequiel Garcia <ezequiel.garcia@free-electrons.com>");
-MODULE_DESCRIPTION("Armada 370/XP thermal driver");
+MODULE_DESCRIPTION("Marvell EBU Armada SoCs thermal driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/thermal/hisi_thermal.c b/drivers/thermal/hisi_thermal.c
index 2d855a96cdd9..761d0559c268 100644
--- a/drivers/thermal/hisi_thermal.c
+++ b/drivers/thermal/hisi_thermal.c
@@ -527,7 +527,7 @@ static void hisi_thermal_toggle_sensor(struct hisi_thermal_sensor *sensor,
static int hisi_thermal_probe(struct platform_device *pdev)
{
struct hisi_thermal_data *data;
- int const (*platform_probe)(struct hisi_thermal_data *);
+ int (*platform_probe)(struct hisi_thermal_data *);
struct device *dev = &pdev->dev;
int ret;
diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c
index e7d4ffc3de7f..a67781b7a0b2 100644
--- a/drivers/thermal/imx_thermal.c
+++ b/drivers/thermal/imx_thermal.c
@@ -70,10 +70,6 @@ enum imx_thermal_trip {
#define IMX_POLLING_DELAY 2000 /* millisecond */
#define IMX_PASSIVE_DELAY 1000
-#define FACTOR0 10000000
-#define FACTOR1 15976
-#define FACTOR2 4297157
-
#define TEMPMON_IMX6Q 1
#define TEMPMON_IMX6SX 2
@@ -347,78 +343,74 @@ static struct thermal_zone_device_ops imx_tz_ops = {
.set_trip_temp = imx_set_trip_temp,
};
-static int imx_init_calib(struct platform_device *pdev, u32 val)
+static int imx_init_calib(struct platform_device *pdev, u32 ocotp_ana1)
{
struct imx_thermal_data *data = platform_get_drvdata(pdev);
- int t1, n1;
+ int n1;
u64 temp64;
- if (val == 0 || val == ~0) {
+ if (ocotp_ana1 == 0 || ocotp_ana1 == ~0) {
dev_err(&pdev->dev, "invalid sensor calibration data\n");
return -EINVAL;
}
/*
- * Sensor data layout:
- * [31:20] - sensor value @ 25C
- * Use universal formula now and only need sensor value @ 25C
- * slope = 0.4297157 - (0.0015976 * 25C fuse)
+ * The sensor is calibrated at 25 °C (aka T1) and the value measured
+ * (aka N1) at this temperature is provided in bits [31:20] in the
+ * i.MX's OCOTP value ANA1.
+ * To find the actual temperature T, the following formula has to be used
+ * when reading value n from the sensor:
+ *
+ * T = T1 + (N - N1) / (0.4148468 - 0.0015423 * N1) °C + 3.580661 °C
+ * = [T1' - N1 / (0.4148468 - 0.0015423 * N1) °C] + N / (0.4148468 - 0.0015423 * N1) °C
+ * = [T1' + N1 / (0.0015423 * N1 - 0.4148468) °C] - N / (0.0015423 * N1 - 0.4148468) °C
+ * = c2 - c1 * N
+ *
+ * with
+ *
+ * T1' = 28.580661 °C
+ * c1 = 1 / (0.0015423 * N1 - 0.4297157) °C
+ * c2 = T1' + N1 / (0.0015423 * N1 - 0.4148468) °C
+ * = T1' + N1 * c1
*/
- n1 = val >> 20;
- t1 = 25; /* t1 always 25C */
+ n1 = ocotp_ana1 >> 20;
- /*
- * Derived from linear interpolation:
- * slope = 0.4297157 - (0.0015976 * 25C fuse)
- * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
- * (Nmeas - n1) / (Tmeas - t1) = slope
- * We want to reduce this down to the minimum computation necessary
- * for each temperature read. Also, we want Tmeas in millicelsius
- * and we don't want to lose precision from integer division. So...
- * Tmeas = (Nmeas - n1) / slope + t1
- * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
- * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
- * Let constant c1 = (-1000 / slope)
- * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
- * Let constant c2 = n1 *c1 + 1000 * t1
- * milli_Tmeas = c2 - Nmeas * c1
- */
- temp64 = FACTOR0;
- temp64 *= 1000;
- do_div(temp64, FACTOR1 * n1 - FACTOR2);
+ temp64 = 10000000; /* use 10^7 as fixed point constant for values in formula */
+ temp64 *= 1000; /* to get result in °mC */
+ do_div(temp64, 15423 * n1 - 4148468);
data->c1 = temp64;
- data->c2 = n1 * data->c1 + 1000 * t1;
+ data->c2 = n1 * data->c1 + 28581;
return 0;
}
-static void imx_init_temp_grade(struct platform_device *pdev, u32 val)
+static void imx_init_temp_grade(struct platform_device *pdev, u32 ocotp_mem0)
{
struct imx_thermal_data *data = platform_get_drvdata(pdev);
/* The maximum die temp is specified by the Temperature Grade */
- switch ((val >> 6) & 0x3) {
- case 0: /* Commercial (0 to 95C) */
+ switch ((ocotp_mem0 >> 6) & 0x3) {
+ case 0: /* Commercial (0 to 95 °C) */
data->temp_grade = "Commercial";
data->temp_max = 95000;
break;
- case 1: /* Extended Commercial (-20 to 105C) */
+ case 1: /* Extended Commercial (-20 °C to 105 °C) */
data->temp_grade = "Extended Commercial";
data->temp_max = 105000;
break;
- case 2: /* Industrial (-40 to 105C) */
+ case 2: /* Industrial (-40 °C to 105 °C) */
data->temp_grade = "Industrial";
data->temp_max = 105000;
break;
- case 3: /* Automotive (-40 to 125C) */
+ case 3: /* Automotive (-40 °C to 125 °C) */
data->temp_grade = "Automotive";
data->temp_max = 125000;
break;
}
/*
- * Set the critical trip point at 5C under max
- * Set the passive trip point at 10C under max (can change via sysfs)
+ * Set the critical trip point at 5 °C under max
+ * Set the passive trip point at 10 °C under max (changeable via sysfs)
*/
data->temp_critical = data->temp_max - (1000 * 5);
data->temp_passive = data->temp_max - (1000 * 10);
diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c
index 8ee38f55c7f3..e26b01c05e82 100644
--- a/drivers/thermal/int340x_thermal/int3400_thermal.c
+++ b/drivers/thermal/int340x_thermal/int3400_thermal.c
@@ -211,7 +211,7 @@ static void int3400_notify(acpi_handle handle,
thermal_prop);
break;
default:
- dev_err(&priv->adev->dev, "Unsupported event [0x%x]\n", event);
+ /* Ignore unknown notification codes sent to INT3400 device */
break;
}
}
@@ -319,17 +319,21 @@ static int int3400_thermal_probe(struct platform_device *pdev)
result = sysfs_create_group(&pdev->dev.kobj, &uuid_attribute_group);
if (result)
- goto free_zone;
+ goto free_rel_misc;
result = acpi_install_notify_handler(
priv->adev->handle, ACPI_DEVICE_NOTIFY, int3400_notify,
(void *)priv);
if (result)
- goto free_zone;
+ goto free_sysfs;
return 0;
-free_zone:
+free_sysfs:
+ sysfs_remove_group(&pdev->dev.kobj, &uuid_attribute_group);
+free_rel_misc:
+ if (!priv->rel_misc_dev_res)
+ acpi_thermal_rel_misc_device_remove(priv->adev->handle);
thermal_zone_device_unregister(priv->thermal);
free_art_trt:
kfree(priv->trts);
diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index 1e61c09153c9..c75661a3801a 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -32,15 +32,10 @@
#include <linux/types.h>
/* AUXADC Registers */
-#define AUXADC_CON0_V 0x000
-#define AUXADC_CON1_V 0x004
#define AUXADC_CON1_SET_V 0x008
#define AUXADC_CON1_CLR_V 0x00c
#define AUXADC_CON2_V 0x010
#define AUXADC_DATA(channel) (0x14 + (channel) * 4)
-#define AUXADC_MISC_V 0x094
-
-#define AUXADC_CON1_CHANNEL(x) BIT(x)
#define APMIXED_SYS_TS_CON1 0x604
@@ -158,8 +153,6 @@
/* The number of sensing points per bank */
#define MT2712_NUM_SENSORS_PER_ZONE 4
-#define THERMAL_NAME "mtk-thermal"
-
struct mtk_thermal;
struct thermal_bank_cfg {
@@ -765,7 +758,7 @@ static struct platform_driver mtk_thermal_driver = {
.probe = mtk_thermal_probe,
.remove = mtk_thermal_remove,
.driver = {
- .name = THERMAL_NAME,
+ .name = "mtk-thermal",
.of_match_table = mtk_thermal_of_match,
},
};
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index d04ec3b9e5ff..e09f0354a4bc 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -30,7 +30,6 @@
#include <linux/err.h>
#include <linux/export.h>
#include <linux/string.h>
-#include <linux/thermal.h>
#include "thermal_core.h"
diff --git a/drivers/thermal/power_allocator.c b/drivers/thermal/power_allocator.c
index b4d3116cfdaf..3055f9a12a17 100644
--- a/drivers/thermal/power_allocator.c
+++ b/drivers/thermal/power_allocator.c
@@ -523,6 +523,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz)
struct thermal_instance *instance;
struct power_allocator_params *params = tz->governor_data;
+ mutex_lock(&tz->lock);
list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
if ((instance->trip != params->trip_max_desired_temperature) ||
(!cdev_is_power_actor(instance->cdev)))
@@ -534,6 +535,7 @@ static void allow_maximum_power(struct thermal_zone_device *tz)
mutex_unlock(&instance->cdev->lock);
thermal_cdev_update(instance->cdev);
}
+ mutex_unlock(&tz->lock);
}
/**
diff --git a/drivers/thermal/tegra/soctherm.c b/drivers/thermal/tegra/soctherm.c
index 075db1de5e53..455b58ce2652 100644
--- a/drivers/thermal/tegra/soctherm.c
+++ b/drivers/thermal/tegra/soctherm.c
@@ -341,62 +341,6 @@ static int tegra_thermctl_get_temp(void *data, int *out_temp)
return 0;
}
-static int
-thermtrip_program(struct device *dev, const struct tegra_tsensor_group *sg,
- int trip_temp);
-static int
-throttrip_program(struct device *dev, const struct tegra_tsensor_group *sg,
- struct soctherm_throt_cfg *stc, int trip_temp);
-static struct soctherm_throt_cfg *
-find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name);
-
-static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
-{
- struct tegra_thermctl_zone *zone = data;
- struct thermal_zone_device *tz = zone->tz;
- struct tegra_soctherm *ts = zone->ts;
- const struct tegra_tsensor_group *sg = zone->sg;
- struct device *dev = zone->dev;
- enum thermal_trip_type type;
- int ret;
-
- if (!tz)
- return -EINVAL;
-
- ret = tz->ops->get_trip_type(tz, trip, &type);
- if (ret)
- return ret;
-
- if (type == THERMAL_TRIP_CRITICAL) {
- return thermtrip_program(dev, sg, temp);
- } else if (type == THERMAL_TRIP_HOT) {
- int i;
-
- for (i = 0; i < THROTTLE_SIZE; i++) {
- struct thermal_cooling_device *cdev;
- struct soctherm_throt_cfg *stc;
-
- if (!ts->throt_cfgs[i].init)
- continue;
-
- cdev = ts->throt_cfgs[i].cdev;
- if (get_thermal_instance(tz, cdev, trip))
- stc = find_throttle_cfg_by_name(ts, cdev->type);
- else
- continue;
-
- return throttrip_program(dev, sg, stc, temp);
- }
- }
-
- return 0;
-}
-
-static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
- .get_temp = tegra_thermctl_get_temp,
- .set_trip_temp = tegra_thermctl_set_trip_temp,
-};
-
/**
* enforce_temp_range() - check and enforce temperature range [min, max]
* @trip_temp: the trip temperature to check
@@ -527,6 +471,53 @@ find_throttle_cfg_by_name(struct tegra_soctherm *ts, const char *name)
return NULL;
}
+static int tegra_thermctl_set_trip_temp(void *data, int trip, int temp)
+{
+ struct tegra_thermctl_zone *zone = data;
+ struct thermal_zone_device *tz = zone->tz;
+ struct tegra_soctherm *ts = zone->ts;
+ const struct tegra_tsensor_group *sg = zone->sg;
+ struct device *dev = zone->dev;
+ enum thermal_trip_type type;
+ int ret;
+
+ if (!tz)
+ return -EINVAL;
+
+ ret = tz->ops->get_trip_type(tz, trip, &type);
+ if (ret)
+ return ret;
+
+ if (type == THERMAL_TRIP_CRITICAL) {
+ return thermtrip_program(dev, sg, temp);
+ } else if (type == THERMAL_TRIP_HOT) {
+ int i;
+
+ for (i = 0; i < THROTTLE_SIZE; i++) {
+ struct thermal_cooling_device *cdev;
+ struct soctherm_throt_cfg *stc;
+
+ if (!ts->throt_cfgs[i].init)
+ continue;
+
+ cdev = ts->throt_cfgs[i].cdev;
+ if (get_thermal_instance(tz, cdev, trip))
+ stc = find_throttle_cfg_by_name(ts, cdev->type);
+ else
+ continue;
+
+ return throttrip_program(dev, sg, stc, temp);
+ }
+ }
+
+ return 0;
+}
+
+static const struct thermal_zone_of_device_ops tegra_of_thermal_ops = {
+ .get_temp = tegra_thermctl_get_temp,
+ .set_trip_temp = tegra_thermctl_set_trip_temp,
+};
+
static int get_hot_temp(struct thermal_zone_device *tz, int *trip, int *temp)
{
int ntrips, i, ret;
diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c
index 541af5946203..c4a508a124dc 100644
--- a/drivers/thermal/thermal_hwmon.c
+++ b/drivers/thermal/thermal_hwmon.c
@@ -59,14 +59,6 @@ static LIST_HEAD(thermal_hwmon_list);
static DEFINE_MUTEX(thermal_hwmon_list_lock);
static ssize_t
-name_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n", hwmon->type);
-}
-static DEVICE_ATTR_RO(name);
-
-static ssize_t
temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
{
int temperature;
@@ -165,15 +157,12 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
INIT_LIST_HEAD(&hwmon->tz_list);
strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
- hwmon->device = hwmon_device_register(NULL);
+ hwmon->device = hwmon_device_register_with_info(NULL, hwmon->type,
+ hwmon, NULL, NULL);
if (IS_ERR(hwmon->device)) {
result = PTR_ERR(hwmon->device);
goto free_mem;
}
- dev_set_drvdata(hwmon->device, hwmon);
- result = device_create_file(hwmon->device, &dev_attr_name);
- if (result)
- goto free_mem;
register_sys_interface:
temp = kzalloc(sizeof(*temp), GFP_KERNEL);
@@ -222,10 +211,8 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
free_temp_mem:
kfree(temp);
unregister_name:
- if (new_hwmon_device) {
- device_remove_file(hwmon->device, &dev_attr_name);
+ if (new_hwmon_device)
hwmon_device_unregister(hwmon->device);
- }
free_mem:
if (new_hwmon_device)
kfree(hwmon);
@@ -267,7 +254,6 @@ void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
list_del(&hwmon->node);
mutex_unlock(&thermal_hwmon_list_lock);
- device_remove_file(hwmon->device, &dev_attr_name);
hwmon_device_unregister(hwmon->device);
kfree(hwmon);
}
diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
index d93eee2f101b..1a6c88b10a39 100644
--- a/drivers/thermal/x86_pkg_temp_thermal.c
+++ b/drivers/thermal/x86_pkg_temp_thermal.c
@@ -96,12 +96,12 @@ static int pkg_temp_debugfs_init(void)
return -ENOENT;
d = debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs,
- (u32 *)&pkg_interrupt_cnt);
+ &pkg_interrupt_cnt);
if (!d)
goto err_out;
d = debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs,
- (u32 *)&pkg_work_cnt);
+ &pkg_work_cnt);
if (!d)
goto err_out;
diff --git a/drivers/usb/host/ehci-st.c b/drivers/usb/host/ehci-st.c
index 3c1362ab70be..dc42981047c9 100644
--- a/drivers/usb/host/ehci-st.c
+++ b/drivers/usb/host/ehci-st.c
@@ -23,6 +23,7 @@
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/ehci_pdriver.h>
+#include <linux/pinctrl/consumer.h>
#include "ehci.h"
diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c
index 9269d5685239..b90ef96e43d6 100644
--- a/drivers/video/console/dummycon.c
+++ b/drivers/video/console/dummycon.c
@@ -67,7 +67,6 @@ const struct consw dummy_con = {
.con_switch = DUMMY,
.con_blank = DUMMY,
.con_font_set = DUMMY,
- .con_font_get = DUMMY,
.con_font_default = DUMMY,
.con_font_copy = DUMMY,
};
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 445b1dc5d441..a17ba1465815 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -422,7 +422,10 @@ static const char *vgacon_startup(void)
vga_video_port_val = VGA_CRT_DM;
if ((screen_info.orig_video_ega_bx & 0xff) != 0x10) {
static struct resource ega_console_resource =
- { .name = "ega", .start = 0x3B0, .end = 0x3BF };
+ { .name = "ega",
+ .flags = IORESOURCE_IO,
+ .start = 0x3B0,
+ .end = 0x3BF };
vga_video_type = VIDEO_TYPE_EGAM;
vga_vram_size = 0x8000;
display_desc = "EGA+";
@@ -430,9 +433,15 @@ static const char *vgacon_startup(void)
&ega_console_resource);
} else {
static struct resource mda1_console_resource =
- { .name = "mda", .start = 0x3B0, .end = 0x3BB };
+ { .name = "mda",
+ .flags = IORESOURCE_IO,
+ .start = 0x3B0,
+ .end = 0x3BB };
static struct resource mda2_console_resource =
- { .name = "mda", .start = 0x3BF, .end = 0x3BF };
+ { .name = "mda",
+ .flags = IORESOURCE_IO,
+ .start = 0x3BF,
+ .end = 0x3BF };
vga_video_type = VIDEO_TYPE_MDA;
vga_vram_size = 0x2000;
display_desc = "*MDA";
@@ -454,15 +463,21 @@ static const char *vgacon_startup(void)
vga_vram_size = 0x8000;
if (!screen_info.orig_video_isVGA) {
- static struct resource ega_console_resource
- = { .name = "ega", .start = 0x3C0, .end = 0x3DF };
+ static struct resource ega_console_resource =
+ { .name = "ega",
+ .flags = IORESOURCE_IO,
+ .start = 0x3C0,
+ .end = 0x3DF };
vga_video_type = VIDEO_TYPE_EGAC;
display_desc = "EGA";
request_resource(&ioport_resource,
&ega_console_resource);
} else {
- static struct resource vga_console_resource
- = { .name = "vga+", .start = 0x3C0, .end = 0x3DF };
+ static struct resource vga_console_resource =
+ { .name = "vga+",
+ .flags = IORESOURCE_IO,
+ .start = 0x3C0,
+ .end = 0x3DF };
vga_video_type = VIDEO_TYPE_VGAC;
display_desc = "VGA+";
request_resource(&ioport_resource,
@@ -494,7 +509,10 @@ static const char *vgacon_startup(void)
}
} else {
static struct resource cga_console_resource =
- { .name = "cga", .start = 0x3D4, .end = 0x3D5 };
+ { .name = "cga",
+ .flags = IORESOURCE_IO,
+ .start = 0x3D4,
+ .end = 0x3D5 };
vga_video_type = VIDEO_TYPE_CGA;
vga_vram_size = 0x2000;
display_desc = "*CGA";
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 2566cfbdebfb..6962b4583fd7 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -1188,7 +1188,7 @@ config FB_INTEL
830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
Say Y if you have and plan to use such a board.
- To make FB_INTELFB=Y work you need to say AGP_INTEL=y too.
+ To make FB_INTEL=Y work you need to say AGP_INTEL=y too.
To compile this driver as a module, choose M here: the
module will be called intelfb.
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index e06358da4b99..3dee267d7c75 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -1119,7 +1119,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
goto put_display_node;
}
- timings_np = of_find_node_by_name(display_np, "display-timings");
+ timings_np = of_get_child_by_name(display_np, "display-timings");
if (!timings_np) {
dev_err(dev, "failed to find display-timings node\n");
ret = -ENODEV;
@@ -1140,6 +1140,12 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
fb_add_videomode(&fb_vm, &info->modelist);
}
+ /*
+ * FIXME: Make sure we are not referencing any fields in display_np
+ * and timings_np and drop our references to them before returning to
+ * avoid leaking the nodes on probe deferral and driver unbind.
+ */
+
return 0;
put_timings_node:
diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
index 4d77daeecf99..87608c0b2351 100644
--- a/drivers/video/fbdev/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
@@ -583,8 +583,8 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
int hTotal, vTotal, num, denom, m, n;
unsigned long long hz, vclk;
long xtal;
- struct timeval start_tv, stop_tv;
- long total_secs, total_usecs;
+ ktime_t start_time, stop_time;
+ u64 total_usecs;
int i;
/* Ugh, we cut interrupts, bad bad bad, but we want some precision
@@ -600,7 +600,7 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
if (((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0)
break;
- do_gettimeofday(&start_tv);
+ start_time = ktime_get();
for(i=0; i<1000000; i++)
if (((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) != 0)
@@ -610,18 +610,14 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
if (((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0)
break;
- do_gettimeofday(&stop_tv);
+ stop_time = ktime_get();
local_irq_enable();
- total_secs = stop_tv.tv_sec - start_tv.tv_sec;
- if (total_secs > 10)
+ total_usecs = ktime_us_delta(stop_time, start_time);
+ if (total_usecs >= 10 * USEC_PER_SEC || total_usecs == 0)
return -1;
- total_usecs = stop_tv.tv_usec - start_tv.tv_usec;
- total_usecs += total_secs * 1000000;
- if (total_usecs < 0)
- total_usecs = -total_usecs;
- hz = 1000000/total_usecs;
+ hz = USEC_PER_SEC/(u32)total_usecs;
hTotal = ((INREG(CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8;
vTotal = ((INREG(CRTC_V_TOTAL_DISP) & 0x3ff) + 1);
diff --git a/drivers/video/fbdev/au1200fb.h b/drivers/video/fbdev/au1200fb.h
index e2672714d8d4..b34fff342a1a 100644
--- a/drivers/video/fbdev/au1200fb.h
+++ b/drivers/video/fbdev/au1200fb.h
@@ -284,289 +284,3 @@ struct au1200_lcd {
/********************************************************************/
#endif /* _AU1200LCD_H */
-/*
- * BRIEF MODULE DESCRIPTION
- * Hardware definitions for the Au1200 LCD controller
- *
- * Copyright 2004 AMD
- * Author: AMD
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU 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 _AU1200LCD_H
-#define _AU1200LCD_H
-
-/********************************************************************/
-#define AU1200_LCD_ADDR 0xB5000000
-
-#define uint8 unsigned char
-#define uint32 unsigned int
-
-struct au1200_lcd {
- volatile uint32 reserved0;
- volatile uint32 screen;
- volatile uint32 backcolor;
- volatile uint32 horztiming;
- volatile uint32 verttiming;
- volatile uint32 clkcontrol;
- volatile uint32 pwmdiv;
- volatile uint32 pwmhi;
- volatile uint32 reserved1;
- volatile uint32 winenable;
- volatile uint32 colorkey;
- volatile uint32 colorkeymsk;
- struct
- {
- volatile uint32 cursorctrl;
- volatile uint32 cursorpos;
- volatile uint32 cursorcolor0;
- volatile uint32 cursorcolor1;
- volatile uint32 cursorcolor2;
- uint32 cursorcolor3;
- } hwc;
- volatile uint32 intstatus;
- volatile uint32 intenable;
- volatile uint32 outmask;
- volatile uint32 fifoctrl;
- uint32 reserved2[(0x0100-0x0058)/4];
- struct
- {
- volatile uint32 winctrl0;
- volatile uint32 winctrl1;
- volatile uint32 winctrl2;
- volatile uint32 winbuf0;
- volatile uint32 winbuf1;
- volatile uint32 winbufctrl;
- uint32 winreserved0;
- uint32 winreserved1;
- } window[4];
-
- uint32 reserved3[(0x0400-0x0180)/4];
-
- volatile uint32 palette[(0x0800-0x0400)/4];
-
- volatile uint8 cursorpattern[256];
-};
-
-/* lcd_screen */
-#define LCD_SCREEN_SEN (1<<31)
-#define LCD_SCREEN_SX (0x07FF<<19)
-#define LCD_SCREEN_SY (0x07FF<< 8)
-#define LCD_SCREEN_SWP (1<<7)
-#define LCD_SCREEN_SWD (1<<6)
-#define LCD_SCREEN_PT (7<<0)
-#define LCD_SCREEN_PT_TFT (0<<0)
-#define LCD_SCREEN_SX_N(WIDTH) ((WIDTH-1)<<19)
-#define LCD_SCREEN_SY_N(HEIGHT) ((HEIGHT-1)<<8)
-#define LCD_SCREEN_PT_CSTN (1<<0)
-#define LCD_SCREEN_PT_CDSTN (2<<0)
-#define LCD_SCREEN_PT_M8STN (3<<0)
-#define LCD_SCREEN_PT_M4STN (4<<0)
-
-/* lcd_backcolor */
-#define LCD_BACKCOLOR_SBGR (0xFF<<16)
-#define LCD_BACKCOLOR_SBGG (0xFF<<8)
-#define LCD_BACKCOLOR_SBGB (0xFF<<0)
-#define LCD_BACKCOLOR_SBGR_N(N) ((N)<<16)
-#define LCD_BACKCOLOR_SBGG_N(N) ((N)<<8)
-#define LCD_BACKCOLOR_SBGB_N(N) ((N)<<0)
-
-/* lcd_winenable */
-#define LCD_WINENABLE_WEN3 (1<<3)
-#define LCD_WINENABLE_WEN2 (1<<2)
-#define LCD_WINENABLE_WEN1 (1<<1)
-#define LCD_WINENABLE_WEN0 (1<<0)
-
-/* lcd_colorkey */
-#define LCD_COLORKEY_CKR (0xFF<<16)
-#define LCD_COLORKEY_CKG (0xFF<<8)
-#define LCD_COLORKEY_CKB (0xFF<<0)
-#define LCD_COLORKEY_CKR_N(N) ((N)<<16)
-#define LCD_COLORKEY_CKG_N(N) ((N)<<8)
-#define LCD_COLORKEY_CKB_N(N) ((N)<<0)
-
-/* lcd_colorkeymsk */
-#define LCD_COLORKEYMSK_CKMR (0xFF<<16)
-#define LCD_COLORKEYMSK_CKMG (0xFF<<8)
-#define LCD_COLORKEYMSK_CKMB (0xFF<<0)
-#define LCD_COLORKEYMSK_CKMR_N(N) ((N)<<16)
-#define LCD_COLORKEYMSK_CKMG_N(N) ((N)<<8)
-#define LCD_COLORKEYMSK_CKMB_N(N) ((N)<<0)
-
-/* lcd windows control 0 */
-#define LCD_WINCTRL0_OX (0x07FF<<21)
-#define LCD_WINCTRL0_OY (0x07FF<<10)
-#define LCD_WINCTRL0_A (0x00FF<<2)
-#define LCD_WINCTRL0_AEN (1<<1)
-#define LCD_WINCTRL0_OX_N(N) ((N)<<21)
-#define LCD_WINCTRL0_OY_N(N) ((N)<<10)
-#define LCD_WINCTRL0_A_N(N) ((N)<<2)
-
-/* lcd windows control 1 */
-#define LCD_WINCTRL1_PRI (3<<30)
-#define LCD_WINCTRL1_PIPE (1<<29)
-#define LCD_WINCTRL1_FRM (0xF<<25)
-#define LCD_WINCTRL1_CCO (1<<24)
-#define LCD_WINCTRL1_PO (3<<22)
-#define LCD_WINCTRL1_SZX (0x07FF<<11)
-#define LCD_WINCTRL1_SZY (0x07FF<<0)
-#define LCD_WINCTRL1_FRM_1BPP (0<<25)
-#define LCD_WINCTRL1_FRM_2BPP (1<<25)
-#define LCD_WINCTRL1_FRM_4BPP (2<<25)
-#define LCD_WINCTRL1_FRM_8BPP (3<<25)
-#define LCD_WINCTRL1_FRM_12BPP (4<<25)
-#define LCD_WINCTRL1_FRM_16BPP655 (5<<25)
-#define LCD_WINCTRL1_FRM_16BPP565 (6<<25)
-#define LCD_WINCTRL1_FRM_16BPP556 (7<<25)
-#define LCD_WINCTRL1_FRM_16BPPI1555 (8<<25)
-#define LCD_WINCTRL1_FRM_16BPPI5551 (9<<25)
-#define LCD_WINCTRL1_FRM_16BPPA1555 (10<<25)
-#define LCD_WINCTRL1_FRM_16BPPA5551 (11<<25)
-#define LCD_WINCTRL1_FRM_24BPP (12<<25)
-#define LCD_WINCTRL1_FRM_32BPP (13<<25)
-#define LCD_WINCTRL1_PRI_N(N) ((N)<<30)
-#define LCD_WINCTRL1_PO_00 (0<<22)
-#define LCD_WINCTRL1_PO_01 (1<<22)
-#define LCD_WINCTRL1_PO_10 (2<<22)
-#define LCD_WINCTRL1_PO_11 (3<<22)
-#define LCD_WINCTRL1_SZX_N(N) ((N-1)<<11)
-#define LCD_WINCTRL1_SZY_N(N) ((N-1)<<0)
-
-/* lcd windows control 2 */
-#define LCD_WINCTRL2_CKMODE (3<<24)
-#define LCD_WINCTRL2_DBM (1<<23)
-#define LCD_WINCTRL2_RAM (3<<21)
-#define LCD_WINCTRL2_BX (0x1FFF<<8)
-#define LCD_WINCTRL2_SCX (0xF<<4)
-#define LCD_WINCTRL2_SCY (0xF<<0)
-#define LCD_WINCTRL2_CKMODE_00 (0<<24)
-#define LCD_WINCTRL2_CKMODE_01 (1<<24)
-#define LCD_WINCTRL2_CKMODE_10 (2<<24)
-#define LCD_WINCTRL2_CKMODE_11 (3<<24)
-#define LCD_WINCTRL2_RAM_NONE (0<<21)
-#define LCD_WINCTRL2_RAM_PALETTE (1<<21)
-#define LCD_WINCTRL2_RAM_GAMMA (2<<21)
-#define LCD_WINCTRL2_RAM_BUFFER (3<<21)
-#define LCD_WINCTRL2_BX_N(N) ((N)<<8)
-#define LCD_WINCTRL2_SCX_1 (0<<4)
-#define LCD_WINCTRL2_SCX_2 (1<<4)
-#define LCD_WINCTRL2_SCX_4 (2<<4)
-#define LCD_WINCTRL2_SCY_1 (0<<0)
-#define LCD_WINCTRL2_SCY_2 (1<<0)
-#define LCD_WINCTRL2_SCY_4 (2<<0)
-
-/* lcd windows buffer control */
-#define LCD_WINBUFCTRL_DB (1<<1)
-#define LCD_WINBUFCTRL_DBN (1<<0)
-
-/* lcd_intstatus, lcd_intenable */
-#define LCD_INT_IFO (0xF<<14)
-#define LCD_INT_IFU (0xF<<10)
-#define LCD_INT_OFO (1<<9)
-#define LCD_INT_OFU (1<<8)
-#define LCD_INT_WAIT (1<<3)
-#define LCD_INT_SD (1<<2)
-#define LCD_INT_SA (1<<1)
-#define LCD_INT_SS (1<<0)
-
-/* lcd_horztiming */
-#define LCD_HORZTIMING_HND2 (0x1FF<<18)
-#define LCD_HORZTIMING_HND1 (0x1FF<<9)
-#define LCD_HORZTIMING_HPW (0x1FF<<0)
-#define LCD_HORZTIMING_HND2_N(N)(((N)-1)<<18)
-#define LCD_HORZTIMING_HND1_N(N)(((N)-1)<<9)
-#define LCD_HORZTIMING_HPW_N(N) (((N)-1)<<0)
-
-/* lcd_verttiming */
-#define LCD_VERTTIMING_VND2 (0x1FF<<18)
-#define LCD_VERTTIMING_VND1 (0x1FF<<9)
-#define LCD_VERTTIMING_VPW (0x1FF<<0)
-#define LCD_VERTTIMING_VND2_N(N)(((N)-1)<<18)
-#define LCD_VERTTIMING_VND1_N(N)(((N)-1)<<9)
-#define LCD_VERTTIMING_VPW_N(N) (((N)-1)<<0)
-
-/* lcd_clkcontrol */
-#define LCD_CLKCONTROL_EXT (1<<22)
-#define LCD_CLKCONTROL_DELAY (3<<20)
-#define LCD_CLKCONTROL_CDD (1<<19)
-#define LCD_CLKCONTROL_IB (1<<18)
-#define LCD_CLKCONTROL_IC (1<<17)
-#define LCD_CLKCONTROL_IH (1<<16)
-#define LCD_CLKCONTROL_IV (1<<15)
-#define LCD_CLKCONTROL_BF (0x1F<<10)
-#define LCD_CLKCONTROL_PCD (0x3FF<<0)
-#define LCD_CLKCONTROL_BF_N(N) (((N)-1)<<10)
-#define LCD_CLKCONTROL_PCD_N(N) ((N)<<0)
-
-/* lcd_pwmdiv */
-#define LCD_PWMDIV_EN (1<<31)
-#define LCD_PWMDIV_PWMDIV (0x1FFFF<<0)
-#define LCD_PWMDIV_PWMDIV_N(N) ((N)<<0)
-
-/* lcd_pwmhi */
-#define LCD_PWMHI_PWMHI1 (0xFFFF<<16)
-#define LCD_PWMHI_PWMHI0 (0xFFFF<<0)
-#define LCD_PWMHI_PWMHI1_N(N) ((N)<<16)
-#define LCD_PWMHI_PWMHI0_N(N) ((N)<<0)
-
-/* lcd_hwccon */
-#define LCD_HWCCON_EN (1<<0)
-
-/* lcd_cursorpos */
-#define LCD_CURSORPOS_HWCXOFF (0x1F<<27)
-#define LCD_CURSORPOS_HWCXPOS (0x07FF<<16)
-#define LCD_CURSORPOS_HWCYOFF (0x1F<<11)
-#define LCD_CURSORPOS_HWCYPOS (0x07FF<<0)
-#define LCD_CURSORPOS_HWCXOFF_N(N) ((N)<<27)
-#define LCD_CURSORPOS_HWCXPOS_N(N) ((N)<<16)
-#define LCD_CURSORPOS_HWCYOFF_N(N) ((N)<<11)
-#define LCD_CURSORPOS_HWCYPOS_N(N) ((N)<<0)
-
-/* lcd_cursorcolor */
-#define LCD_CURSORCOLOR_HWCA (0xFF<<24)
-#define LCD_CURSORCOLOR_HWCR (0xFF<<16)
-#define LCD_CURSORCOLOR_HWCG (0xFF<<8)
-#define LCD_CURSORCOLOR_HWCB (0xFF<<0)
-#define LCD_CURSORCOLOR_HWCA_N(N) ((N)<<24)
-#define LCD_CURSORCOLOR_HWCR_N(N) ((N)<<16)
-#define LCD_CURSORCOLOR_HWCG_N(N) ((N)<<8)
-#define LCD_CURSORCOLOR_HWCB_N(N) ((N)<<0)
-
-/* lcd_fifoctrl */
-#define LCD_FIFOCTRL_F3IF (1<<29)
-#define LCD_FIFOCTRL_F3REQ (0x1F<<24)
-#define LCD_FIFOCTRL_F2IF (1<<29)
-#define LCD_FIFOCTRL_F2REQ (0x1F<<16)
-#define LCD_FIFOCTRL_F1IF (1<<29)
-#define LCD_FIFOCTRL_F1REQ (0x1F<<8)
-#define LCD_FIFOCTRL_F0IF (1<<29)
-#define LCD_FIFOCTRL_F0REQ (0x1F<<0)
-#define LCD_FIFOCTRL_F3REQ_N(N) ((N-1)<<24)
-#define LCD_FIFOCTRL_F2REQ_N(N) ((N-1)<<16)
-#define LCD_FIFOCTRL_F1REQ_N(N) ((N-1)<<8)
-#define LCD_FIFOCTRL_F0REQ_N(N) ((N-1)<<0)
-
-/* lcd_outmask */
-#define LCD_OUTMASK_MASK (0x00FFFFFF)
-
-/********************************************************************/
-#endif /* _AU1200LCD_H */
diff --git a/drivers/video/fbdev/auo_k190x.c b/drivers/video/fbdev/auo_k190x.c
index 1e383c547633..9d24d1b3e9ef 100644
--- a/drivers/video/fbdev/auo_k190x.c
+++ b/drivers/video/fbdev/auo_k190x.c
@@ -1056,13 +1056,12 @@ int auok190x_common_probe(struct platform_device *pdev,
/* videomemory handling */
videomemorysize = roundup((panel->w * panel->h) * 2, PAGE_SIZE);
- videomemory = vmalloc(videomemorysize);
+ videomemory = vzalloc(videomemorysize);
if (!videomemory) {
ret = -ENOMEM;
goto err_irq;
}
- memset(videomemory, 0, videomemorysize);
info->screen_base = (char *)videomemory;
info->fix.smem_len = videomemorysize;
diff --git a/drivers/video/fbdev/intelfb/intelfbhw.c b/drivers/video/fbdev/intelfb/intelfbhw.c
index 83fec573cceb..57aff7450bce 100644
--- a/drivers/video/fbdev/intelfb/intelfbhw.c
+++ b/drivers/video/fbdev/intelfb/intelfbhw.c
@@ -181,7 +181,9 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
return 1;
/* Find the bridge device. It is always 0:0.0 */
- if (!(bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)))) {
+ bridge_dev = pci_get_domain_bus_and_slot(pci_domain_nr(pdev->bus), 0,
+ PCI_DEVFN(0, 0));
+ if (!bridge_dev) {
ERR_MSG("cannot find bridge device\n");
return 1;
}
diff --git a/drivers/video/fbdev/mmp/core.c b/drivers/video/fbdev/mmp/core.c
index a0f496049db7..3a6bb6561ba0 100644
--- a/drivers/video/fbdev/mmp/core.c
+++ b/drivers/video/fbdev/mmp/core.c
@@ -23,6 +23,7 @@
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/export.h>
+#include <linux/module.h>
#include <video/mmp_disp.h>
static struct mmp_overlay *path_get_overlay(struct mmp_path *path,
@@ -249,3 +250,7 @@ void mmp_unregister_path(struct mmp_path *path)
mutex_unlock(&disp_lock);
}
EXPORT_SYMBOL_GPL(mmp_unregister_path);
+
+MODULE_AUTHOR("Zhou Zhu <zzhu3@marvell.com>");
+MODULE_DESCRIPTION("Marvell MMP display framework");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c
index 79b1dc7f042b..246bea3a7d9b 100644
--- a/drivers/video/fbdev/mxsfb.c
+++ b/drivers/video/fbdev/mxsfb.c
@@ -169,7 +169,6 @@ struct mxsfb_devdata {
};
struct mxsfb_info {
- struct fb_info fb_info;
struct platform_device *pdev;
struct clk *clk;
struct clk *clk_axi;
@@ -208,8 +207,6 @@ static const struct mxsfb_devdata mxsfb_devdata[] = {
},
};
-#define to_imxfb_host(x) (container_of(x, struct mxsfb_info, fb_info))
-
/* mask and shift depends on architecture */
static inline u32 set_hsync_pulse_width(struct mxsfb_info *host, unsigned val)
{
@@ -269,7 +266,7 @@ static inline unsigned chan_to_field(unsigned chan, struct fb_bitfield *bf)
static int mxsfb_check_var(struct fb_var_screeninfo *var,
struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
const struct fb_bitfield *rgb = NULL;
if (var->xres < MIN_XRES)
@@ -330,7 +327,7 @@ static inline void mxsfb_disable_axi_clk(struct mxsfb_info *host)
static void mxsfb_enable_controller(struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
u32 reg;
int ret;
@@ -367,7 +364,7 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
static void mxsfb_disable_controller(struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
unsigned loop;
u32 reg;
int ret;
@@ -409,7 +406,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
static int mxsfb_set_par(struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
u32 ctrl, vdctrl0, vdctrl4;
int line_size, fb_size;
int reenable = 0;
@@ -569,7 +566,7 @@ static int mxsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
static int mxsfb_blank(int blank, struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
switch (blank) {
case FB_BLANK_POWERDOWN:
@@ -591,7 +588,7 @@ static int mxsfb_blank(int blank, struct fb_info *fb_info)
static int mxsfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fb_info)
{
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
unsigned offset;
if (var->xoffset != 0)
@@ -622,10 +619,10 @@ static struct fb_ops mxsfb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static int mxsfb_restore_mode(struct mxsfb_info *host,
+static int mxsfb_restore_mode(struct fb_info *fb_info,
struct fb_videomode *vmode)
{
- struct fb_info *fb_info = &host->fb_info;
+ struct mxsfb_info *host = fb_info->par;
unsigned line_count;
unsigned period;
unsigned long pa, fbsize;
@@ -726,10 +723,10 @@ err:
return ret;
}
-static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host,
+static int mxsfb_init_fbinfo_dt(struct fb_info *fb_info,
struct fb_videomode *vmode)
{
- struct fb_info *fb_info = &host->fb_info;
+ struct mxsfb_info *host = fb_info->par;
struct fb_var_screeninfo *var = &fb_info->var;
struct device *dev = &host->pdev->dev;
struct device_node *np = host->pdev->dev.of_node;
@@ -805,12 +802,12 @@ put_display_node:
return ret;
}
-static int mxsfb_init_fbinfo(struct mxsfb_info *host,
+static int mxsfb_init_fbinfo(struct fb_info *fb_info,
struct fb_videomode *vmode)
{
int ret;
+ struct mxsfb_info *host = fb_info->par;
struct device *dev = &host->pdev->dev;
- struct fb_info *fb_info = &host->fb_info;
struct fb_var_screeninfo *var = &fb_info->var;
dma_addr_t fb_phys;
void *fb_virt;
@@ -824,7 +821,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host,
fb_info->fix.visual = FB_VISUAL_TRUECOLOR,
fb_info->fix.accel = FB_ACCEL_NONE;
- ret = mxsfb_init_fbinfo_dt(host, vmode);
+ ret = mxsfb_init_fbinfo_dt(fb_info, vmode);
if (ret)
return ret;
@@ -843,16 +840,16 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host,
fb_info->screen_base = fb_virt;
fb_info->screen_size = fb_info->fix.smem_len = fb_size;
- if (mxsfb_restore_mode(host, vmode))
+ if (mxsfb_restore_mode(fb_info, vmode))
memset(fb_virt, 0, fb_size);
return 0;
}
-static void mxsfb_free_videomem(struct mxsfb_info *host)
+static void mxsfb_free_videomem(struct fb_info *fb_info)
{
+ struct mxsfb_info *host = fb_info->par;
struct device *dev = &host->pdev->dev;
- struct fb_info *fb_info = &host->fb_info;
dma_free_wc(dev, fb_info->screen_size, fb_info->screen_base,
fb_info->fix.smem_start);
@@ -902,7 +899,7 @@ static int mxsfb_probe(struct platform_device *pdev)
if (mode == NULL)
return -ENOMEM;
- host = to_imxfb_host(fb_info);
+ host = fb_info->par;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
host->base = devm_ioremap_resource(&pdev->dev, res);
@@ -941,7 +938,7 @@ static int mxsfb_probe(struct platform_device *pdev)
goto fb_release;
}
- ret = mxsfb_init_fbinfo(host, mode);
+ ret = mxsfb_init_fbinfo(fb_info, mode);
if (ret != 0)
goto fb_release;
@@ -982,13 +979,13 @@ fb_release:
static int mxsfb_remove(struct platform_device *pdev)
{
struct fb_info *fb_info = platform_get_drvdata(pdev);
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
if (host->enabled)
mxsfb_disable_controller(fb_info);
unregister_framebuffer(fb_info);
- mxsfb_free_videomem(host);
+ mxsfb_free_videomem(fb_info);
framebuffer_release(fb_info);
@@ -998,7 +995,7 @@ static int mxsfb_remove(struct platform_device *pdev)
static void mxsfb_shutdown(struct platform_device *pdev)
{
struct fb_info *fb_info = platform_get_drvdata(pdev);
- struct mxsfb_info *host = to_imxfb_host(fb_info);
+ struct mxsfb_info *host = fb_info->par;
mxsfb_enable_axi_clk(host);
diff --git a/drivers/video/fbdev/nvidia/nv_hw.c b/drivers/video/fbdev/nvidia/nv_hw.c
index 81c80ac3c76f..8335da4ca30e 100644
--- a/drivers/video/fbdev/nvidia/nv_hw.c
+++ b/drivers/video/fbdev/nvidia/nv_hw.c
@@ -683,10 +683,11 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
nv10_sim_state sim_data;
unsigned int M, N, P, pll, MClk, NVClk, memctrl;
struct pci_dev *dev;
+ int domain = pci_domain_nr(par->pci_dev->bus);
if ((par->Chipset & 0x0FF0) == 0x01A0) {
unsigned int uMClkPostDiv;
- dev = pci_get_bus_and_slot(0, 3);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 3);
pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
@@ -694,7 +695,7 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
uMClkPostDiv = 4;
MClk = 400000 / uMClkPostDiv;
} else {
- dev = pci_get_bus_and_slot(0, 5);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 5);
pci_read_config_dword(dev, 0x4c, &MClk);
MClk /= 1000;
}
@@ -707,13 +708,13 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
sim_data.pix_bpp = (char)pixelDepth;
sim_data.enable_video = 0;
sim_data.enable_mp = 0;
- dev = pci_get_bus_and_slot(0, 1);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 1);
pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
pci_dev_put(dev);
sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
sim_data.memory_width = 64;
- dev = pci_get_bus_and_slot(0, 3);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 3);
pci_read_config_dword(dev, 0, &memctrl);
pci_dev_put(dev);
memctrl >>= 16;
@@ -721,7 +722,7 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
u32 dimm[3];
- dev = pci_get_bus_and_slot(0, 2);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 2);
pci_read_config_dword(dev, 0x40, &dimm[0]);
dimm[0] = (dimm[0] >> 8) & 0x4f;
pci_read_config_dword(dev, 0x44, &dimm[1]);
diff --git a/drivers/video/fbdev/nvidia/nv_setup.c b/drivers/video/fbdev/nvidia/nv_setup.c
index 2f2e162134fa..b17acd290360 100644
--- a/drivers/video/fbdev/nvidia/nv_setup.c
+++ b/drivers/video/fbdev/nvidia/nv_setup.c
@@ -264,7 +264,8 @@ static void nv10GetConfig(struct nvidia_par *par)
}
#endif
- dev = pci_get_bus_and_slot(0, 1);
+ dev = pci_get_domain_bus_and_slot(pci_domain_nr(par->pci_dev->bus),
+ 0, 1);
if ((par->Chipset & 0xffff) == 0x01a0) {
u32 amt;
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dispc.c b/drivers/video/fbdev/omap2/omapfb/dss/dispc.c
index 7a75dfda9845..fb605aefd9b1 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dispc.c
@@ -3976,52 +3976,33 @@ static const struct dispc_features omap54xx_dispc_feats = {
.has_writeback = true,
};
-static int dispc_init_features(struct platform_device *pdev)
+static const struct dispc_features *dispc_get_features(void)
{
- const struct dispc_features *src;
- struct dispc_features *dst;
-
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (!dst) {
- dev_err(&pdev->dev, "Failed to allocate DISPC Features\n");
- return -ENOMEM;
- }
-
switch (omapdss_get_version()) {
case OMAPDSS_VER_OMAP24xx:
- src = &omap24xx_dispc_feats;
- break;
+ return &omap24xx_dispc_feats;
case OMAPDSS_VER_OMAP34xx_ES1:
- src = &omap34xx_rev1_0_dispc_feats;
- break;
+ return &omap34xx_rev1_0_dispc_feats;
case OMAPDSS_VER_OMAP34xx_ES3:
case OMAPDSS_VER_OMAP3630:
case OMAPDSS_VER_AM35xx:
case OMAPDSS_VER_AM43xx:
- src = &omap34xx_rev3_0_dispc_feats;
- break;
+ return &omap34xx_rev3_0_dispc_feats;
case OMAPDSS_VER_OMAP4430_ES1:
case OMAPDSS_VER_OMAP4430_ES2:
case OMAPDSS_VER_OMAP4:
- src = &omap44xx_dispc_feats;
- break;
+ return &omap44xx_dispc_feats;
case OMAPDSS_VER_OMAP5:
case OMAPDSS_VER_DRA7xx:
- src = &omap54xx_dispc_feats;
- break;
+ return &omap54xx_dispc_feats;
default:
- return -ENODEV;
+ return NULL;
}
-
- memcpy(dst, src, sizeof(*dst));
- dispc.feat = dst;
-
- return 0;
}
static irqreturn_t dispc_irq_handler(int irq, void *arg)
@@ -4078,9 +4059,9 @@ static int dispc_bind(struct device *dev, struct device *master, void *data)
spin_lock_init(&dispc.control_lock);
- r = dispc_init_features(dispc.pdev);
- if (r)
- return r;
+ dispc.feat = dispc_get_features();
+ if (!dispc.feat)
+ return -ENODEV;
dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
if (!dispc_mem) {
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss.c b/drivers/video/fbdev/omap2/omapfb/dss/dss.c
index 48c6500c24e1..39fe7247ff98 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dss.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dss.c
@@ -887,58 +887,37 @@ static const struct dss_features dra7xx_dss_feats = {
.num_ports = ARRAY_SIZE(dra7xx_ports),
};
-static int dss_init_features(struct platform_device *pdev)
+static const struct dss_features *dss_get_features(void)
{
- const struct dss_features *src;
- struct dss_features *dst;
-
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (!dst) {
- dev_err(&pdev->dev, "Failed to allocate local DSS Features\n");
- return -ENOMEM;
- }
-
switch (omapdss_get_version()) {
case OMAPDSS_VER_OMAP24xx:
- src = &omap24xx_dss_feats;
- break;
+ return &omap24xx_dss_feats;
case OMAPDSS_VER_OMAP34xx_ES1:
case OMAPDSS_VER_OMAP34xx_ES3:
case OMAPDSS_VER_AM35xx:
- src = &omap34xx_dss_feats;
- break;
+ return &omap34xx_dss_feats;
case OMAPDSS_VER_OMAP3630:
- src = &omap3630_dss_feats;
- break;
+ return &omap3630_dss_feats;
case OMAPDSS_VER_OMAP4430_ES1:
case OMAPDSS_VER_OMAP4430_ES2:
case OMAPDSS_VER_OMAP4:
- src = &omap44xx_dss_feats;
- break;
+ return &omap44xx_dss_feats;
case OMAPDSS_VER_OMAP5:
- src = &omap54xx_dss_feats;
- break;
+ return &omap54xx_dss_feats;
case OMAPDSS_VER_AM43xx:
- src = &am43xx_dss_feats;
- break;
+ return &am43xx_dss_feats;
case OMAPDSS_VER_DRA7xx:
- src = &dra7xx_dss_feats;
- break;
+ return &dra7xx_dss_feats;
default:
- return -ENODEV;
+ return NULL;
}
-
- memcpy(dst, src, sizeof(*dst));
- dss.feat = dst;
-
- return 0;
}
static void dss_uninit_ports(struct platform_device *pdev);
@@ -1104,9 +1083,9 @@ static int dss_bind(struct device *dev)
dss.pdev = pdev;
- r = dss_init_features(dss.pdev);
- if (r)
- return r;
+ dss.feat = dss_get_features();
+ if (!dss.feat)
+ return -ENODEV;
dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
if (!dss_mem) {
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
index ec78d61bc551..28de56e21c74 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c
@@ -673,10 +673,7 @@ static int hdmi_audio_register(struct device *dev)
dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
&pdata, sizeof(pdata));
- if (IS_ERR(hdmi.audio_pdev))
- return PTR_ERR(hdmi.audio_pdev);
-
- return 0;
+ return PTR_ERR_OR_ZERO(hdmi.audio_pdev);
}
/* HDMI HW IP initialisation */
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/omapfb/dss/hdmi_phy.c
index 9a13c35fd6d8..eee09b4bdcf6 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/hdmi_phy.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/hdmi_phy.c
@@ -189,47 +189,30 @@ static const struct hdmi_phy_features omap54xx_phy_feats = {
.max_phy = 186000000,
};
-static int hdmi_phy_init_features(struct platform_device *pdev)
+static const struct hdmi_phy_features *hdmi_phy_get_features(void)
{
- struct hdmi_phy_features *dst;
- const struct hdmi_phy_features *src;
-
- dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
- if (!dst) {
- dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n");
- return -ENOMEM;
- }
-
switch (omapdss_get_version()) {
case OMAPDSS_VER_OMAP4430_ES1:
case OMAPDSS_VER_OMAP4430_ES2:
case OMAPDSS_VER_OMAP4:
- src = &omap44xx_phy_feats;
- break;
+ return &omap44xx_phy_feats;
case OMAPDSS_VER_OMAP5:
case OMAPDSS_VER_DRA7xx:
- src = &omap54xx_phy_feats;
- break;
+ return &omap54xx_phy_feats;
default:
- return -ENODEV;
+ return NULL;
}
-
- memcpy(dst, src, sizeof(*dst));
- phy_feat = dst;
-
- return 0;
}
int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy)
{
- int r;
struct resource *res;
- r = hdmi_phy_init_features(pdev);
- if (r)
- return r;
+ phy_feat = hdmi_phy_get_features();
+ if (!phy_feat)
+ return -ENODEV;
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
if (!res) {
diff --git a/drivers/video/fbdev/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c
index 55fbb432c053..0955622a1227 100644
--- a/drivers/video/fbdev/pxa3xx-gcu.c
+++ b/drivers/video/fbdev/pxa3xx-gcu.c
@@ -104,7 +104,7 @@ struct pxa3xx_gcu_priv {
wait_queue_head_t wait_idle;
wait_queue_head_t wait_free;
spinlock_t spinlock;
- struct timeval base_time;
+ struct timespec64 base_time;
struct pxa3xx_gcu_batch *free;
struct pxa3xx_gcu_batch *ready;
@@ -126,18 +126,20 @@ gc_writel(struct pxa3xx_gcu_priv *priv, unsigned int off, unsigned long val)
#define QPRINT(priv, level, msg) \
do { \
- struct timeval tv; \
+ struct timespec64 ts; \
struct pxa3xx_gcu_shared *shared = priv->shared; \
u32 base = gc_readl(priv, REG_GCRBBR); \
\
- do_gettimeofday(&tv); \
+ ktime_get_ts64(&ts); \
+ ts = timespec64_sub(ts, priv->base_time); \
\
- printk(level "%ld.%03ld.%03ld - %-17s: %-21s (%s, " \
+ printk(level "%lld.%03ld.%03ld - %-17s: %-21s (%s, " \
"STATUS " \
"0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, " \
"T %5ld)\n", \
- tv.tv_sec - priv->base_time.tv_sec, \
- tv.tv_usec / 1000, tv.tv_usec % 1000, \
+ (s64)(ts.tv_sec), \
+ ts.tv_nsec / NSEC_PER_MSEC, \
+ (ts.tv_nsec % NSEC_PER_MSEC) / USEC_PER_MSEC, \
__func__, msg, \
shared->hw_running ? "running" : " idle", \
gc_readl(priv, REG_GCISCR), \
@@ -164,7 +166,7 @@ pxa3xx_gcu_reset(struct pxa3xx_gcu_priv *priv)
priv->shared->buffer_phys = priv->shared_phys;
priv->shared->magic = PXA3XX_GCU_SHARED_MAGIC;
- do_gettimeofday(&priv->base_time);
+ ktime_get_ts64(&priv->base_time);
/* set up the ring buffer pointers */
gc_writel(priv, REG_GCRBLR, 0);
diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c
index 1ea78bb911fb..ff8282374f37 100644
--- a/drivers/video/fbdev/riva/fbdev.c
+++ b/drivers/video/fbdev/riva/fbdev.c
@@ -780,7 +780,7 @@ static int riva_load_video_mode(struct fb_info *info)
else
newmode.misc_output |= 0x80;
- rc = CalcStateExt(&par->riva, &newmode.ext, bpp, width,
+ rc = CalcStateExt(&par->riva, &newmode.ext, par->pdev, bpp, width,
hDisplaySize, height, dotClock);
if (rc)
goto out;
diff --git a/drivers/video/fbdev/riva/nv_driver.c b/drivers/video/fbdev/riva/nv_driver.c
index f3694cf17e58..a3d9c66973ad 100644
--- a/drivers/video/fbdev/riva/nv_driver.c
+++ b/drivers/video/fbdev/riva/nv_driver.c
@@ -159,6 +159,7 @@ unsigned long riva_get_memlen(struct riva_par *par)
unsigned int chipset = par->Chipset;
struct pci_dev* dev;
u32 amt;
+ int domain = pci_domain_nr(par->pdev->bus);
switch (chip->Architecture) {
case NV_ARCH_03:
@@ -226,12 +227,12 @@ unsigned long riva_get_memlen(struct riva_par *par)
case NV_ARCH_30:
if(chipset == NV_CHIP_IGEFORCE2) {
- dev = pci_get_bus_and_slot(0, 1);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 1);
pci_read_config_dword(dev, 0x7C, &amt);
pci_dev_put(dev);
memlen = (((amt >> 6) & 31) + 1) * 1024;
} else if (chipset == NV_CHIP_0x01F0) {
- dev = pci_get_bus_and_slot(0, 1);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 1);
pci_read_config_dword(dev, 0x84, &amt);
pci_dev_put(dev);
memlen = (((amt >> 4) & 127) + 1) * 1024;
@@ -417,6 +418,6 @@ riva_common_setup(struct riva_par *par)
}
par->riva.flatPanel = (par->FlatPanel > 0) ? TRUE : FALSE;
- RivaGetConfig(&par->riva, par->Chipset);
+ RivaGetConfig(&par->riva, par->pdev, par->Chipset);
}
diff --git a/drivers/video/fbdev/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c
index 8bdf37f3013b..0601c13f2105 100644
--- a/drivers/video/fbdev/riva/riva_hw.c
+++ b/drivers/video/fbdev/riva/riva_hw.c
@@ -1108,7 +1108,8 @@ static void nForceUpdateArbitrationSettings
unsigned pixelDepth,
unsigned *burst,
unsigned *lwm,
- RIVA_HW_INST *chip
+ RIVA_HW_INST *chip,
+ struct pci_dev *pdev
)
{
nv10_fifo_info fifo_data;
@@ -1116,8 +1117,9 @@ static void nForceUpdateArbitrationSettings
unsigned int M, N, P, pll, MClk, NVClk;
unsigned int uMClkPostDiv;
struct pci_dev *dev;
+ int domain = pci_domain_nr(pdev->bus);
- dev = pci_get_bus_and_slot(0, 3);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 3);
pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
pci_dev_put(dev);
uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
@@ -1132,7 +1134,7 @@ static void nForceUpdateArbitrationSettings
sim_data.enable_video = 0;
sim_data.enable_mp = 0;
- dev = pci_get_bus_and_slot(0, 1);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 1);
pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
pci_dev_put(dev);
sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
@@ -1234,6 +1236,7 @@ int CalcStateExt
(
RIVA_HW_INST *chip,
RIVA_HW_STATE *state,
+ struct pci_dev *pdev,
int bpp,
int width,
int hDisplaySize,
@@ -1300,7 +1303,7 @@ int CalcStateExt
pixelDepth * 8,
&(state->arbitration0),
&(state->arbitration1),
- chip);
+ chip, pdev);
} else {
nv10UpdateArbitrationSettings(VClk,
pixelDepth * 8,
@@ -2102,10 +2105,12 @@ static void nv4GetConfig
static void nv10GetConfig
(
RIVA_HW_INST *chip,
+ struct pci_dev *pdev,
unsigned int chipset
)
{
struct pci_dev* dev;
+ int domain = pci_domain_nr(pdev->bus);
u32 amt;
#ifdef __BIG_ENDIAN
@@ -2118,12 +2123,12 @@ static void nv10GetConfig
* Fill in chip configuration.
*/
if(chipset == NV_CHIP_IGEFORCE2) {
- dev = pci_get_bus_and_slot(0, 1);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 1);
pci_read_config_dword(dev, 0x7C, &amt);
pci_dev_put(dev);
chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
} else if(chipset == NV_CHIP_0x01F0) {
- dev = pci_get_bus_and_slot(0, 1);
+ dev = pci_get_domain_bus_and_slot(domain, 0, 1);
pci_read_config_dword(dev, 0x84, &amt);
pci_dev_put(dev);
chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
@@ -2224,6 +2229,7 @@ static void nv10GetConfig
int RivaGetConfig
(
RIVA_HW_INST *chip,
+ struct pci_dev *pdev,
unsigned int chipset
)
{
@@ -2245,7 +2251,7 @@ int RivaGetConfig
case NV_ARCH_10:
case NV_ARCH_20:
case NV_ARCH_30:
- nv10GetConfig(chip, chipset);
+ nv10GetConfig(chip, pdev, chipset);
break;
default:
return (-1);
diff --git a/drivers/video/fbdev/riva/riva_hw.h b/drivers/video/fbdev/riva/riva_hw.h
index c2769f73e0b2..5e7b35466b00 100644
--- a/drivers/video/fbdev/riva/riva_hw.h
+++ b/drivers/video/fbdev/riva/riva_hw.h
@@ -536,6 +536,7 @@ extern int CalcStateExt
(
RIVA_HW_INST *chip,
RIVA_HW_STATE *state,
+ struct pci_dev *pdev,
int bpp,
int width,
int hDisplaySize,
@@ -546,7 +547,7 @@ extern int CalcStateExt
/*
* External routines.
*/
-int RivaGetConfig(RIVA_HW_INST *, unsigned int);
+int RivaGetConfig(RIVA_HW_INST *chip, struct pci_dev *pdev, unsigned int c);
/*
* FIFO Free Count. Should attempt to yield processor if RIVA is busy.
*/
diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index 2275e80b5776..8db7085e5d1a 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1086,8 +1086,7 @@ static int ufx_ops_open(struct fb_info *info, int user)
struct fb_deferred_io *fbdefio;
- fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL);
-
+ fbdefio = kzalloc(sizeof(*fbdefio), GFP_KERNEL);
if (fbdefio) {
fbdefio->delay = UFX_DEFIO_WRITE_DELAY;
fbdefio->deferred_io = ufx_dpy_deferred_io;
@@ -1875,7 +1874,7 @@ static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size)
INIT_LIST_HEAD(&dev->urbs.list);
while (i < count) {
- unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL);
+ unode = kzalloc(sizeof(*unode), GFP_KERNEL);
if (!unode)
break;
unode->dev = dev;
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
index d44f14242016..452a4207ac1b 100644
--- a/drivers/video/fbdev/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
@@ -16,8 +16,6 @@
* from Florian Echtler, Henrik Bjerregaard Pedersen, and others.
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -32,7 +30,7 @@
#include <video/udlfb.h>
#include "edid.h"
-static struct fb_fix_screeninfo dlfb_fix = {
+static const struct fb_fix_screeninfo dlfb_fix = {
.id = "udlfb",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_TRUECOLOR,
@@ -76,10 +74,10 @@ static int pixel_limit; /* Optionally force a pixel resolution limit */
/* dlfb keeps a list of urbs for efficient bulk transfers */
static void dlfb_urb_completion(struct urb *urb);
-static struct urb *dlfb_get_urb(struct dlfb_data *dev);
-static int dlfb_submit_urb(struct dlfb_data *dev, struct urb * urb, size_t len);
-static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size);
-static void dlfb_free_urb_list(struct dlfb_data *dev);
+static struct urb *dlfb_get_urb(struct dlfb_data *dlfb);
+static int dlfb_submit_urb(struct dlfb_data *dlfb, struct urb * urb, size_t len);
+static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size);
+static void dlfb_free_urb_list(struct dlfb_data *dlfb);
/*
* All DisplayLink bulk operations start with 0xAF, followed by specific code
@@ -274,7 +272,7 @@ static char *dlfb_set_vid_cmds(char *wrptr, struct fb_var_screeninfo *var)
* and then generates the appropriate command sequence that then drives the
* display controller.
*/
-static int dlfb_set_video_mode(struct dlfb_data *dev,
+static int dlfb_set_video_mode(struct dlfb_data *dlfb,
struct fb_var_screeninfo *var)
{
char *buf;
@@ -283,10 +281,10 @@ static int dlfb_set_video_mode(struct dlfb_data *dev,
int writesize;
struct urb *urb;
- if (!atomic_read(&dev->usb_active))
+ if (!atomic_read(&dlfb->usb_active))
return -EPERM;
- urb = dlfb_get_urb(dev);
+ urb = dlfb_get_urb(dlfb);
if (!urb)
return -ENOMEM;
@@ -302,7 +300,7 @@ static int dlfb_set_video_mode(struct dlfb_data *dev,
/* set base for 16bpp segment to 0 */
wrptr = dlfb_set_base16bpp(wrptr, 0);
/* set base for 8bpp segment to end of fb */
- wrptr = dlfb_set_base8bpp(wrptr, dev->info->fix.smem_len);
+ wrptr = dlfb_set_base8bpp(wrptr, dlfb->info->fix.smem_len);
wrptr = dlfb_set_vid_cmds(wrptr, var);
wrptr = dlfb_blanking(wrptr, FB_BLANK_UNBLANK);
@@ -310,9 +308,9 @@ static int dlfb_set_video_mode(struct dlfb_data *dev,
writesize = wrptr - buf;
- retval = dlfb_submit_urb(dev, urb, writesize);
+ retval = dlfb_submit_urb(dlfb, urb, writesize);
- dev->blank_mode = FB_BLANK_UNBLANK;
+ dlfb->blank_mode = FB_BLANK_UNBLANK;
return retval;
}
@@ -333,8 +331,8 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
pos = (unsigned long)info->fix.smem_start + offset;
- pr_notice("mmap() framebuffer addr:%lu size:%lu\n",
- pos, size);
+ dev_dbg(info->dev, "mmap() framebuffer addr:%lu size:%lu\n",
+ pos, size);
while (size > 0) {
page = vmalloc_to_pfn((void *)pos);
@@ -505,8 +503,6 @@ static void dlfb_compress_hline(
*command_buffer_ptr = cmd;
*pixel_start_ptr = pixel;
*device_address_ptr = dev_addr;
-
- return;
}
/*
@@ -515,13 +511,13 @@ static void dlfb_compress_hline(
* (that we can only write to, slowly, and can never read), and (optionally)
* our shadow copy that tracks what's been sent to that hardware buffer.
*/
-static int dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
+static int dlfb_render_hline(struct dlfb_data *dlfb, struct urb **urb_ptr,
const char *front, char **urb_buf_ptr,
u32 byte_offset, u32 byte_width,
int *ident_ptr, int *sent_ptr)
{
const u8 *line_start, *line_end, *next_pixel;
- u32 dev_addr = dev->base16 + byte_offset;
+ u32 dev_addr = dlfb->base16 + byte_offset;
struct urb *urb = *urb_ptr;
u8 *cmd = *urb_buf_ptr;
u8 *cmd_end = (u8 *) urb->transfer_buffer + urb->transfer_buffer_length;
@@ -530,9 +526,9 @@ static int dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
next_pixel = line_start;
line_end = next_pixel + byte_width;
- if (dev->backing_buffer) {
+ if (dlfb->backing_buffer) {
int offset;
- const u8 *back_start = (u8 *) (dev->backing_buffer
+ const u8 *back_start = (u8 *) (dlfb->backing_buffer
+ byte_offset);
*ident_ptr += dlfb_trim_hline(back_start, &next_pixel,
@@ -556,10 +552,10 @@ static int dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
if (cmd >= cmd_end) {
int len = cmd - (u8 *) urb->transfer_buffer;
- if (dlfb_submit_urb(dev, urb, len))
+ if (dlfb_submit_urb(dlfb, urb, len))
return 1; /* lost pixels is set */
*sent_ptr += len;
- urb = dlfb_get_urb(dev);
+ urb = dlfb_get_urb(dlfb);
if (!urb)
return 1; /* lost_pixels is set */
*urb_ptr = urb;
@@ -573,7 +569,7 @@ static int dlfb_render_hline(struct dlfb_data *dev, struct urb **urb_ptr,
return 0;
}
-static int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
+static int dlfb_handle_damage(struct dlfb_data *dlfb, int x, int y,
int width, int height, char *data)
{
int i, ret;
@@ -591,24 +587,24 @@ static int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
x = aligned_x;
if ((width <= 0) ||
- (x + width > dev->info->var.xres) ||
- (y + height > dev->info->var.yres))
+ (x + width > dlfb->info->var.xres) ||
+ (y + height > dlfb->info->var.yres))
return -EINVAL;
- if (!atomic_read(&dev->usb_active))
+ if (!atomic_read(&dlfb->usb_active))
return 0;
- urb = dlfb_get_urb(dev);
+ urb = dlfb_get_urb(dlfb);
if (!urb)
return 0;
cmd = urb->transfer_buffer;
for (i = y; i < y + height ; i++) {
- const int line_offset = dev->info->fix.line_length * i;
+ const int line_offset = dlfb->info->fix.line_length * i;
const int byte_offset = line_offset + (x * BPP);
- if (dlfb_render_hline(dev, &urb,
- (char *) dev->info->fix.smem_start,
+ if (dlfb_render_hline(dlfb, &urb,
+ (char *) dlfb->info->fix.smem_start,
&cmd, byte_offset, width * BPP,
&bytes_identical, &bytes_sent))
goto error;
@@ -617,19 +613,19 @@ static int dlfb_handle_damage(struct dlfb_data *dev, int x, int y,
if (cmd > (char *) urb->transfer_buffer) {
/* Send partial buffer remaining before exiting */
int len = cmd - (char *) urb->transfer_buffer;
- ret = dlfb_submit_urb(dev, urb, len);
+ ret = dlfb_submit_urb(dlfb, urb, len);
bytes_sent += len;
} else
dlfb_urb_completion(urb);
error:
- atomic_add(bytes_sent, &dev->bytes_sent);
- atomic_add(bytes_identical, &dev->bytes_identical);
- atomic_add(width*height*2, &dev->bytes_rendered);
+ atomic_add(bytes_sent, &dlfb->bytes_sent);
+ atomic_add(bytes_identical, &dlfb->bytes_identical);
+ atomic_add(width*height*2, &dlfb->bytes_rendered);
end_cycles = get_cycles();
atomic_add(((unsigned int) ((end_cycles - start_cycles)
>> 10)), /* Kcycles */
- &dev->cpu_kcycles_used);
+ &dlfb->cpu_kcycles_used);
return 0;
}
@@ -644,7 +640,7 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos)
{
ssize_t result;
- struct dlfb_data *dev = info->par;
+ struct dlfb_data *dlfb = info->par;
u32 offset = (u32) *ppos;
result = fb_sys_write(info, buf, count, ppos);
@@ -654,7 +650,7 @@ static ssize_t dlfb_ops_write(struct fb_info *info, const char __user *buf,
int lines = min((u32)((result / info->fix.line_length) + 1),
(u32)info->var.yres);
- dlfb_handle_damage(dev, 0, start, info->var.xres,
+ dlfb_handle_damage(dlfb, 0, start, info->var.xres,
lines, info->screen_base);
}
@@ -666,33 +662,33 @@ static void dlfb_ops_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
- struct dlfb_data *dev = info->par;
+ struct dlfb_data *dlfb = info->par;
sys_copyarea(info, area);
- dlfb_handle_damage(dev, area->dx, area->dy,
+ dlfb_handle_damage(dlfb, area->dx, area->dy,
area->width, area->height, info->screen_base);
}
static void dlfb_ops_imageblit(struct fb_info *info,
const struct fb_image *image)
{
- struct dlfb_data *dev = info->par;
+ struct dlfb_data *dlfb = info->par;
sys_imageblit(info, image);
- dlfb_handle_damage(dev, image->dx, image->dy,
+ dlfb_handle_damage(dlfb, image->dx, image->dy,
image->width, image->height, info->screen_base);
}
static void dlfb_ops_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
- struct dlfb_data *dev = info->par;
+ struct dlfb_data *dlfb = info->par;
sys_fillrect(info, rect);
- dlfb_handle_damage(dev, rect->dx, rect->dy, rect->width,
+ dlfb_handle_damage(dlfb, rect->dx, rect->dy, rect->width,
rect->height, info->screen_base);
}
@@ -707,7 +703,7 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
{
struct page *cur;
struct fb_deferred_io *fbdefio = info->fbdefio;
- struct dlfb_data *dev = info->par;
+ struct dlfb_data *dlfb = info->par;
struct urb *urb;
char *cmd;
cycles_t start_cycles, end_cycles;
@@ -718,12 +714,12 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
if (!fb_defio)
return;
- if (!atomic_read(&dev->usb_active))
+ if (!atomic_read(&dlfb->usb_active))
return;
start_cycles = get_cycles();
- urb = dlfb_get_urb(dev);
+ urb = dlfb_get_urb(dlfb);
if (!urb)
return;
@@ -732,7 +728,7 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
/* walk the written page list and render each to device */
list_for_each_entry(cur, &fbdefio->pagelist, lru) {
- if (dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start,
+ if (dlfb_render_hline(dlfb, &urb, (char *) info->fix.smem_start,
&cmd, cur->index << PAGE_SHIFT,
PAGE_SIZE, &bytes_identical, &bytes_sent))
goto error;
@@ -742,25 +738,24 @@ static void dlfb_dpy_deferred_io(struct fb_info *info,
if (cmd > (char *) urb->transfer_buffer) {
/* Send partial buffer remaining before exiting */
int len = cmd - (char *) urb->transfer_buffer;
- dlfb_submit_urb(dev, urb, len);
+ dlfb_submit_urb(dlfb, urb, len);
bytes_sent += len;
} else
dlfb_urb_completion(urb);
error:
- atomic_add(bytes_sent, &dev->bytes_sent);
- atomic_add(bytes_identical, &dev->bytes_identical);
- atomic_add(bytes_rendered, &dev->bytes_rendered);
+ atomic_add(bytes_sent, &dlfb->bytes_sent);
+ atomic_add(bytes_identical, &dlfb->bytes_identical);
+ atomic_add(bytes_rendered, &dlfb->bytes_rendered);
end_cycles = get_cycles();
atomic_add(((unsigned int) ((end_cycles - start_cycles)
>> 10)), /* Kcycles */
- &dev->cpu_kcycles_used);
+ &dlfb->cpu_kcycles_used);
}
-static int dlfb_get_edid(struct dlfb_data *dev, char *edid, int len)
+static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len)
{
- int i;
- int ret;
+ int i, ret;
char *rbuf;
rbuf = kmalloc(2, GFP_KERNEL);
@@ -768,12 +763,13 @@ static int dlfb_get_edid(struct dlfb_data *dev, char *edid, int len)
return 0;
for (i = 0; i < len; i++) {
- ret = usb_control_msg(dev->udev,
- usb_rcvctrlpipe(dev->udev, 0), 0x02,
+ ret = usb_control_msg(dlfb->udev,
+ usb_rcvctrlpipe(dlfb->udev, 0), 0x02,
(0x80 | (0x02 << 5)), i << 8, 0xA1,
rbuf, 2, USB_CTRL_GET_TIMEOUT);
if (ret < 2) {
- pr_err("Read EDID byte %d failed: %d\n", i, ret);
+ dev_err(&dlfb->udev->dev,
+ "Read EDID byte %d failed: %d\n", i, ret);
i--;
break;
}
@@ -789,15 +785,15 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
- struct dlfb_data *dev = info->par;
+ struct dlfb_data *dlfb = info->par;
- if (!atomic_read(&dev->usb_active))
+ if (!atomic_read(&dlfb->usb_active))
return 0;
/* TODO: Update X server to get this from sysfs instead */
if (cmd == DLFB_IOCTL_RETURN_EDID) {
void __user *edid = (void __user *)arg;
- if (copy_to_user(edid, dev->edid, dev->edid_size))
+ if (copy_to_user(edid, dlfb->edid, dlfb->edid_size))
return -EFAULT;
return 0;
}
@@ -832,7 +828,7 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
if (area.y > info->var.yres)
area.y = info->var.yres;
- dlfb_handle_damage(dev, area.x, area.y, area.w, area.h,
+ dlfb_handle_damage(dlfb, area.x, area.y, area.w, area.h,
info->screen_base);
}
@@ -873,7 +869,7 @@ dlfb_ops_setcolreg(unsigned regno, unsigned red, unsigned green,
*/
static int dlfb_ops_open(struct fb_info *info, int user)
{
- struct dlfb_data *dev = info->par;
+ struct dlfb_data *dlfb = info->par;
/*
* fbcon aggressively connects to first framebuffer it finds,
@@ -884,12 +880,12 @@ static int dlfb_ops_open(struct fb_info *info, int user)
return -EBUSY;
/* If the USB device is gone, we don't accept new opens */
- if (dev->virtualized)
+ if (dlfb->virtualized)
return -ENODEV;
- dev->fb_count++;
+ dlfb->fb_count++;
- kref_get(&dev->kref);
+ kref_get(&dlfb->kref);
if (fb_defio && (info->fbdefio == NULL)) {
/* enable defio at last moment if not disabled by client */
@@ -907,8 +903,8 @@ static int dlfb_ops_open(struct fb_info *info, int user)
fb_deferred_io_init(info);
}
- pr_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n",
- info->node, user, info, dev->fb_count);
+ dev_dbg(info->dev, "open, user=%d fb_info=%p count=%d\n",
+ user, info, dlfb->fb_count);
return 0;
}
@@ -920,15 +916,11 @@ static int dlfb_ops_open(struct fb_info *info, int user)
*/
static void dlfb_free(struct kref *kref)
{
- struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
+ struct dlfb_data *dlfb = container_of(kref, struct dlfb_data, kref);
- vfree(dev->backing_buffer);
-
- kfree(dev->edid);
-
- pr_warn("freeing dlfb_data %p\n", dev);
-
- kfree(dev);
+ vfree(dlfb->backing_buffer);
+ kfree(dlfb->edid);
+ kfree(dlfb);
}
static void dlfb_release_urb_work(struct work_struct *work)
@@ -936,16 +928,14 @@ static void dlfb_release_urb_work(struct work_struct *work)
struct urb_node *unode = container_of(work, struct urb_node,
release_urb_work.work);
- up(&unode->dev->urbs.limit_sem);
+ up(&unode->dlfb->urbs.limit_sem);
}
-static void dlfb_free_framebuffer(struct dlfb_data *dev)
+static void dlfb_free_framebuffer(struct dlfb_data *dlfb)
{
- struct fb_info *info = dev->info;
+ struct fb_info *info = dlfb->info;
if (info) {
- int node = info->node;
-
unregister_framebuffer(info);
if (info->cmap.len != 0)
@@ -956,48 +946,45 @@ static void dlfb_free_framebuffer(struct dlfb_data *dev)
fb_destroy_modelist(&info->modelist);
- dev->info = NULL;
+ dlfb->info = NULL;
/* Assume info structure is freed after this point */
framebuffer_release(info);
-
- pr_warn("fb_info for /dev/fb%d has been freed\n", node);
}
/* ref taken in probe() as part of registering framebfufer */
- kref_put(&dev->kref, dlfb_free);
+ kref_put(&dlfb->kref, dlfb_free);
}
static void dlfb_free_framebuffer_work(struct work_struct *work)
{
- struct dlfb_data *dev = container_of(work, struct dlfb_data,
+ struct dlfb_data *dlfb = container_of(work, struct dlfb_data,
free_framebuffer_work.work);
- dlfb_free_framebuffer(dev);
+ dlfb_free_framebuffer(dlfb);
}
/*
* Assumes caller is holding info->lock mutex (for open and release at least)
*/
static int dlfb_ops_release(struct fb_info *info, int user)
{
- struct dlfb_data *dev = info->par;
+ struct dlfb_data *dlfb = info->par;
- dev->fb_count--;
+ dlfb->fb_count--;
/* We can't free fb_info here - fbmem will touch it when we return */
- if (dev->virtualized && (dev->fb_count == 0))
- schedule_delayed_work(&dev->free_framebuffer_work, HZ);
+ if (dlfb->virtualized && (dlfb->fb_count == 0))
+ schedule_delayed_work(&dlfb->free_framebuffer_work, HZ);
- if ((dev->fb_count == 0) && (info->fbdefio)) {
+ if ((dlfb->fb_count == 0) && (info->fbdefio)) {
fb_deferred_io_cleanup(info);
kfree(info->fbdefio);
info->fbdefio = NULL;
info->fbops->fb_mmap = dlfb_ops_mmap;
}
- pr_warn("released /dev/fb%d user=%d count=%d\n",
- info->node, user, dev->fb_count);
+ dev_dbg(info->dev, "release, user=%d count=%d\n", user, dlfb->fb_count);
- kref_put(&dev->kref, dlfb_free);
+ kref_put(&dlfb->kref, dlfb_free);
return 0;
}
@@ -1006,19 +993,10 @@ static int dlfb_ops_release(struct fb_info *info, int user)
* Check whether a video mode is supported by the DisplayLink chip
* We start from monitor's modes, so don't need to filter that here
*/
-static int dlfb_is_valid_mode(struct fb_videomode *mode,
- struct fb_info *info)
+static int dlfb_is_valid_mode(struct fb_videomode *mode, struct dlfb_data *dlfb)
{
- struct dlfb_data *dev = info->par;
-
- if (mode->xres * mode->yres > dev->sku_pixel_limit) {
- pr_warn("%dx%d beyond chip capabilities\n",
- mode->xres, mode->yres);
+ if (mode->xres * mode->yres > dlfb->sku_pixel_limit)
return 0;
- }
-
- pr_info("%dx%d @ %d Hz valid mode\n", mode->xres, mode->yres,
- mode->refresh);
return 1;
}
@@ -1039,6 +1017,7 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct fb_videomode mode;
+ struct dlfb_data *dlfb = info->par;
/* TODO: support dynamically changing framebuffer size */
if ((var->xres * var->yres * 2) > info->fix.smem_len)
@@ -1049,7 +1028,7 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
fb_var_to_videomode(&mode, var);
- if (!dlfb_is_valid_mode(&mode, info))
+ if (!dlfb_is_valid_mode(&mode, dlfb))
return -EINVAL;
return 0;
@@ -1057,16 +1036,14 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
static int dlfb_ops_set_par(struct fb_info *info)
{
- struct dlfb_data *dev = info->par;
+ struct dlfb_data *dlfb = info->par;
int result;
u16 *pix_framebuffer;
int i;
- pr_notice("set_par mode %dx%d\n", info->var.xres, info->var.yres);
+ result = dlfb_set_video_mode(dlfb, &info->var);
- result = dlfb_set_video_mode(dev, &info->var);
-
- if ((result == 0) && (dev->fb_count == 0)) {
+ if ((result == 0) && (dlfb->fb_count == 0)) {
/* paint greenscreen */
@@ -1074,7 +1051,7 @@ static int dlfb_ops_set_par(struct fb_info *info)
for (i = 0; i < info->fix.smem_len / 2; i++)
pix_framebuffer[i] = 0x37e6;
- dlfb_handle_damage(dev, 0, 0, info->var.xres, info->var.yres,
+ dlfb_handle_damage(dlfb, 0, 0, info->var.xres, info->var.yres,
info->screen_base);
}
@@ -1101,21 +1078,21 @@ static char *dlfb_dummy_render(char *buf)
*/
static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
{
- struct dlfb_data *dev = info->par;
+ struct dlfb_data *dlfb = info->par;
char *bufptr;
struct urb *urb;
- pr_debug("/dev/fb%d FB_BLANK mode %d --> %d\n",
- info->node, dev->blank_mode, blank_mode);
+ dev_dbg(info->dev, "blank, mode %d --> %d\n",
+ dlfb->blank_mode, blank_mode);
- if ((dev->blank_mode == FB_BLANK_POWERDOWN) &&
+ if ((dlfb->blank_mode == FB_BLANK_POWERDOWN) &&
(blank_mode != FB_BLANK_POWERDOWN)) {
/* returning from powerdown requires a fresh modeset */
- dlfb_set_video_mode(dev, &info->var);
+ dlfb_set_video_mode(dlfb, &info->var);
}
- urb = dlfb_get_urb(dev);
+ urb = dlfb_get_urb(dlfb);
if (!urb)
return 0;
@@ -1127,10 +1104,10 @@ static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
/* seems like a render op is needed to have blank change take effect */
bufptr = dlfb_dummy_render(bufptr);
- dlfb_submit_urb(dev, urb, bufptr -
+ dlfb_submit_urb(dlfb, urb, bufptr -
(char *) urb->transfer_buffer);
- dev->blank_mode = blank_mode;
+ dlfb->blank_mode = blank_mode;
return 0;
}
@@ -1157,7 +1134,7 @@ static struct fb_ops dlfb_ops = {
* Assumes &info->lock held by caller
* Assumes no active clients have framebuffer open
*/
-static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
+static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info)
{
int retval = -ENOMEM;
int old_len = info->fix.smem_len;
@@ -1166,8 +1143,6 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
unsigned char *new_fb;
unsigned char *new_back = NULL;
- pr_warn("Reallocating framebuffer. Addresses will change!\n");
-
new_len = info->fix.line_length * info->var.yres;
if (PAGE_ALIGN(new_len) > old_len) {
@@ -1176,7 +1151,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
*/
new_fb = vmalloc(new_len);
if (!new_fb) {
- pr_err("Virtual framebuffer alloc failed\n");
+ dev_err(info->dev, "Virtual framebuffer alloc failed\n");
goto error;
}
@@ -1199,10 +1174,11 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
if (shadow)
new_back = vzalloc(new_len);
if (!new_back)
- pr_info("No shadow/backing buffer allocated\n");
+ dev_info(info->dev,
+ "No shadow/backing buffer allocated\n");
else {
- vfree(dev->backing_buffer);
- dev->backing_buffer = new_back;
+ vfree(dlfb->backing_buffer);
+ dlfb->backing_buffer = new_back;
}
}
@@ -1226,18 +1202,22 @@ error:
* monspecs is NULL, and fb_var_screeninfo is set to safe VESA mode
* Returns 0 if successful
*/
-static int dlfb_setup_modes(struct dlfb_data *dev,
+static int dlfb_setup_modes(struct dlfb_data *dlfb,
struct fb_info *info,
char *default_edid, size_t default_edid_size)
{
- int i;
- const struct fb_videomode *default_vmode = NULL;
- int result = 0;
char *edid;
- int tries = 3;
+ int i, result = 0, tries = 3;
+ struct device *dev = info->device;
+ struct fb_videomode *mode;
+ const struct fb_videomode *default_vmode = NULL;
- if (info->dev) /* only use mutex if info has been registered */
+ if (info->dev) {
+ /* only use mutex if info has been registered */
mutex_lock(&info->lock);
+ /* parent device is used otherwise */
+ dev = info->dev;
+ }
edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
if (!edid) {
@@ -1255,27 +1235,26 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
*/
while (tries--) {
- i = dlfb_get_edid(dev, edid, EDID_LENGTH);
+ i = dlfb_get_edid(dlfb, edid, EDID_LENGTH);
if (i >= EDID_LENGTH)
fb_edid_to_monspecs(edid, &info->monspecs);
if (info->monspecs.modedb_len > 0) {
- dev->edid = edid;
- dev->edid_size = i;
+ dlfb->edid = edid;
+ dlfb->edid_size = i;
break;
}
}
/* If that fails, use a previously returned EDID if available */
if (info->monspecs.modedb_len == 0) {
+ dev_err(dev, "Unable to get valid EDID from device/display\n");
- pr_err("Unable to get valid EDID from device/display\n");
-
- if (dev->edid) {
- fb_edid_to_monspecs(dev->edid, &info->monspecs);
+ if (dlfb->edid) {
+ fb_edid_to_monspecs(dlfb->edid, &info->monspecs);
if (info->monspecs.modedb_len > 0)
- pr_err("Using previously queried EDID\n");
+ dev_err(dev, "Using previously queried EDID\n");
}
}
@@ -1285,9 +1264,9 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
fb_edid_to_monspecs(default_edid, &info->monspecs);
if (info->monspecs.modedb_len > 0) {
memcpy(edid, default_edid, default_edid_size);
- dev->edid = edid;
- dev->edid_size = default_edid_size;
- pr_err("Using default/backup EDID\n");
+ dlfb->edid = edid;
+ dlfb->edid_size = default_edid_size;
+ dev_err(dev, "Using default/backup EDID\n");
}
}
}
@@ -1296,10 +1275,12 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
if (info->monspecs.modedb_len > 0) {
for (i = 0; i < info->monspecs.modedb_len; i++) {
- if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info))
- fb_add_videomode(&info->monspecs.modedb[i],
- &info->modelist);
- else {
+ mode = &info->monspecs.modedb[i];
+ if (dlfb_is_valid_mode(mode, dlfb)) {
+ fb_add_videomode(mode, &info->modelist);
+ } else {
+ dev_dbg(dev, "Specified mode %dx%d too big\n",
+ mode->xres, mode->yres);
if (i == 0)
/* if we've removed top/best mode */
info->monspecs.misc
@@ -1323,10 +1304,12 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
* But at least the user has a chance to choose
*/
for (i = 0; i < VESA_MODEDB_SIZE; i++) {
- if (dlfb_is_valid_mode((struct fb_videomode *)
- &vesa_modes[i], info))
- fb_add_videomode(&vesa_modes[i],
- &info->modelist);
+ mode = (struct fb_videomode *)&vesa_modes[i];
+ if (dlfb_is_valid_mode(mode, dlfb))
+ fb_add_videomode(mode, &info->modelist);
+ else
+ dev_dbg(dev, "VESA mode %dx%d too big\n",
+ mode->xres, mode->yres);
}
/*
@@ -1341,7 +1324,7 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
}
/* If we have good mode and no active clients*/
- if ((default_vmode != NULL) && (dev->fb_count == 0)) {
+ if ((default_vmode != NULL) && (dlfb->fb_count == 0)) {
fb_videomode_to_var(&info->var, default_vmode);
dlfb_var_color_format(&info->var);
@@ -1353,13 +1336,13 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
info->fix.line_length = info->var.xres *
(info->var.bits_per_pixel / 8);
- result = dlfb_realloc_framebuffer(dev, info);
+ result = dlfb_realloc_framebuffer(dlfb, info);
} else
result = -EINVAL;
error:
- if (edid && (dev->edid != edid))
+ if (edid && (dlfb->edid != edid))
kfree(edid);
if (info->dev)
@@ -1371,33 +1354,33 @@ error:
static ssize_t metrics_bytes_rendered_show(struct device *fbdev,
struct device_attribute *a, char *buf) {
struct fb_info *fb_info = dev_get_drvdata(fbdev);
- struct dlfb_data *dev = fb_info->par;
+ struct dlfb_data *dlfb = fb_info->par;
return snprintf(buf, PAGE_SIZE, "%u\n",
- atomic_read(&dev->bytes_rendered));
+ atomic_read(&dlfb->bytes_rendered));
}
static ssize_t metrics_bytes_identical_show(struct device *fbdev,
struct device_attribute *a, char *buf) {
struct fb_info *fb_info = dev_get_drvdata(fbdev);
- struct dlfb_data *dev = fb_info->par;
+ struct dlfb_data *dlfb = fb_info->par;
return snprintf(buf, PAGE_SIZE, "%u\n",
- atomic_read(&dev->bytes_identical));
+ atomic_read(&dlfb->bytes_identical));
}
static ssize_t metrics_bytes_sent_show(struct device *fbdev,
struct device_attribute *a, char *buf) {
struct fb_info *fb_info = dev_get_drvdata(fbdev);
- struct dlfb_data *dev = fb_info->par;
+ struct dlfb_data *dlfb = fb_info->par;
return snprintf(buf, PAGE_SIZE, "%u\n",
- atomic_read(&dev->bytes_sent));
+ atomic_read(&dlfb->bytes_sent));
}
static ssize_t metrics_cpu_kcycles_used_show(struct device *fbdev,
struct device_attribute *a, char *buf) {
struct fb_info *fb_info = dev_get_drvdata(fbdev);
- struct dlfb_data *dev = fb_info->par;
+ struct dlfb_data *dlfb = fb_info->par;
return snprintf(buf, PAGE_SIZE, "%u\n",
- atomic_read(&dev->cpu_kcycles_used));
+ atomic_read(&dlfb->cpu_kcycles_used));
}
static ssize_t edid_show(
@@ -1406,21 +1389,18 @@ static ssize_t edid_show(
char *buf, loff_t off, size_t count) {
struct device *fbdev = container_of(kobj, struct device, kobj);
struct fb_info *fb_info = dev_get_drvdata(fbdev);
- struct dlfb_data *dev = fb_info->par;
+ struct dlfb_data *dlfb = fb_info->par;
- if (dev->edid == NULL)
+ if (dlfb->edid == NULL)
return 0;
- if ((off >= dev->edid_size) || (count > dev->edid_size))
+ if ((off >= dlfb->edid_size) || (count > dlfb->edid_size))
return 0;
- if (off + count > dev->edid_size)
- count = dev->edid_size - off;
-
- pr_info("sysfs edid copy %p to %p, %d bytes\n",
- dev->edid, buf, (int) count);
+ if (off + count > dlfb->edid_size)
+ count = dlfb->edid_size - off;
- memcpy(buf, dev->edid, count);
+ memcpy(buf, dlfb->edid, count);
return count;
}
@@ -1431,21 +1411,20 @@ static ssize_t edid_store(
char *src, loff_t src_off, size_t src_size) {
struct device *fbdev = container_of(kobj, struct device, kobj);
struct fb_info *fb_info = dev_get_drvdata(fbdev);
- struct dlfb_data *dev = fb_info->par;
+ struct dlfb_data *dlfb = fb_info->par;
int ret;
/* We only support write of entire EDID at once, no offset*/
if ((src_size != EDID_LENGTH) || (src_off != 0))
return -EINVAL;
- ret = dlfb_setup_modes(dev, fb_info, src, src_size);
+ ret = dlfb_setup_modes(dlfb, fb_info, src, src_size);
if (ret)
return ret;
- if (!dev->edid || memcmp(src, dev->edid, src_size))
+ if (!dlfb->edid || memcmp(src, dlfb->edid, src_size))
return -EINVAL;
- pr_info("sysfs written EDID is new default\n");
dlfb_ops_set_par(fb_info);
return src_size;
}
@@ -1455,12 +1434,12 @@ static ssize_t metrics_reset_store(struct device *fbdev,
const char *buf, size_t count)
{
struct fb_info *fb_info = dev_get_drvdata(fbdev);
- struct dlfb_data *dev = fb_info->par;
+ struct dlfb_data *dlfb = fb_info->par;
- atomic_set(&dev->bytes_rendered, 0);
- atomic_set(&dev->bytes_identical, 0);
- atomic_set(&dev->bytes_sent, 0);
- atomic_set(&dev->cpu_kcycles_used, 0);
+ atomic_set(&dlfb->bytes_rendered, 0);
+ atomic_set(&dlfb->bytes_identical, 0);
+ atomic_set(&dlfb->bytes_sent, 0);
+ atomic_set(&dlfb->cpu_kcycles_used, 0);
return count;
}
@@ -1473,7 +1452,7 @@ static const struct bin_attribute edid_attr = {
.write = edid_store
};
-static struct device_attribute fb_device_attrs[] = {
+static const struct device_attribute fb_device_attrs[] = {
__ATTR_RO(metrics_bytes_rendered),
__ATTR_RO(metrics_bytes_identical),
__ATTR_RO(metrics_bytes_sent),
@@ -1484,7 +1463,7 @@ static struct device_attribute fb_device_attrs[] = {
/*
* This is necessary before we can communicate with the display controller.
*/
-static int dlfb_select_std_channel(struct dlfb_data *dev)
+static int dlfb_select_std_channel(struct dlfb_data *dlfb)
{
int ret;
void *buf;
@@ -1499,7 +1478,7 @@ static int dlfb_select_std_channel(struct dlfb_data *dev)
if (!buf)
return -ENOMEM;
- ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+ ret = usb_control_msg(dlfb->udev, usb_sndctrlpipe(dlfb->udev, 0),
NR_USB_REQUEST_CHANNEL,
(USB_DIR_OUT | USB_TYPE_VENDOR), 0, 0,
buf, sizeof(set_def_chn), USB_CTRL_SET_TIMEOUT);
@@ -1509,8 +1488,8 @@ static int dlfb_select_std_channel(struct dlfb_data *dev)
return ret;
}
-static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
- struct usb_interface *interface)
+static int dlfb_parse_vendor_descriptor(struct dlfb_data *dlfb,
+ struct usb_interface *intf)
{
char *desc;
char *buf;
@@ -1522,20 +1501,21 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
return false;
desc = buf;
- total_len = usb_get_descriptor(interface_to_usbdev(interface),
+ total_len = usb_get_descriptor(interface_to_usbdev(intf),
0x5f, /* vendor specific */
0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
/* if not found, look in configuration descriptor */
if (total_len < 0) {
- if (0 == usb_get_extra_descriptor(interface->cur_altsetting,
+ if (0 == usb_get_extra_descriptor(intf->cur_altsetting,
0x5f, &desc))
total_len = (int) desc[0];
}
if (total_len > 5) {
- pr_info("vendor descriptor length:%x data:%11ph\n", total_len,
- desc);
+ dev_info(&intf->dev,
+ "vendor descriptor length: %d data: %11ph\n",
+ total_len, desc);
if ((desc[0] != total_len) || /* descriptor length */
(desc[1] != 0x5f) || /* vendor descriptor type */
@@ -1560,9 +1540,10 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
case 0x0200: { /* max_area */
u32 max_area;
max_area = le32_to_cpu(*((u32 *)desc));
- pr_warn("DL chip limited to %d pixel modes\n",
- max_area);
- dev->sku_pixel_limit = max_area;
+ dev_warn(&intf->dev,
+ "DL chip limited to %d pixel modes\n",
+ max_area);
+ dlfb->sku_pixel_limit = max_area;
break;
}
default:
@@ -1571,14 +1552,15 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
desc += length;
}
} else {
- pr_info("vendor descriptor not available (%d)\n", total_len);
+ dev_info(&intf->dev, "vendor descriptor not available (%d)\n",
+ total_len);
}
goto success;
unrecognized:
/* allow udlfb to load for now even if firmware unrecognized */
- pr_err("Unrecognized vendor firmware descriptor\n");
+ dev_err(&intf->dev, "Unrecognized vendor firmware descriptor\n");
success:
kfree(buf);
@@ -1587,75 +1569,66 @@ success:
static void dlfb_init_framebuffer_work(struct work_struct *work);
-static int dlfb_usb_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
+static int dlfb_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
- struct usb_device *usbdev;
- struct dlfb_data *dev;
+ struct dlfb_data *dlfb;
int retval = -ENOMEM;
+ struct usb_device *usbdev = interface_to_usbdev(intf);
/* usb initialization */
-
- usbdev = interface_to_usbdev(interface);
-
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- dev_err(&interface->dev, "dlfb_usb_probe: failed alloc of dev struct\n");
+ dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL);
+ if (!dlfb) {
+ dev_err(&intf->dev, "%s: failed to allocate dlfb\n", __func__);
goto error;
}
- kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */
+ kref_init(&dlfb->kref); /* matching kref_put in usb .disconnect fn */
- dev->udev = usbdev;
- dev->gdev = &usbdev->dev; /* our generic struct device * */
- usb_set_intfdata(interface, dev);
+ dlfb->udev = usbdev;
+ usb_set_intfdata(intf, dlfb);
- pr_info("%s %s - serial #%s\n",
- usbdev->manufacturer, usbdev->product, usbdev->serial);
- pr_info("vid_%04x&pid_%04x&rev_%04x driver's dlfb_data struct at %p\n",
- le16_to_cpu(usbdev->descriptor.idVendor),
- le16_to_cpu(usbdev->descriptor.idProduct),
- le16_to_cpu(usbdev->descriptor.bcdDevice), dev);
- pr_info("console enable=%d\n", console);
- pr_info("fb_defio enable=%d\n", fb_defio);
- pr_info("shadow enable=%d\n", shadow);
+ dev_dbg(&intf->dev, "console enable=%d\n", console);
+ dev_dbg(&intf->dev, "fb_defio enable=%d\n", fb_defio);
+ dev_dbg(&intf->dev, "shadow enable=%d\n", shadow);
- dev->sku_pixel_limit = 2048 * 1152; /* default to maximum */
+ dlfb->sku_pixel_limit = 2048 * 1152; /* default to maximum */
- if (!dlfb_parse_vendor_descriptor(dev, interface)) {
- pr_err("firmware not recognized. Assume incompatible device\n");
+ if (!dlfb_parse_vendor_descriptor(dlfb, intf)) {
+ dev_err(&intf->dev,
+ "firmware not recognized, incompatible device?\n");
goto error;
}
if (pixel_limit) {
- pr_warn("DL chip limit of %d overridden"
- " by module param to %d\n",
- dev->sku_pixel_limit, pixel_limit);
- dev->sku_pixel_limit = pixel_limit;
+ dev_warn(&intf->dev,
+ "DL chip limit of %d overridden to %d\n",
+ dlfb->sku_pixel_limit, pixel_limit);
+ dlfb->sku_pixel_limit = pixel_limit;
}
- if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
+ if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
retval = -ENOMEM;
- pr_err("dlfb_alloc_urb_list failed\n");
+ dev_err(&intf->dev, "unable to allocate urb list\n");
goto error;
}
- kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */
+ kref_get(&dlfb->kref); /* matching kref_put in free_framebuffer_work */
- /* We don't register a new USB class. Our client interface is fbdev */
+ /* We don't register a new USB class. Our client interface is dlfbev */
/* Workitem keep things fast & simple during USB enumeration */
- INIT_DELAYED_WORK(&dev->init_framebuffer_work,
+ INIT_DELAYED_WORK(&dlfb->init_framebuffer_work,
dlfb_init_framebuffer_work);
- schedule_delayed_work(&dev->init_framebuffer_work, 0);
+ schedule_delayed_work(&dlfb->init_framebuffer_work, 0);
return 0;
error:
- if (dev) {
+ if (dlfb) {
- kref_put(&dev->kref, dlfb_free); /* last ref from kref_init */
+ kref_put(&dlfb->kref, dlfb_free); /* last ref from kref_init */
/* dev has been deallocated. Do not dereference */
}
@@ -1665,97 +1638,101 @@ error:
static void dlfb_init_framebuffer_work(struct work_struct *work)
{
- struct dlfb_data *dev = container_of(work, struct dlfb_data,
- init_framebuffer_work.work);
+ int i, retval;
struct fb_info *info;
- int retval;
- int i;
+ const struct device_attribute *attr;
+ struct dlfb_data *dlfb = container_of(work, struct dlfb_data,
+ init_framebuffer_work.work);
/* allocates framebuffer driver structure, not framebuffer memory */
- info = framebuffer_alloc(0, dev->gdev);
+ info = framebuffer_alloc(0, &dlfb->udev->dev);
if (!info) {
- pr_err("framebuffer_alloc failed\n");
+ dev_err(&dlfb->udev->dev, "framebuffer_alloc failed\n");
goto error;
}
- dev->info = info;
- info->par = dev;
- info->pseudo_palette = dev->pseudo_palette;
+ dlfb->info = info;
+ info->par = dlfb;
+ info->pseudo_palette = dlfb->pseudo_palette;
info->fbops = &dlfb_ops;
retval = fb_alloc_cmap(&info->cmap, 256, 0);
if (retval < 0) {
- pr_err("fb_alloc_cmap failed %x\n", retval);
+ dev_err(info->device, "cmap allocation failed: %d\n", retval);
goto error;
}
- INIT_DELAYED_WORK(&dev->free_framebuffer_work,
+ INIT_DELAYED_WORK(&dlfb->free_framebuffer_work,
dlfb_free_framebuffer_work);
INIT_LIST_HEAD(&info->modelist);
- retval = dlfb_setup_modes(dev, info, NULL, 0);
+ retval = dlfb_setup_modes(dlfb, info, NULL, 0);
if (retval != 0) {
- pr_err("unable to find common mode for display and adapter\n");
+ dev_err(info->device,
+ "unable to find common mode for display and adapter\n");
goto error;
}
/* ready to begin using device */
- atomic_set(&dev->usb_active, 1);
- dlfb_select_std_channel(dev);
+ atomic_set(&dlfb->usb_active, 1);
+ dlfb_select_std_channel(dlfb);
dlfb_ops_check_var(&info->var, info);
dlfb_ops_set_par(info);
retval = register_framebuffer(info);
if (retval < 0) {
- pr_err("register_framebuffer failed %d\n", retval);
+ dev_err(info->device, "unable to register framebuffer: %d\n",
+ retval);
goto error;
}
for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) {
- retval = device_create_file(info->dev, &fb_device_attrs[i]);
- if (retval) {
- pr_warn("device_create_file failed %d\n", retval);
- }
+ attr = &fb_device_attrs[i];
+ retval = device_create_file(info->dev, attr);
+ if (retval)
+ dev_warn(info->device,
+ "failed to create '%s' attribute: %d\n",
+ attr->attr.name, retval);
}
retval = device_create_bin_file(info->dev, &edid_attr);
- if (retval) {
- pr_warn("device_create_bin_file failed %d\n", retval);
- }
-
- pr_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
- " Using %dK framebuffer memory\n", info->node,
- info->var.xres, info->var.yres,
- ((dev->backing_buffer) ?
- info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
+ if (retval)
+ dev_warn(info->device, "failed to create '%s' attribute: %d\n",
+ edid_attr.attr.name, retval);
+
+ dev_info(info->device,
+ "%s is DisplayLink USB device (%dx%d, %dK framebuffer memory)\n",
+ dev_name(info->dev), info->var.xres, info->var.yres,
+ ((dlfb->backing_buffer) ?
+ info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
return;
error:
- dlfb_free_framebuffer(dev);
+ dlfb_free_framebuffer(dlfb);
}
-static void dlfb_usb_disconnect(struct usb_interface *interface)
+static void dlfb_usb_disconnect(struct usb_interface *intf)
{
- struct dlfb_data *dev;
+ struct dlfb_data *dlfb;
struct fb_info *info;
int i;
- dev = usb_get_intfdata(interface);
- info = dev->info;
+ dlfb = usb_get_intfdata(intf);
+ info = dlfb->info;
- pr_info("USB disconnect starting\n");
+ dev_dbg(&intf->dev, "USB disconnect starting\n");
/* we virtualize until all fb clients release. Then we free */
- dev->virtualized = true;
+ dlfb->virtualized = true;
/* When non-active we'll update virtual framebuffer, but no new urbs */
- atomic_set(&dev->usb_active, 0);
+ atomic_set(&dlfb->usb_active, 0);
/* this function will wait for all in-flight urbs to complete */
- dlfb_free_urb_list(dev);
+ dlfb_free_urb_list(dlfb);
if (info) {
/* remove udlfb's sysfs interfaces */
@@ -1765,20 +1742,17 @@ static void dlfb_usb_disconnect(struct usb_interface *interface)
unlink_framebuffer(info);
}
- usb_set_intfdata(interface, NULL);
- dev->udev = NULL;
- dev->gdev = NULL;
+ usb_set_intfdata(intf, NULL);
+ dlfb->udev = NULL;
/* if clients still have us open, will be freed on last close */
- if (dev->fb_count == 0)
- schedule_delayed_work(&dev->free_framebuffer_work, 0);
+ if (dlfb->fb_count == 0)
+ schedule_delayed_work(&dlfb->free_framebuffer_work, 0);
/* release reference taken by kref_init in probe() */
- kref_put(&dev->kref, dlfb_free);
+ kref_put(&dlfb->kref, dlfb_free);
/* consider dlfb_data freed */
-
- return;
}
static struct usb_driver dlfb_driver = {
@@ -1793,26 +1767,32 @@ module_usb_driver(dlfb_driver);
static void dlfb_urb_completion(struct urb *urb)
{
struct urb_node *unode = urb->context;
- struct dlfb_data *dev = unode->dev;
+ struct dlfb_data *dlfb = unode->dlfb;
unsigned long flags;
- /* sync/async unlink faults aren't errors */
- if (urb->status) {
- if (!(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN)) {
- pr_err("%s - nonzero write bulk status received: %d\n",
- __func__, urb->status);
- atomic_set(&dev->lost_pixels, 1);
- }
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* sync/async unlink faults aren't errors */
+ break;
+ default:
+ dev_err(&dlfb->udev->dev,
+ "%s - nonzero write bulk status received: %d\n",
+ __func__, urb->status);
+ atomic_set(&dlfb->lost_pixels, 1);
+ break;
}
- urb->transfer_buffer_length = dev->urbs.size; /* reset to actual */
+ urb->transfer_buffer_length = dlfb->urbs.size; /* reset to actual */
- spin_lock_irqsave(&dev->urbs.lock, flags);
- list_add_tail(&unode->entry, &dev->urbs.list);
- dev->urbs.available++;
- spin_unlock_irqrestore(&dev->urbs.lock, flags);
+ spin_lock_irqsave(&dlfb->urbs.lock, flags);
+ list_add_tail(&unode->entry, &dlfb->urbs.list);
+ dlfb->urbs.available++;
+ spin_unlock_irqrestore(&dlfb->urbs.lock, flags);
/*
* When using fb_defio, we deadlock if up() is called
@@ -1821,65 +1801,63 @@ static void dlfb_urb_completion(struct urb *urb)
if (fb_defio)
schedule_delayed_work(&unode->release_urb_work, 0);
else
- up(&dev->urbs.limit_sem);
+ up(&dlfb->urbs.limit_sem);
}
-static void dlfb_free_urb_list(struct dlfb_data *dev)
+static void dlfb_free_urb_list(struct dlfb_data *dlfb)
{
- int count = dev->urbs.count;
+ int count = dlfb->urbs.count;
struct list_head *node;
struct urb_node *unode;
struct urb *urb;
int ret;
unsigned long flags;
- pr_notice("Freeing all render urbs\n");
-
/* keep waiting and freeing, until we've got 'em all */
while (count--) {
/* Getting interrupted means a leak, but ok at disconnect */
- ret = down_interruptible(&dev->urbs.limit_sem);
+ ret = down_interruptible(&dlfb->urbs.limit_sem);
if (ret)
break;
- spin_lock_irqsave(&dev->urbs.lock, flags);
+ spin_lock_irqsave(&dlfb->urbs.lock, flags);
- node = dev->urbs.list.next; /* have reserved one with sem */
+ node = dlfb->urbs.list.next; /* have reserved one with sem */
list_del_init(node);
- spin_unlock_irqrestore(&dev->urbs.lock, flags);
+ spin_unlock_irqrestore(&dlfb->urbs.lock, flags);
unode = list_entry(node, struct urb_node, entry);
urb = unode->urb;
/* Free each separately allocated piece */
- usb_free_coherent(urb->dev, dev->urbs.size,
+ usb_free_coherent(urb->dev, dlfb->urbs.size,
urb->transfer_buffer, urb->transfer_dma);
usb_free_urb(urb);
kfree(node);
}
- dev->urbs.count = 0;
+ dlfb->urbs.count = 0;
}
-static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
+static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size)
{
int i = 0;
struct urb *urb;
struct urb_node *unode;
char *buf;
- spin_lock_init(&dev->urbs.lock);
+ spin_lock_init(&dlfb->urbs.lock);
- dev->urbs.size = size;
- INIT_LIST_HEAD(&dev->urbs.list);
+ dlfb->urbs.size = size;
+ INIT_LIST_HEAD(&dlfb->urbs.list);
while (i < count) {
- unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL);
+ unode = kzalloc(sizeof(*unode), GFP_KERNEL);
if (!unode)
break;
- unode->dev = dev;
+ unode->dlfb = dlfb;
INIT_DELAYED_WORK(&unode->release_urb_work,
dlfb_release_urb_work);
@@ -1891,7 +1869,7 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
}
unode->urb = urb;
- buf = usb_alloc_coherent(dev->udev, MAX_TRANSFER, GFP_KERNEL,
+ buf = usb_alloc_coherent(dlfb->udev, MAX_TRANSFER, GFP_KERNEL,
&urb->transfer_dma);
if (!buf) {
kfree(unode);
@@ -1900,69 +1878,64 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
}
/* urb->transfer_buffer_length set to actual before submit */
- usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 1),
+ usb_fill_bulk_urb(urb, dlfb->udev, usb_sndbulkpipe(dlfb->udev, 1),
buf, size, dlfb_urb_completion, unode);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- list_add_tail(&unode->entry, &dev->urbs.list);
+ list_add_tail(&unode->entry, &dlfb->urbs.list);
i++;
}
- sema_init(&dev->urbs.limit_sem, i);
- dev->urbs.count = i;
- dev->urbs.available = i;
-
- pr_notice("allocated %d %d byte urbs\n", i, (int) size);
+ sema_init(&dlfb->urbs.limit_sem, i);
+ dlfb->urbs.count = i;
+ dlfb->urbs.available = i;
return i;
}
-static struct urb *dlfb_get_urb(struct dlfb_data *dev)
+static struct urb *dlfb_get_urb(struct dlfb_data *dlfb)
{
int ret;
struct list_head *entry;
struct urb_node *unode;
- struct urb *urb = NULL;
unsigned long flags;
/* Wait for an in-flight buffer to complete and get re-queued */
- ret = down_timeout(&dev->urbs.limit_sem, GET_URB_TIMEOUT);
+ ret = down_timeout(&dlfb->urbs.limit_sem, GET_URB_TIMEOUT);
if (ret) {
- atomic_set(&dev->lost_pixels, 1);
- pr_warn("wait for urb interrupted: %x available: %d\n",
- ret, dev->urbs.available);
- goto error;
+ atomic_set(&dlfb->lost_pixels, 1);
+ dev_warn(&dlfb->udev->dev,
+ "wait for urb interrupted: %d available: %d\n",
+ ret, dlfb->urbs.available);
+ return NULL;
}
- spin_lock_irqsave(&dev->urbs.lock, flags);
+ spin_lock_irqsave(&dlfb->urbs.lock, flags);
- BUG_ON(list_empty(&dev->urbs.list)); /* reserved one with limit_sem */
- entry = dev->urbs.list.next;
+ BUG_ON(list_empty(&dlfb->urbs.list)); /* reserved one with limit_sem */
+ entry = dlfb->urbs.list.next;
list_del_init(entry);
- dev->urbs.available--;
+ dlfb->urbs.available--;
- spin_unlock_irqrestore(&dev->urbs.lock, flags);
+ spin_unlock_irqrestore(&dlfb->urbs.lock, flags);
unode = list_entry(entry, struct urb_node, entry);
- urb = unode->urb;
-
-error:
- return urb;
+ return unode->urb;
}
-static int dlfb_submit_urb(struct dlfb_data *dev, struct urb *urb, size_t len)
+static int dlfb_submit_urb(struct dlfb_data *dlfb, struct urb *urb, size_t len)
{
int ret;
- BUG_ON(len > dev->urbs.size);
+ BUG_ON(len > dlfb->urbs.size);
urb->transfer_buffer_length = len; /* set to actual payload len */
ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret) {
dlfb_urb_completion(urb); /* because no one else will */
- atomic_set(&dev->lost_pixels, 1);
- pr_err("usb_submit_urb error %x\n", ret);
+ atomic_set(&dlfb->lost_pixels, 1);
+ dev_err(&dlfb->udev->dev, "submit urb error: %d\n", ret);
}
return ret;
}
diff --git a/drivers/video/fbdev/vfb.c b/drivers/video/fbdev/vfb.c
index da653a080394..54127905bfe7 100644
--- a/drivers/video/fbdev/vfb.c
+++ b/drivers/video/fbdev/vfb.c
@@ -239,8 +239,23 @@ static int vfb_check_var(struct fb_var_screeninfo *var,
*/
static int vfb_set_par(struct fb_info *info)
{
+ switch (info->var.bits_per_pixel) {
+ case 1:
+ info->fix.visual = FB_VISUAL_MONO01;
+ break;
+ case 8:
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ break;
+ case 16:
+ case 24:
+ case 32:
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ break;
+ }
+
info->fix.line_length = get_line_length(info->var.xres_virtual,
info->var.bits_per_pixel);
+
return 0;
}
@@ -450,6 +465,8 @@ static int vfb_probe(struct platform_device *dev)
goto err2;
platform_set_drvdata(dev, info);
+ vfb_set_par(info);
+
fb_info(info, "Virtual frame buffer device, using %ldK of video memory\n",
videomemorysize >> 10);
return 0;
diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c
index 5f0690c8fc93..2c6a576ed84c 100644
--- a/drivers/video/fbdev/vga16fb.c
+++ b/drivers/video/fbdev/vga16fb.c
@@ -1055,7 +1055,6 @@ static void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
case FB_TYPE_VGA_PLANES:
if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
width = width/8;
- height = height;
line_ofs = info->fix.line_length - width;
setmode(1);
diff --git a/drivers/video/fbdev/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c
index 1a1176bf0906..5c5cd2923041 100644
--- a/drivers/video/fbdev/vt8500lcdfb.c
+++ b/drivers/video/fbdev/vt8500lcdfb.c
@@ -289,10 +289,8 @@ static int vt8500lcd_probe(struct platform_device *pdev)
fbi = devm_kzalloc(&pdev->dev, sizeof(struct vt8500lcd_info)
+ sizeof(u32) * 16, GFP_KERNEL);
- if (!fbi) {
- dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
+ if (!fbi)
return -ENOMEM;
- }
strcpy(fbi->fb.fix.id, "VT8500 LCD");
diff --git a/drivers/video/fbdev/wm8505fb.c b/drivers/video/fbdev/wm8505fb.c
index 253ffe9baab2..8f0d5379861d 100644
--- a/drivers/video/fbdev/wm8505fb.c
+++ b/drivers/video/fbdev/wm8505fb.c
@@ -276,10 +276,8 @@ static int wm8505fb_probe(struct platform_device *pdev)
fbi = devm_kzalloc(&pdev->dev, sizeof(struct wm8505fb_info) +
sizeof(u32) * 16, GFP_KERNEL);
- if (!fbi) {
- dev_err(&pdev->dev, "Failed to initialize framebuffer device\n");
+ if (!fbi)
return -ENOMEM;
- }
strcpy(fbi->fb.fix.id, DRIVER_NAME);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 5bf613d3b7d6..aff773bcebdb 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -328,16 +328,18 @@ config 977_WATCHDOG
Not sure? It's safe to say N.
-config GEMINI_WATCHDOG
- tristate "Gemini watchdog"
- depends on ARCH_GEMINI
+config FTWDT010_WATCHDOG
+ tristate "Faraday Technology FTWDT010 watchdog"
+ depends on ARM || COMPILE_TEST
select WATCHDOG_CORE
+ default ARCH_GEMINI
help
- Say Y here if to include support for the watchdog timer
- embedded in the Cortina Systems Gemini family of devices.
+ Say Y here if to include support for the Faraday Technology
+ FTWDT010 watchdog timer embedded in the Cortina Systems Gemini
+ family of devices.
To compile this driver as a module, choose M here: the
- module will be called gemini_wdt.
+ module will be called ftwdt010_wdt.
config IXP4XX_WATCHDOG
tristate "IXP4xx Watchdog"
@@ -748,12 +750,12 @@ config RENESAS_RZAWDT
Renesas RZ/A SoCs. These watchdogs can be used to reset a system.
config ASPEED_WATCHDOG
- tristate "Aspeed 2400 watchdog support"
+ tristate "Aspeed BMC watchdog support"
depends on ARCH_ASPEED || COMPILE_TEST
select WATCHDOG_CORE
help
Say Y here to include support for the watchdog timer
- in Apseed BMC SoCs.
+ in Aspeed BMC SoCs.
This driver is required to reboot the SoC.
@@ -794,14 +796,23 @@ config UNIPHIER_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called uniphier_wdt.
-# AVR32 Architecture
+config RTD119X_WATCHDOG
+ bool "Realtek RTD119x/RTD129x watchdog support"
+ depends on ARCH_REALTEK || COMPILE_TEST
+ depends on OF
+ select WATCHDOG_CORE
+ default ARCH_REALTEK
+ help
+ Say Y here to include support for the watchdog timer in
+ Realtek RTD1295 SoCs.
-config AT32AP700X_WDT
- tristate "AT32AP700x watchdog"
- depends on CPU_AT32AP700X || COMPILE_TEST
+config SPRD_WATCHDOG
+ tristate "Spreadtrum watchdog support"
+ depends on ARCH_SPRD || COMPILE_TEST
+ select WATCHDOG_CORE
help
- Watchdog timer embedded into AT32AP700x devices. This will reboot
- your system when the timeout is reached.
+ Say Y here to include watchdog timer supported
+ by Spreadtrum system.
# BLACKFIN Architecture
@@ -1458,7 +1469,7 @@ config RC32434_WDT
config INDYDOG
tristate "Indy/I2 Hardware Watchdog"
- depends on SGI_HAS_INDYDOG || (MIPS && COMPILE_TEST)
+ depends on SGI_HAS_INDYDOG
help
Hardware driver for the Indy's/I2's watchdog. This is a
watchdog timer that will reboot the machine after a 60 second
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 135c5e81f25e..0474d38aa854 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -46,7 +46,7 @@ obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o
obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
obj-$(CONFIG_977_WATCHDOG) += wdt977.o
-obj-$(CONFIG_GEMINI_WATCHDOG) += gemini_wdt.o
+obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
@@ -88,9 +88,8 @@ obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o
obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o
obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o
obj-$(CONFIG_UNIPHIER_WATCHDOG) += uniphier_wdt.o
-
-# AVR32 Architecture
-obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
+obj-$(CONFIG_RTD119X_WATCHDOG) += rtd119x_wdt.o
+obj-$(CONFIG_SPRD_WATCHDOG) += sprd_wdt.o
# BLACKFIN Architecture
obj-$(CONFIG_BFIN_WDT) += bfin_wdt.o
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c
index 7d7db0c5a64e..f61944369c1a 100644
--- a/drivers/watchdog/advantechwdt.c
+++ b/drivers/watchdog/advantechwdt.c
@@ -181,7 +181,7 @@ static long advwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (advwdt_set_heartbeat(new_timeout))
return -EINVAL;
advwdt_ping();
- /* Fall */
+ /* fall through */
case WDIOC_GETTIMEOUT:
return put_user(timeout, p);
default:
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c
index 3a17fbd39f8a..60f0c2eb8531 100644
--- a/drivers/watchdog/alim1535_wdt.c
+++ b/drivers/watchdog/alim1535_wdt.c
@@ -223,8 +223,8 @@ static long ali_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (ali_settimer(new_timeout))
return -EINVAL;
ali_keepalive();
- /* Fall */
}
+ /* fall through */
case WDIOC_GETTIMEOUT:
return put_user(timeout, p);
default:
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c
index 79cc766cd30f..ca5b91e2eb92 100644
--- a/drivers/watchdog/aspeed_wdt.c
+++ b/drivers/watchdog/aspeed_wdt.c
@@ -243,9 +243,13 @@ static int aspeed_wdt_probe(struct platform_device *pdev)
if (of_property_read_bool(np, "aspeed,external-signal"))
wdt->ctrl |= WDT_CTRL_WDT_EXT;
- writel(wdt->ctrl, wdt->base + WDT_CTRL);
-
if (readl(wdt->base + WDT_CTRL) & WDT_CTRL_ENABLE) {
+ /*
+ * The watchdog is running, but invoke aspeed_wdt_start() to
+ * write wdt->ctrl to WDT_CTRL to ensure the watchdog's
+ * configuration conforms to the driver's expectations.
+ * Primarily, ensure we're using the 1MHz clock source.
+ */
aspeed_wdt_start(&wdt->wdd);
set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
}
@@ -312,7 +316,18 @@ static struct platform_driver aspeed_watchdog_driver = {
.of_match_table = of_match_ptr(aspeed_wdt_of_table),
},
};
-module_platform_driver(aspeed_watchdog_driver);
+
+static int __init aspeed_wdt_init(void)
+{
+ return platform_driver_register(&aspeed_watchdog_driver);
+}
+arch_initcall(aspeed_wdt_init);
+
+static void __exit aspeed_wdt_exit(void)
+{
+ platform_driver_unregister(&aspeed_watchdog_driver);
+}
+module_exit(aspeed_wdt_exit);
MODULE_DESCRIPTION("Aspeed Watchdog Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
deleted file mode 100644
index 81ba8920f127..000000000000
--- a/drivers/watchdog/at32ap700x_wdt.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Watchdog driver for Atmel AT32AP700X devices
- *
- * Copyright (C) 2005-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.
- *
- *
- * Errata: WDT Clear is blocked after WDT Reset
- *
- * A watchdog timer event will, after reset, block writes to the WDT_CLEAR
- * register, preventing the program to clear the next Watchdog Timer Reset.
- *
- * If you still want to use the WDT after a WDT reset a small code can be
- * insterted at the startup checking the AVR32_PM.rcause register for WDT reset
- * and use a GPIO pin to reset the system. This method requires that one of the
- * GPIO pins are available and connected externally to the RESET_N pin. After
- * the GPIO pin has pulled down the reset line the GPIO will be reset and leave
- * the pin tristated with pullup.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/platform_device.h>
-#include <linux/watchdog.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-
-#define TIMEOUT_MIN 1
-#define TIMEOUT_MAX 2
-#define TIMEOUT_DEFAULT TIMEOUT_MAX
-
-/* module parameters */
-static int timeout = TIMEOUT_DEFAULT;
-module_param(timeout, int, 0);
-MODULE_PARM_DESC(timeout,
- "Timeout value. Limited to be 1 or 2 seconds. (default="
- __MODULE_STRING(TIMEOUT_DEFAULT) ")");
-
-static bool nowayout = WATCHDOG_NOWAYOUT;
-module_param(nowayout, bool, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
- __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-
-/* Watchdog registers and write/read macro */
-#define WDT_CTRL 0x00
-#define WDT_CTRL_EN 0
-#define WDT_CTRL_PSEL 8
-#define WDT_CTRL_KEY 24
-
-#define WDT_CLR 0x04
-
-#define WDT_RCAUSE 0x10
-#define WDT_RCAUSE_POR 0
-#define WDT_RCAUSE_EXT 2
-#define WDT_RCAUSE_WDT 3
-#define WDT_RCAUSE_JTAG 4
-#define WDT_RCAUSE_SERP 5
-
-#define WDT_BIT(name) (1 << WDT_##name)
-#define WDT_BF(name, value) ((value) << WDT_##name)
-
-#define wdt_readl(dev, reg) \
- __raw_readl((dev)->regs + WDT_##reg)
-#define wdt_writel(dev, reg, value) \
- __raw_writel((value), (dev)->regs + WDT_##reg)
-
-struct wdt_at32ap700x {
- void __iomem *regs;
- spinlock_t io_lock;
- int timeout;
- int boot_status;
- unsigned long users;
- struct miscdevice miscdev;
-};
-
-static struct wdt_at32ap700x *wdt;
-static char expect_release;
-
-/*
- * Disable the watchdog.
- */
-static inline void at32_wdt_stop(void)
-{
- unsigned long psel;
-
- spin_lock(&wdt->io_lock);
- psel = wdt_readl(wdt, CTRL) & WDT_BF(CTRL_PSEL, 0x0f);
- wdt_writel(wdt, CTRL, psel | WDT_BF(CTRL_KEY, 0x55));
- wdt_writel(wdt, CTRL, psel | WDT_BF(CTRL_KEY, 0xaa));
- spin_unlock(&wdt->io_lock);
-}
-
-/*
- * Enable and reset the watchdog.
- */
-static inline void at32_wdt_start(void)
-{
- /* 0xf is 2^16 divider = 2 sec, 0xe is 2^15 divider = 1 sec */
- unsigned long psel = (wdt->timeout > 1) ? 0xf : 0xe;
-
- spin_lock(&wdt->io_lock);
- wdt_writel(wdt, CTRL, WDT_BIT(CTRL_EN)
- | WDT_BF(CTRL_PSEL, psel)
- | WDT_BF(CTRL_KEY, 0x55));
- wdt_writel(wdt, CTRL, WDT_BIT(CTRL_EN)
- | WDT_BF(CTRL_PSEL, psel)
- | WDT_BF(CTRL_KEY, 0xaa));
- spin_unlock(&wdt->io_lock);
-}
-
-/*
- * Pat the watchdog timer.
- */
-static inline void at32_wdt_pat(void)
-{
- spin_lock(&wdt->io_lock);
- wdt_writel(wdt, CLR, 0x42);
- spin_unlock(&wdt->io_lock);
-}
-
-/*
- * Watchdog device is opened, and watchdog starts running.
- */
-static int at32_wdt_open(struct inode *inode, struct file *file)
-{
- if (test_and_set_bit(1, &wdt->users))
- return -EBUSY;
-
- at32_wdt_start();
- return nonseekable_open(inode, file);
-}
-
-/*
- * Close the watchdog device.
- */
-static int at32_wdt_close(struct inode *inode, struct file *file)
-{
- if (expect_release == 42) {
- at32_wdt_stop();
- } else {
- dev_dbg(wdt->miscdev.parent,
- "unexpected close, not stopping watchdog!\n");
- at32_wdt_pat();
- }
- clear_bit(1, &wdt->users);
- expect_release = 0;
- return 0;
-}
-
-/*
- * Change the watchdog time interval.
- */
-static int at32_wdt_settimeout(int time)
-{
- /*
- * All counting occurs at 1 / SLOW_CLOCK (32 kHz) and max prescaler is
- * 2 ^ 16 allowing up to 2 seconds timeout.
- */
- if ((time < TIMEOUT_MIN) || (time > TIMEOUT_MAX))
- return -EINVAL;
-
- /*
- * Set new watchdog time. It will be used when at32_wdt_start() is
- * called.
- */
- wdt->timeout = time;
- return 0;
-}
-
-/*
- * Get the watchdog status.
- */
-static int at32_wdt_get_status(void)
-{
- int rcause;
- int status = 0;
-
- rcause = wdt_readl(wdt, RCAUSE);
-
- switch (rcause) {
- case WDT_BIT(RCAUSE_EXT):
- status = WDIOF_EXTERN1;
- break;
- case WDT_BIT(RCAUSE_WDT):
- status = WDIOF_CARDRESET;
- break;
- case WDT_BIT(RCAUSE_POR): /* fall through */
- case WDT_BIT(RCAUSE_JTAG): /* fall through */
- case WDT_BIT(RCAUSE_SERP): /* fall through */
- default:
- break;
- }
-
- return status;
-}
-
-static const struct watchdog_info at32_wdt_info = {
- .identity = "at32ap700x watchdog",
- .options = WDIOF_SETTIMEOUT |
- WDIOF_KEEPALIVEPING |
- WDIOF_MAGICCLOSE,
-};
-
-/*
- * Handle commands from user-space.
- */
-static long at32_wdt_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- int ret = -ENOTTY;
- int time;
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- ret = copy_to_user(argp, &at32_wdt_info,
- sizeof(at32_wdt_info)) ? -EFAULT : 0;
- break;
- case WDIOC_GETSTATUS:
- ret = put_user(0, p);
- break;
- case WDIOC_GETBOOTSTATUS:
- ret = put_user(wdt->boot_status, p);
- break;
- case WDIOC_SETOPTIONS:
- ret = get_user(time, p);
- if (ret)
- break;
- if (time & WDIOS_DISABLECARD)
- at32_wdt_stop();
- if (time & WDIOS_ENABLECARD)
- at32_wdt_start();
- ret = 0;
- break;
- case WDIOC_KEEPALIVE:
- at32_wdt_pat();
- ret = 0;
- break;
- case WDIOC_SETTIMEOUT:
- ret = get_user(time, p);
- if (ret)
- break;
- ret = at32_wdt_settimeout(time);
- if (ret)
- break;
- /* Enable new time value */
- at32_wdt_start();
- /* fall through */
- case WDIOC_GETTIMEOUT:
- ret = put_user(wdt->timeout, p);
- break;
- }
-
- return ret;
-}
-
-static ssize_t at32_wdt_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
-{
- /* See if we got the magic character 'V' and reload the timer */
- if (len) {
- if (!nowayout) {
- size_t i;
-
- /*
- * note: just in case someone wrote the magic
- * character five months ago...
- */
- expect_release = 0;
-
- /*
- * scan to see whether or not we got the magic
- * character
- */
- for (i = 0; i != len; i++) {
- char c;
- if (get_user(c, data + i))
- return -EFAULT;
- if (c == 'V')
- expect_release = 42;
- }
- }
- /* someone wrote to us, we should pat the watchdog */
- at32_wdt_pat();
- }
- return len;
-}
-
-static const struct file_operations at32_wdt_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .unlocked_ioctl = at32_wdt_ioctl,
- .open = at32_wdt_open,
- .release = at32_wdt_close,
- .write = at32_wdt_write,
-};
-
-static int __init at32_wdt_probe(struct platform_device *pdev)
-{
- struct resource *regs;
- int ret;
-
- if (wdt) {
- dev_dbg(&pdev->dev, "only 1 wdt instance supported.\n");
- return -EBUSY;
- }
-
- regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!regs) {
- dev_dbg(&pdev->dev, "missing mmio resource\n");
- return -ENXIO;
- }
-
- wdt = devm_kzalloc(&pdev->dev, sizeof(struct wdt_at32ap700x),
- GFP_KERNEL);
- if (!wdt)
- return -ENOMEM;
-
- wdt->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs));
- if (!wdt->regs) {
- ret = -ENOMEM;
- dev_dbg(&pdev->dev, "could not map I/O memory\n");
- goto err_free;
- }
-
- spin_lock_init(&wdt->io_lock);
- wdt->boot_status = at32_wdt_get_status();
-
- /* Work-around for watchdog silicon errata. */
- if (wdt->boot_status & WDIOF_CARDRESET) {
- dev_info(&pdev->dev, "CPU must be reset with external "
- "reset or POR due to silicon errata.\n");
- ret = -EIO;
- goto err_free;
- } else {
- wdt->users = 0;
- }
-
- wdt->miscdev.minor = WATCHDOG_MINOR;
- wdt->miscdev.name = "watchdog";
- wdt->miscdev.fops = &at32_wdt_fops;
- wdt->miscdev.parent = &pdev->dev;
-
- platform_set_drvdata(pdev, wdt);
-
- if (at32_wdt_settimeout(timeout)) {
- at32_wdt_settimeout(TIMEOUT_DEFAULT);
- dev_dbg(&pdev->dev,
- "default timeout invalid, set to %d sec.\n",
- TIMEOUT_DEFAULT);
- }
-
- ret = misc_register(&wdt->miscdev);
- if (ret) {
- dev_dbg(&pdev->dev, "failed to register wdt miscdev\n");
- goto err_free;
- }
-
- dev_info(&pdev->dev,
- "AT32AP700X WDT at 0x%p, timeout %d sec (nowayout=%d)\n",
- wdt->regs, wdt->timeout, nowayout);
-
- return 0;
-
-err_free:
- wdt = NULL;
- return ret;
-}
-
-static int __exit at32_wdt_remove(struct platform_device *pdev)
-{
- if (wdt && platform_get_drvdata(pdev) == wdt) {
- /* Stop the timer before we leave */
- if (!nowayout)
- at32_wdt_stop();
-
- misc_deregister(&wdt->miscdev);
- wdt = NULL;
- }
- return 0;
-}
-
-static void at32_wdt_shutdown(struct platform_device *pdev)
-{
- at32_wdt_stop();
-}
-
-#ifdef CONFIG_PM
-static int at32_wdt_suspend(struct platform_device *pdev, pm_message_t message)
-{
- at32_wdt_stop();
- return 0;
-}
-
-static int at32_wdt_resume(struct platform_device *pdev)
-{
- if (wdt->users)
- at32_wdt_start();
- return 0;
-}
-#else
-#define at32_wdt_suspend NULL
-#define at32_wdt_resume NULL
-#endif
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:at32_wdt");
-
-static struct platform_driver at32_wdt_driver = {
- .remove = __exit_p(at32_wdt_remove),
- .suspend = at32_wdt_suspend,
- .resume = at32_wdt_resume,
- .driver = {
- .name = "at32_wdt",
- },
- .shutdown = at32_wdt_shutdown,
-};
-
-module_platform_driver_probe(at32_wdt_driver, at32_wdt_probe);
-
-MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
-MODULE_DESCRIPTION("Watchdog driver for Atmel AT32AP700X");
-MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c
index 9083d3d922b0..814dff6045a4 100644
--- a/drivers/watchdog/da9062_wdt.c
+++ b/drivers/watchdog/da9062_wdt.c
@@ -46,22 +46,6 @@ static void da9062_set_window_start(struct da9062_watchdog *wdt)
wdt->j_time_stamp = jiffies;
}
-static void da9062_apply_window_protection(struct da9062_watchdog *wdt)
-{
- unsigned long delay = msecs_to_jiffies(DA9062_RESET_PROTECTION_MS);
- unsigned long timeout = wdt->j_time_stamp + delay;
- unsigned long now = jiffies;
- unsigned int diff_ms;
-
- /* if time-limit has not elapsed then wait for remainder */
- if (time_before(now, timeout)) {
- diff_ms = jiffies_to_msecs(timeout-now);
- dev_dbg(wdt->hw->dev,
- "Kicked too quickly. Delaying %u msecs\n", diff_ms);
- msleep(diff_ms);
- }
-}
-
static unsigned int da9062_wdt_timeout_to_sel(unsigned int secs)
{
unsigned int i;
@@ -78,8 +62,6 @@ static int da9062_reset_watchdog_timer(struct da9062_watchdog *wdt)
{
int ret;
- da9062_apply_window_protection(wdt);
-
ret = regmap_update_bits(wdt->hw->regmap,
DA9062AA_CONTROL_F,
DA9062AA_WATCHDOG_MASK,
@@ -100,6 +82,13 @@ static int da9062_wdt_update_timeout_register(struct da9062_watchdog *wdt,
if (ret)
return ret;
+ regmap_update_bits(chip->regmap,
+ DA9062AA_CONTROL_D,
+ DA9062AA_TWDSCALE_MASK,
+ DA9062_TWDSCALE_DISABLE);
+
+ usleep_range(150, 300);
+
return regmap_update_bits(chip->regmap,
DA9062AA_CONTROL_D,
DA9062AA_TWDSCALE_MASK,
@@ -175,6 +164,25 @@ static int da9062_wdt_set_timeout(struct watchdog_device *wdd,
return ret;
}
+static int da9062_wdt_restart(struct watchdog_device *wdd, unsigned long action,
+ void *data)
+{
+ struct da9062_watchdog *wdt = watchdog_get_drvdata(wdd);
+ int ret;
+
+ ret = regmap_write(wdt->hw->regmap,
+ DA9062AA_CONTROL_F,
+ DA9062AA_SHUTDOWN_MASK);
+ if (ret)
+ dev_alert(wdt->hw->dev, "Failed to shutdown (err = %d)\n",
+ ret);
+
+ /* wait for reset to assert... */
+ mdelay(500);
+
+ return ret;
+}
+
static const struct watchdog_info da9062_watchdog_info = {
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
.identity = "DA9062 WDT",
@@ -186,6 +194,7 @@ static const struct watchdog_ops da9062_watchdog_ops = {
.stop = da9062_wdt_stop,
.ping = da9062_wdt_ping,
.set_timeout = da9062_wdt_set_timeout,
+ .restart = da9062_wdt_restart,
};
static const struct of_device_id da9062_compatible_id_table[] = {
@@ -215,10 +224,13 @@ static int da9062_wdt_probe(struct platform_device *pdev)
wdt->wdtdev.ops = &da9062_watchdog_ops;
wdt->wdtdev.min_timeout = DA9062_WDT_MIN_TIMEOUT;
wdt->wdtdev.max_timeout = DA9062_WDT_MAX_TIMEOUT;
+ wdt->wdtdev.min_hw_heartbeat_ms = DA9062_RESET_PROTECTION_MS;
wdt->wdtdev.timeout = DA9062_WDG_DEFAULT_TIMEOUT;
wdt->wdtdev.status = WATCHDOG_NOWAYOUT_INIT_STATUS;
wdt->wdtdev.parent = &pdev->dev;
+ watchdog_set_restart_priority(&wdt->wdtdev, 128);
+
watchdog_set_drvdata(&wdt->wdtdev, wdt);
ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev);
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 2f46487af86d..3e4c592c239f 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -140,6 +140,42 @@ static unsigned int davinci_wdt_get_timeleft(struct watchdog_device *wdd)
return wdd->timeout - timer_counter;
}
+static int davinci_wdt_restart(struct watchdog_device *wdd,
+ unsigned long action, void *data)
+{
+ struct davinci_wdt_device *davinci_wdt = watchdog_get_drvdata(wdd);
+ u32 tgcr, wdtcr;
+
+ /* disable, internal clock source */
+ iowrite32(0, davinci_wdt->base + TCR);
+
+ /* reset timer, set mode to 64-bit watchdog, and unreset */
+ tgcr = 0;
+ iowrite32(tgcr, davinci_wdt->base + TGCR);
+ tgcr = TIMMODE_64BIT_WDOG | TIM12RS_UNRESET | TIM34RS_UNRESET;
+ iowrite32(tgcr, davinci_wdt->base + TGCR);
+
+ /* clear counter and period regs */
+ iowrite32(0, davinci_wdt->base + TIM12);
+ iowrite32(0, davinci_wdt->base + TIM34);
+ iowrite32(0, davinci_wdt->base + PRD12);
+ iowrite32(0, davinci_wdt->base + PRD34);
+
+ /* put watchdog in pre-active state */
+ wdtcr = WDKEY_SEQ0 | WDEN;
+ iowrite32(wdtcr, davinci_wdt->base + WDTCR);
+
+ /* put watchdog in active state */
+ wdtcr = WDKEY_SEQ1 | WDEN;
+ iowrite32(wdtcr, davinci_wdt->base + WDTCR);
+
+ /* write an invalid value to the WDKEY field to trigger a restart */
+ wdtcr = 0x00004000;
+ iowrite32(wdtcr, davinci_wdt->base + WDTCR);
+
+ return 0;
+}
+
static const struct watchdog_info davinci_wdt_info = {
.options = WDIOF_KEEPALIVEPING,
.identity = "DaVinci/Keystone Watchdog",
@@ -151,6 +187,7 @@ static const struct watchdog_ops davinci_wdt_ops = {
.stop = davinci_wdt_ping,
.ping = davinci_wdt_ping,
.get_timeleft = davinci_wdt_get_timeleft,
+ .restart = davinci_wdt_restart,
};
static int davinci_wdt_probe(struct platform_device *pdev)
@@ -195,6 +232,7 @@ static int davinci_wdt_probe(struct platform_device *pdev)
watchdog_set_drvdata(wdd, davinci_wdt);
watchdog_set_nowayout(wdd, 1);
+ watchdog_set_restart_priority(wdd, 128);
wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
davinci_wdt->base = devm_ioremap_resource(dev, wdt_mem);
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index 36be987ff9ef..c2f4ff516230 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -127,14 +127,27 @@ static int dw_wdt_start(struct watchdog_device *wdd)
dw_wdt_set_timeout(wdd, wdd->timeout);
- set_bit(WDOG_HW_RUNNING, &wdd->status);
-
writel(WDOG_CONTROL_REG_WDT_EN_MASK,
dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
return 0;
}
+static int dw_wdt_stop(struct watchdog_device *wdd)
+{
+ struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
+
+ if (!dw_wdt->rst) {
+ set_bit(WDOG_HW_RUNNING, &wdd->status);
+ return 0;
+ }
+
+ reset_control_assert(dw_wdt->rst);
+ reset_control_deassert(dw_wdt->rst);
+
+ return 0;
+}
+
static int dw_wdt_restart(struct watchdog_device *wdd,
unsigned long action, void *data)
{
@@ -173,6 +186,7 @@ static const struct watchdog_info dw_wdt_ident = {
static const struct watchdog_ops dw_wdt_ops = {
.owner = THIS_MODULE,
.start = dw_wdt_start,
+ .stop = dw_wdt_stop,
.ping = dw_wdt_ping,
.set_timeout = dw_wdt_set_timeout,
.get_timeleft = dw_wdt_get_timeleft,
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c
index 38e96712264f..47f77a6fdfd6 100644
--- a/drivers/watchdog/eurotechwdt.c
+++ b/drivers/watchdog/eurotechwdt.c
@@ -290,7 +290,7 @@ static long eurwdt_ioctl(struct file *file,
eurwdt_timeout = time;
eurwdt_set_timeout(time);
spin_unlock(&eurwdt_lock);
- /* Fall */
+ /* fall through */
case WDIOC_GETTIMEOUT:
return put_user(eurwdt_timeout, p);
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index 8658dba21768..e0678c14480f 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -627,7 +627,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
if (new_options & WDIOS_ENABLECARD)
return watchdog_start();
-
+ /* fall through */
case WDIOC_KEEPALIVE:
watchdog_keepalive();
@@ -641,7 +641,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
return -EINVAL;
watchdog_keepalive();
- /* Fall */
+ /* fall through */
case WDIOC_GETTIMEOUT:
return put_user(watchdog.timeout, uarg.i);
diff --git a/drivers/watchdog/ftwdt010_wdt.c b/drivers/watchdog/ftwdt010_wdt.c
new file mode 100644
index 000000000000..a9c2912ee280
--- /dev/null
+++ b/drivers/watchdog/ftwdt010_wdt.c
@@ -0,0 +1,236 @@
+/*
+ * Watchdog driver for Faraday Technology FTWDT010
+ *
+ * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * Inspired by the out-of-tree drivers from OpenWRT:
+ * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/watchdog.h>
+
+#define FTWDT010_WDCOUNTER 0x0
+#define FTWDT010_WDLOAD 0x4
+#define FTWDT010_WDRESTART 0x8
+#define FTWDT010_WDCR 0xC
+
+#define WDRESTART_MAGIC 0x5AB9
+
+#define WDCR_CLOCK_5MHZ BIT(4)
+#define WDCR_WDEXT BIT(3)
+#define WDCR_WDINTR BIT(2)
+#define WDCR_SYS_RST BIT(1)
+#define WDCR_ENABLE BIT(0)
+
+#define WDT_CLOCK 5000000 /* 5 MHz */
+
+struct ftwdt010_wdt {
+ struct watchdog_device wdd;
+ struct device *dev;
+ void __iomem *base;
+ bool has_irq;
+};
+
+static inline
+struct ftwdt010_wdt *to_ftwdt010_wdt(struct watchdog_device *wdd)
+{
+ return container_of(wdd, struct ftwdt010_wdt, wdd);
+}
+
+static int ftwdt010_wdt_start(struct watchdog_device *wdd)
+{
+ struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
+ u32 enable;
+
+ writel(wdd->timeout * WDT_CLOCK, gwdt->base + FTWDT010_WDLOAD);
+ writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
+ /* set clock before enabling */
+ enable = WDCR_CLOCK_5MHZ | WDCR_SYS_RST;
+ writel(enable, gwdt->base + FTWDT010_WDCR);
+ if (gwdt->has_irq)
+ enable |= WDCR_WDINTR;
+ enable |= WDCR_ENABLE;
+ writel(enable, gwdt->base + FTWDT010_WDCR);
+
+ return 0;
+}
+
+static int ftwdt010_wdt_stop(struct watchdog_device *wdd)
+{
+ struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
+
+ writel(0, gwdt->base + FTWDT010_WDCR);
+
+ return 0;
+}
+
+static int ftwdt010_wdt_ping(struct watchdog_device *wdd)
+{
+ struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
+
+ writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
+
+ return 0;
+}
+
+static int ftwdt010_wdt_set_timeout(struct watchdog_device *wdd,
+ unsigned int timeout)
+{
+ wdd->timeout = timeout;
+ if (watchdog_active(wdd))
+ ftwdt010_wdt_start(wdd);
+
+ return 0;
+}
+
+static irqreturn_t ftwdt010_wdt_interrupt(int irq, void *data)
+{
+ struct ftwdt010_wdt *gwdt = data;
+
+ watchdog_notify_pretimeout(&gwdt->wdd);
+
+ return IRQ_HANDLED;
+}
+
+static const struct watchdog_ops ftwdt010_wdt_ops = {
+ .start = ftwdt010_wdt_start,
+ .stop = ftwdt010_wdt_stop,
+ .ping = ftwdt010_wdt_ping,
+ .set_timeout = ftwdt010_wdt_set_timeout,
+ .owner = THIS_MODULE,
+};
+
+static const struct watchdog_info ftwdt010_wdt_info = {
+ .options = WDIOF_KEEPALIVEPING
+ | WDIOF_MAGICCLOSE
+ | WDIOF_SETTIMEOUT,
+ .identity = KBUILD_MODNAME,
+};
+
+
+static int ftwdt010_wdt_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ struct ftwdt010_wdt *gwdt;
+ unsigned int reg;
+ int irq;
+ int ret;
+
+ gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
+ if (!gwdt)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ gwdt->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(gwdt->base))
+ return PTR_ERR(gwdt->base);
+
+ gwdt->dev = dev;
+ gwdt->wdd.info = &ftwdt010_wdt_info;
+ gwdt->wdd.ops = &ftwdt010_wdt_ops;
+ gwdt->wdd.min_timeout = 1;
+ gwdt->wdd.max_timeout = 0xFFFFFFFF / WDT_CLOCK;
+ gwdt->wdd.parent = dev;
+
+ /*
+ * If 'timeout-sec' unspecified in devicetree, assume a 13 second
+ * default.
+ */
+ gwdt->wdd.timeout = 13U;
+ watchdog_init_timeout(&gwdt->wdd, 0, dev);
+
+ reg = readw(gwdt->base + FTWDT010_WDCR);
+ if (reg & WDCR_ENABLE) {
+ /* Watchdog was enabled by the bootloader, disable it. */
+ reg &= ~WDCR_ENABLE;
+ writel(reg, gwdt->base + FTWDT010_WDCR);
+ }
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq) {
+ ret = devm_request_irq(dev, irq, ftwdt010_wdt_interrupt, 0,
+ "watchdog bark", gwdt);
+ if (ret)
+ return ret;
+ gwdt->has_irq = true;
+ }
+
+ ret = devm_watchdog_register_device(dev, &gwdt->wdd);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register watchdog\n");
+ return ret;
+ }
+
+ /* Set up platform driver data */
+ platform_set_drvdata(pdev, gwdt);
+ dev_info(dev, "FTWDT010 watchdog driver enabled\n");
+
+ return 0;
+}
+
+static int __maybe_unused ftwdt010_wdt_suspend(struct device *dev)
+{
+ struct ftwdt010_wdt *gwdt = dev_get_drvdata(dev);
+ unsigned int reg;
+
+ reg = readw(gwdt->base + FTWDT010_WDCR);
+ reg &= ~WDCR_ENABLE;
+ writel(reg, gwdt->base + FTWDT010_WDCR);
+
+ return 0;
+}
+
+static int __maybe_unused ftwdt010_wdt_resume(struct device *dev)
+{
+ struct ftwdt010_wdt *gwdt = dev_get_drvdata(dev);
+ unsigned int reg;
+
+ if (watchdog_active(&gwdt->wdd)) {
+ reg = readw(gwdt->base + FTWDT010_WDCR);
+ reg |= WDCR_ENABLE;
+ writel(reg, gwdt->base + FTWDT010_WDCR);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops ftwdt010_wdt_dev_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(ftwdt010_wdt_suspend,
+ ftwdt010_wdt_resume)
+};
+
+#ifdef CONFIG_OF
+static const struct of_device_id ftwdt010_wdt_match[] = {
+ { .compatible = "faraday,ftwdt010" },
+ { .compatible = "cortina,gemini-watchdog" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ftwdt010_wdt_match);
+#endif
+
+static struct platform_driver ftwdt010_wdt_driver = {
+ .probe = ftwdt010_wdt_probe,
+ .driver = {
+ .name = "ftwdt010-wdt",
+ .of_match_table = of_match_ptr(ftwdt010_wdt_match),
+ .pm = &ftwdt010_wdt_dev_pm_ops,
+ },
+};
+module_platform_driver(ftwdt010_wdt_driver);
+MODULE_AUTHOR("Linus Walleij");
+MODULE_DESCRIPTION("Watchdog driver for Faraday Technology FTWDT010");
+MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/gemini_wdt.c b/drivers/watchdog/gemini_wdt.c
deleted file mode 100644
index 8155aa619e4c..000000000000
--- a/drivers/watchdog/gemini_wdt.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Watchdog driver for Cortina Systems Gemini SoC
- *
- * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
- *
- * Inspired by the out-of-tree drivers from OpenWRT:
- * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/watchdog.h>
-
-#define GEMINI_WDCOUNTER 0x0
-#define GEMINI_WDLOAD 0x4
-#define GEMINI_WDRESTART 0x8
-#define GEMINI_WDCR 0xC
-
-#define WDRESTART_MAGIC 0x5AB9
-
-#define WDCR_CLOCK_5MHZ BIT(4)
-#define WDCR_SYS_RST BIT(1)
-#define WDCR_ENABLE BIT(0)
-
-#define WDT_CLOCK 5000000 /* 5 MHz */
-
-struct gemini_wdt {
- struct watchdog_device wdd;
- struct device *dev;
- void __iomem *base;
-};
-
-static inline
-struct gemini_wdt *to_gemini_wdt(struct watchdog_device *wdd)
-{
- return container_of(wdd, struct gemini_wdt, wdd);
-}
-
-static int gemini_wdt_start(struct watchdog_device *wdd)
-{
- struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
-
- writel(wdd->timeout * WDT_CLOCK, gwdt->base + GEMINI_WDLOAD);
- writel(WDRESTART_MAGIC, gwdt->base + GEMINI_WDRESTART);
- /* set clock before enabling */
- writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST,
- gwdt->base + GEMINI_WDCR);
- writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE,
- gwdt->base + GEMINI_WDCR);
-
- return 0;
-}
-
-static int gemini_wdt_stop(struct watchdog_device *wdd)
-{
- struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
-
- writel(0, gwdt->base + GEMINI_WDCR);
-
- return 0;
-}
-
-static int gemini_wdt_ping(struct watchdog_device *wdd)
-{
- struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
-
- writel(WDRESTART_MAGIC, gwdt->base + GEMINI_WDRESTART);
-
- return 0;
-}
-
-static int gemini_wdt_set_timeout(struct watchdog_device *wdd,
- unsigned int timeout)
-{
- wdd->timeout = timeout;
- if (watchdog_active(wdd))
- gemini_wdt_start(wdd);
-
- return 0;
-}
-
-static irqreturn_t gemini_wdt_interrupt(int irq, void *data)
-{
- struct gemini_wdt *gwdt = data;
-
- watchdog_notify_pretimeout(&gwdt->wdd);
-
- return IRQ_HANDLED;
-}
-
-static const struct watchdog_ops gemini_wdt_ops = {
- .start = gemini_wdt_start,
- .stop = gemini_wdt_stop,
- .ping = gemini_wdt_ping,
- .set_timeout = gemini_wdt_set_timeout,
- .owner = THIS_MODULE,
-};
-
-static const struct watchdog_info gemini_wdt_info = {
- .options = WDIOF_KEEPALIVEPING
- | WDIOF_MAGICCLOSE
- | WDIOF_SETTIMEOUT,
- .identity = KBUILD_MODNAME,
-};
-
-
-static int gemini_wdt_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct resource *res;
- struct gemini_wdt *gwdt;
- unsigned int reg;
- int irq;
- int ret;
-
- gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
- if (!gwdt)
- return -ENOMEM;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- gwdt->base = devm_ioremap_resource(dev, res);
- if (IS_ERR(gwdt->base))
- return PTR_ERR(gwdt->base);
-
- irq = platform_get_irq(pdev, 0);
- if (!irq)
- return -EINVAL;
-
- gwdt->dev = dev;
- gwdt->wdd.info = &gemini_wdt_info;
- gwdt->wdd.ops = &gemini_wdt_ops;
- gwdt->wdd.min_timeout = 1;
- gwdt->wdd.max_timeout = 0xFFFFFFFF / WDT_CLOCK;
- gwdt->wdd.parent = dev;
-
- /*
- * If 'timeout-sec' unspecified in devicetree, assume a 13 second
- * default.
- */
- gwdt->wdd.timeout = 13U;
- watchdog_init_timeout(&gwdt->wdd, 0, dev);
-
- reg = readw(gwdt->base + GEMINI_WDCR);
- if (reg & WDCR_ENABLE) {
- /* Watchdog was enabled by the bootloader, disable it. */
- reg &= ~WDCR_ENABLE;
- writel(reg, gwdt->base + GEMINI_WDCR);
- }
-
- ret = devm_request_irq(dev, irq, gemini_wdt_interrupt, 0,
- "watchdog bark", gwdt);
- if (ret)
- return ret;
-
- ret = devm_watchdog_register_device(dev, &gwdt->wdd);
- if (ret) {
- dev_err(&pdev->dev, "failed to register watchdog\n");
- return ret;
- }
-
- /* Set up platform driver data */
- platform_set_drvdata(pdev, gwdt);
- dev_info(dev, "Gemini watchdog driver enabled\n");
-
- return 0;
-}
-
-static int __maybe_unused gemini_wdt_suspend(struct device *dev)
-{
- struct gemini_wdt *gwdt = dev_get_drvdata(dev);
- unsigned int reg;
-
- reg = readw(gwdt->base + GEMINI_WDCR);
- reg &= ~WDCR_ENABLE;
- writel(reg, gwdt->base + GEMINI_WDCR);
-
- return 0;
-}
-
-static int __maybe_unused gemini_wdt_resume(struct device *dev)
-{
- struct gemini_wdt *gwdt = dev_get_drvdata(dev);
- unsigned int reg;
-
- if (watchdog_active(&gwdt->wdd)) {
- reg = readw(gwdt->base + GEMINI_WDCR);
- reg |= WDCR_ENABLE;
- writel(reg, gwdt->base + GEMINI_WDCR);
- }
-
- return 0;
-}
-
-static const struct dev_pm_ops gemini_wdt_dev_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(gemini_wdt_suspend,
- gemini_wdt_resume)
-};
-
-#ifdef CONFIG_OF
-static const struct of_device_id gemini_wdt_match[] = {
- { .compatible = "cortina,gemini-watchdog" },
- {},
-};
-MODULE_DEVICE_TABLE(of, gemini_wdt_match);
-#endif
-
-static struct platform_driver gemini_wdt_driver = {
- .probe = gemini_wdt_probe,
- .driver = {
- .name = "gemini-wdt",
- .of_match_table = of_match_ptr(gemini_wdt_match),
- .pm = &gemini_wdt_dev_pm_ops,
- },
-};
-module_platform_driver(gemini_wdt_driver);
-MODULE_AUTHOR("Linus Walleij");
-MODULE_DESCRIPTION("Watchdog driver for Gemini");
-MODULE_LICENSE("GPL");
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c
index cb66c2f99ff1..3ade28190341 100644
--- a/drivers/watchdog/gpio_wdt.c
+++ b/drivers/watchdog/gpio_wdt.c
@@ -12,7 +12,8 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/module.h>
-#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/watchdog.h>
@@ -25,8 +26,7 @@ enum {
};
struct gpio_wdt_priv {
- int gpio;
- bool active_low;
+ struct gpio_desc *gpiod;
bool state;
bool always_running;
unsigned int hw_algo;
@@ -35,11 +35,12 @@ struct gpio_wdt_priv {
static void gpio_wdt_disable(struct gpio_wdt_priv *priv)
{
- gpio_set_value_cansleep(priv->gpio, !priv->active_low);
+ /* Eternal ping */
+ gpiod_set_value_cansleep(priv->gpiod, 1);
/* Put GPIO back to tristate */
if (priv->hw_algo == HW_ALGO_TOGGLE)
- gpio_direction_input(priv->gpio);
+ gpiod_direction_input(priv->gpiod);
}
static int gpio_wdt_ping(struct watchdog_device *wdd)
@@ -50,13 +51,13 @@ static int gpio_wdt_ping(struct watchdog_device *wdd)
case HW_ALGO_TOGGLE:
/* Toggle output pin */
priv->state = !priv->state;
- gpio_set_value_cansleep(priv->gpio, priv->state);
+ gpiod_set_value_cansleep(priv->gpiod, priv->state);
break;
case HW_ALGO_LEVEL:
/* Pulse */
- gpio_set_value_cansleep(priv->gpio, !priv->active_low);
+ gpiod_set_value_cansleep(priv->gpiod, 1);
udelay(1);
- gpio_set_value_cansleep(priv->gpio, priv->active_low);
+ gpiod_set_value_cansleep(priv->gpiod, 0);
break;
}
return 0;
@@ -66,8 +67,8 @@ static int gpio_wdt_start(struct watchdog_device *wdd)
{
struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
- priv->state = priv->active_low;
- gpio_direction_output(priv->gpio, priv->state);
+ priv->state = 0;
+ gpiod_direction_output(priv->gpiod, priv->state);
set_bit(WDOG_HW_RUNNING, &wdd->status);
@@ -80,7 +81,8 @@ static int gpio_wdt_stop(struct watchdog_device *wdd)
if (!priv->always_running) {
gpio_wdt_disable(priv);
- clear_bit(WDOG_HW_RUNNING, &wdd->status);
+ } else {
+ set_bit(WDOG_HW_RUNNING, &wdd->status);
}
return 0;
@@ -101,44 +103,38 @@ static const struct watchdog_ops gpio_wdt_ops = {
static int gpio_wdt_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
struct gpio_wdt_priv *priv;
- enum of_gpio_flags flags;
+ enum gpiod_flags gflags;
unsigned int hw_margin;
- unsigned long f = 0;
const char *algo;
int ret;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
platform_set_drvdata(pdev, priv);
- priv->gpio = of_get_gpio_flags(pdev->dev.of_node, 0, &flags);
- if (!gpio_is_valid(priv->gpio))
- return priv->gpio;
-
- priv->active_low = flags & OF_GPIO_ACTIVE_LOW;
-
- ret = of_property_read_string(pdev->dev.of_node, "hw_algo", &algo);
+ ret = of_property_read_string(np, "hw_algo", &algo);
if (ret)
return ret;
if (!strcmp(algo, "toggle")) {
priv->hw_algo = HW_ALGO_TOGGLE;
- f = GPIOF_IN;
+ gflags = GPIOD_IN;
} else if (!strcmp(algo, "level")) {
priv->hw_algo = HW_ALGO_LEVEL;
- f = priv->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ gflags = GPIOD_OUT_LOW;
} else {
return -EINVAL;
}
- ret = devm_gpio_request_one(&pdev->dev, priv->gpio, f,
- dev_name(&pdev->dev));
- if (ret)
- return ret;
+ priv->gpiod = devm_gpiod_get(dev, NULL, gflags);
+ if (IS_ERR(priv->gpiod))
+ return PTR_ERR(priv->gpiod);
- ret = of_property_read_u32(pdev->dev.of_node,
+ ret = of_property_read_u32(np,
"hw_margin_ms", &hw_margin);
if (ret)
return ret;
@@ -146,7 +142,7 @@ static int gpio_wdt_probe(struct platform_device *pdev)
if (hw_margin < 2 || hw_margin > 65535)
return -EINVAL;
- priv->always_running = of_property_read_bool(pdev->dev.of_node,
+ priv->always_running = of_property_read_bool(np,
"always-running");
watchdog_set_drvdata(&priv->wdd, priv);
@@ -155,9 +151,9 @@ static int gpio_wdt_probe(struct platform_device *pdev)
priv->wdd.ops = &gpio_wdt_ops;
priv->wdd.min_timeout = SOFT_TIMEOUT_MIN;
priv->wdd.max_hw_heartbeat_ms = hw_margin;
- priv->wdd.parent = &pdev->dev;
+ priv->wdd.parent = dev;
- if (watchdog_init_timeout(&priv->wdd, 0, &pdev->dev) < 0)
+ if (watchdog_init_timeout(&priv->wdd, 0, dev) < 0)
priv->wdd.timeout = SOFT_TIMEOUT_DEF;
watchdog_stop_on_reboot(&priv->wdd);
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 67fbe35ce7cf..f1f00dfc0e68 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -52,6 +52,7 @@ static char expect_release;
static unsigned long hpwdt_is_open;
static void __iomem *pci_mem_addr; /* the PCI-memory address */
+static unsigned long __iomem *hpwdt_nmistat;
static unsigned long __iomem *hpwdt_timer_reg;
static unsigned long __iomem *hpwdt_timer_con;
@@ -475,6 +476,11 @@ static int hpwdt_time_left(void)
}
#ifdef CONFIG_HPWDT_NMI_DECODING
+static int hpwdt_my_nmi(void)
+{
+ return ioread8(hpwdt_nmistat) & 0x6;
+}
+
/*
* NMI Handler
*/
@@ -486,6 +492,9 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
if (!hpwdt_nmi_decoding)
return NMI_DONE;
+ if ((ulReason == NMI_UNKNOWN) && !hpwdt_my_nmi())
+ return NMI_DONE;
+
spin_lock_irqsave(&rom_lock, rom_pl);
if (!die_nmi_called && !is_icru && !is_uefi)
asminline_call(&cmn_regs, cru_rom_addr);
@@ -700,7 +709,7 @@ static void dmi_find_icru(const struct dmi_header *dm, void *dummy)
smbios_proliant_ptr = (struct smbios_proliant_info *) dm;
if (smbios_proliant_ptr->misc_features & 0x01)
is_icru = 1;
- if (smbios_proliant_ptr->misc_features & 0x408)
+ if (smbios_proliant_ptr->misc_features & 0x1400)
is_uefi = 1;
}
}
@@ -842,6 +851,7 @@ static int hpwdt_init_one(struct pci_dev *dev,
retval = -ENOMEM;
goto error_pci_iomap;
}
+ hpwdt_nmistat = pci_mem_addr + 0x6e;
hpwdt_timer_reg = pci_mem_addr + 0x70;
hpwdt_timer_con = pci_mem_addr + 0x72;
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index d7befd58b391..950c71a8bb22 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -21,14 +21,15 @@
* Version 0.02
* 20050210 David Härdeman <david@2gen.com>
* Ported driver to kernel 2.6
+ * 20171016 Radu Rendec <rrendec@arista.com>
+ * Change driver to use the watchdog subsystem
+ * Add support for multiple 6300ESB devices
*/
/*
* Includes, defines, variables, module parameters, ...
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
@@ -42,19 +43,17 @@
#include <linux/io.h>
/* Module and version information */
-#define ESB_VERSION "0.05"
#define ESB_MODULE_NAME "i6300ESB timer"
-#define ESB_DRIVER_NAME ESB_MODULE_NAME ", v" ESB_VERSION
/* PCI configuration registers */
#define ESB_CONFIG_REG 0x60 /* Config register */
#define ESB_LOCK_REG 0x68 /* WDT lock register */
/* Memory mapped registers */
-#define ESB_TIMER1_REG (BASEADDR + 0x00)/* Timer1 value after each reset */
-#define ESB_TIMER2_REG (BASEADDR + 0x04)/* Timer2 value after each reset */
-#define ESB_GINTSR_REG (BASEADDR + 0x08)/* General Interrupt Status Register */
-#define ESB_RELOAD_REG (BASEADDR + 0x0c)/* Reload register */
+#define ESB_TIMER1_REG(w) ((w)->base + 0x00)/* Timer1 value after each reset */
+#define ESB_TIMER2_REG(w) ((w)->base + 0x04)/* Timer2 value after each reset */
+#define ESB_GINTSR_REG(w) ((w)->base + 0x08)/* General Interrupt Status Reg */
+#define ESB_RELOAD_REG(w) ((w)->base + 0x0c)/* Reload register */
/* Lock register bits */
#define ESB_WDT_FUNC (0x01 << 2) /* Watchdog functionality */
@@ -74,25 +73,18 @@
#define ESB_UNLOCK1 0x80 /* Step 1 to unlock reset registers */
#define ESB_UNLOCK2 0x86 /* Step 2 to unlock reset registers */
-/* internal variables */
-static void __iomem *BASEADDR;
-static DEFINE_SPINLOCK(esb_lock); /* Guards the hardware */
-static unsigned long timer_alive;
-static struct pci_dev *esb_pci;
-static unsigned short triggered; /* The status of the watchdog upon boot */
-static char esb_expect_close;
-
-/* We can only use 1 card due to the /dev/watchdog restriction */
-static int cards_found;
-
/* module parameters */
/* 30 sec default heartbeat (1 < heartbeat < 2*1023) */
-#define WATCHDOG_HEARTBEAT 30
-static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */
+#define ESB_HEARTBEAT_MIN 1
+#define ESB_HEARTBEAT_MAX 2046
+#define ESB_HEARTBEAT_DEFAULT 30
+#define ESB_HEARTBEAT_RANGE __MODULE_STRING(ESB_HEARTBEAT_MIN) \
+ "<heartbeat<" __MODULE_STRING(ESB_HEARTBEAT_MAX)
+static int heartbeat; /* in seconds */
module_param(heartbeat, int, 0);
MODULE_PARM_DESC(heartbeat,
- "Watchdog heartbeat in seconds. (1<heartbeat<2046, default="
- __MODULE_STRING(WATCHDOG_HEARTBEAT) ")");
+ "Watchdog heartbeat in seconds. (" ESB_HEARTBEAT_RANGE
+ ", default=" __MODULE_STRING(ESB_HEARTBEAT_DEFAULT) ")");
static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
@@ -100,6 +92,15 @@ MODULE_PARM_DESC(nowayout,
"Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+/* internal variables */
+struct esb_dev {
+ struct watchdog_device wdd;
+ void __iomem *base;
+ struct pci_dev *pdev;
+};
+
+#define to_esb_dev(wptr) container_of(wptr, struct esb_dev, wdd)
+
/*
* Some i6300ESB specific functions
*/
@@ -110,61 +111,58 @@ MODULE_PARM_DESC(nowayout,
* reload register. After this the appropriate registers can be written
* to once before they need to be unlocked again.
*/
-static inline void esb_unlock_registers(void)
+static inline void esb_unlock_registers(struct esb_dev *edev)
{
- writew(ESB_UNLOCK1, ESB_RELOAD_REG);
- writew(ESB_UNLOCK2, ESB_RELOAD_REG);
+ writew(ESB_UNLOCK1, ESB_RELOAD_REG(edev));
+ writew(ESB_UNLOCK2, ESB_RELOAD_REG(edev));
}
-static int esb_timer_start(void)
+static int esb_timer_start(struct watchdog_device *wdd)
{
+ struct esb_dev *edev = to_esb_dev(wdd);
+ int _wdd_nowayout = test_bit(WDOG_NO_WAY_OUT, &wdd->status);
u8 val;
- spin_lock(&esb_lock);
- esb_unlock_registers();
- writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+ esb_unlock_registers(edev);
+ writew(ESB_WDT_RELOAD, ESB_RELOAD_REG(edev));
/* Enable or Enable + Lock? */
- val = ESB_WDT_ENABLE | (nowayout ? ESB_WDT_LOCK : 0x00);
- pci_write_config_byte(esb_pci, ESB_LOCK_REG, val);
- spin_unlock(&esb_lock);
+ val = ESB_WDT_ENABLE | (_wdd_nowayout ? ESB_WDT_LOCK : 0x00);
+ pci_write_config_byte(edev->pdev, ESB_LOCK_REG, val);
return 0;
}
-static int esb_timer_stop(void)
+static int esb_timer_stop(struct watchdog_device *wdd)
{
+ struct esb_dev *edev = to_esb_dev(wdd);
u8 val;
- spin_lock(&esb_lock);
/* First, reset timers as suggested by the docs */
- esb_unlock_registers();
- writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+ esb_unlock_registers(edev);
+ writew(ESB_WDT_RELOAD, ESB_RELOAD_REG(edev));
/* Then disable the WDT */
- pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x0);
- pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val);
- spin_unlock(&esb_lock);
+ pci_write_config_byte(edev->pdev, ESB_LOCK_REG, 0x0);
+ pci_read_config_byte(edev->pdev, ESB_LOCK_REG, &val);
/* Returns 0 if the timer was disabled, non-zero otherwise */
return val & ESB_WDT_ENABLE;
}
-static void esb_timer_keepalive(void)
+static int esb_timer_keepalive(struct watchdog_device *wdd)
{
- spin_lock(&esb_lock);
- esb_unlock_registers();
- writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+ struct esb_dev *edev = to_esb_dev(wdd);
+
+ esb_unlock_registers(edev);
+ writew(ESB_WDT_RELOAD, ESB_RELOAD_REG(edev));
/* FIXME: Do we need to flush anything here? */
- spin_unlock(&esb_lock);
+ return 0;
}
-static int esb_timer_set_heartbeat(int time)
+static int esb_timer_set_heartbeat(struct watchdog_device *wdd,
+ unsigned int time)
{
+ struct esb_dev *edev = to_esb_dev(wdd);
u32 val;
- if (time < 0x1 || time > (2 * 0x03ff))
- return -EINVAL;
-
- spin_lock(&esb_lock);
-
/* We shift by 9, so if we are passed a value of 1 sec,
* val will be 1 << 9 = 512, then write that to two
* timers => 2 * 512 = 1024 (which is decremented at 1KHz)
@@ -172,162 +170,39 @@ static int esb_timer_set_heartbeat(int time)
val = time << 9;
/* Write timer 1 */
- esb_unlock_registers();
- writel(val, ESB_TIMER1_REG);
+ esb_unlock_registers(edev);
+ writel(val, ESB_TIMER1_REG(edev));
/* Write timer 2 */
- esb_unlock_registers();
- writel(val, ESB_TIMER2_REG);
+ esb_unlock_registers(edev);
+ writel(val, ESB_TIMER2_REG(edev));
/* Reload */
- esb_unlock_registers();
- writew(ESB_WDT_RELOAD, ESB_RELOAD_REG);
+ esb_unlock_registers(edev);
+ writew(ESB_WDT_RELOAD, ESB_RELOAD_REG(edev));
/* FIXME: Do we need to flush everything out? */
/* Done */
- heartbeat = time;
- spin_unlock(&esb_lock);
- return 0;
-}
-
-/*
- * /dev/watchdog handling
- */
-
-static int esb_open(struct inode *inode, struct file *file)
-{
- /* /dev/watchdog can only be opened once */
- if (test_and_set_bit(0, &timer_alive))
- return -EBUSY;
-
- /* Reload and activate timer */
- esb_timer_start();
-
- return nonseekable_open(inode, file);
-}
-
-static int esb_release(struct inode *inode, struct file *file)
-{
- /* Shut off the timer. */
- if (esb_expect_close == 42)
- esb_timer_stop();
- else {
- pr_crit("Unexpected close, not stopping watchdog!\n");
- esb_timer_keepalive();
- }
- clear_bit(0, &timer_alive);
- esb_expect_close = 0;
+ wdd->timeout = time;
return 0;
}
-static ssize_t esb_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
-{
- /* See if we got the magic character 'V' and reload the timer */
- if (len) {
- if (!nowayout) {
- size_t i;
-
- /* note: just in case someone wrote the magic character
- * five months ago... */
- esb_expect_close = 0;
-
- /* scan to see whether or not we got the
- * magic character */
- for (i = 0; i != len; i++) {
- char c;
- if (get_user(c, data + i))
- return -EFAULT;
- if (c == 'V')
- esb_expect_close = 42;
- }
- }
-
- /* someone wrote to us, we should reload the timer */
- esb_timer_keepalive();
- }
- return len;
-}
-
-static long esb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int new_options, retval = -EINVAL;
- int new_heartbeat;
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
- static const struct watchdog_info ident = {
- .options = WDIOF_SETTIMEOUT |
- WDIOF_KEEPALIVEPING |
- WDIOF_MAGICCLOSE,
- .firmware_version = 0,
- .identity = ESB_MODULE_NAME,
- };
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- return copy_to_user(argp, &ident,
- sizeof(ident)) ? -EFAULT : 0;
-
- case WDIOC_GETSTATUS:
- return put_user(0, p);
-
- case WDIOC_GETBOOTSTATUS:
- return put_user(triggered, p);
-
- case WDIOC_SETOPTIONS:
- {
- if (get_user(new_options, p))
- return -EFAULT;
-
- if (new_options & WDIOS_DISABLECARD) {
- esb_timer_stop();
- retval = 0;
- }
-
- if (new_options & WDIOS_ENABLECARD) {
- esb_timer_start();
- retval = 0;
- }
- return retval;
- }
- case WDIOC_KEEPALIVE:
- esb_timer_keepalive();
- return 0;
-
- case WDIOC_SETTIMEOUT:
- {
- if (get_user(new_heartbeat, p))
- return -EFAULT;
- if (esb_timer_set_heartbeat(new_heartbeat))
- return -EINVAL;
- esb_timer_keepalive();
- /* Fall */
- }
- case WDIOC_GETTIMEOUT:
- return put_user(heartbeat, p);
- default:
- return -ENOTTY;
- }
-}
-
/*
- * Kernel Interfaces
+ * Watchdog Subsystem Interfaces
*/
-static const struct file_operations esb_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = esb_write,
- .unlocked_ioctl = esb_ioctl,
- .open = esb_open,
- .release = esb_release,
+static struct watchdog_info esb_info = {
+ .identity = ESB_MODULE_NAME,
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
};
-static struct miscdevice esb_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &esb_fops,
+static const struct watchdog_ops esb_ops = {
+ .owner = THIS_MODULE,
+ .start = esb_timer_start,
+ .stop = esb_timer_stop,
+ .set_timeout = esb_timer_set_heartbeat,
+ .ping = esb_timer_keepalive,
};
/*
@@ -343,38 +218,38 @@ MODULE_DEVICE_TABLE(pci, esb_pci_tbl);
* Init & exit routines
*/
-static unsigned char esb_getdevice(struct pci_dev *pdev)
+static unsigned char esb_getdevice(struct esb_dev *edev)
{
- if (pci_enable_device(pdev)) {
- pr_err("failed to enable device\n");
+ if (pci_enable_device(edev->pdev)) {
+ dev_err(&edev->pdev->dev, "failed to enable device\n");
goto err_devput;
}
- if (pci_request_region(pdev, 0, ESB_MODULE_NAME)) {
- pr_err("failed to request region\n");
+ if (pci_request_region(edev->pdev, 0, ESB_MODULE_NAME)) {
+ dev_err(&edev->pdev->dev, "failed to request region\n");
goto err_disable;
}
- BASEADDR = pci_ioremap_bar(pdev, 0);
- if (BASEADDR == NULL) {
+ edev->base = pci_ioremap_bar(edev->pdev, 0);
+ if (edev->base == NULL) {
/* Something's wrong here, BASEADDR has to be set */
- pr_err("failed to get BASEADDR\n");
+ dev_err(&edev->pdev->dev, "failed to get BASEADDR\n");
goto err_release;
}
/* Done */
- esb_pci = pdev;
+ dev_set_drvdata(&edev->pdev->dev, edev);
return 1;
err_release:
- pci_release_region(pdev, 0);
+ pci_release_region(edev->pdev, 0);
err_disable:
- pci_disable_device(pdev);
+ pci_disable_device(edev->pdev);
err_devput:
return 0;
}
-static void esb_initdevice(void)
+static void esb_initdevice(struct esb_dev *edev)
{
u8 val1;
u16 val2;
@@ -391,96 +266,87 @@ static void esb_initdevice(void)
* any interrupts as there is not much we can do with it
* right now.
*/
- pci_write_config_word(esb_pci, ESB_CONFIG_REG, 0x0003);
+ pci_write_config_word(edev->pdev, ESB_CONFIG_REG, 0x0003);
/* Check that the WDT isn't already locked */
- pci_read_config_byte(esb_pci, ESB_LOCK_REG, &val1);
+ pci_read_config_byte(edev->pdev, ESB_LOCK_REG, &val1);
if (val1 & ESB_WDT_LOCK)
- pr_warn("nowayout already set\n");
+ dev_warn(&edev->pdev->dev, "nowayout already set\n");
/* Set the timer to watchdog mode and disable it for now */
- pci_write_config_byte(esb_pci, ESB_LOCK_REG, 0x00);
+ pci_write_config_byte(edev->pdev, ESB_LOCK_REG, 0x00);
/* Check if the watchdog was previously triggered */
- esb_unlock_registers();
- val2 = readw(ESB_RELOAD_REG);
+ esb_unlock_registers(edev);
+ val2 = readw(ESB_RELOAD_REG(edev));
if (val2 & ESB_WDT_TIMEOUT)
- triggered = WDIOF_CARDRESET;
+ edev->wdd.bootstatus = WDIOF_CARDRESET;
/* Reset WDT_TIMEOUT flag and timers */
- esb_unlock_registers();
- writew((ESB_WDT_TIMEOUT | ESB_WDT_RELOAD), ESB_RELOAD_REG);
+ esb_unlock_registers(edev);
+ writew((ESB_WDT_TIMEOUT | ESB_WDT_RELOAD), ESB_RELOAD_REG(edev));
/* And set the correct timeout value */
- esb_timer_set_heartbeat(heartbeat);
+ esb_timer_set_heartbeat(&edev->wdd, edev->wdd.timeout);
}
static int esb_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
+ struct esb_dev *edev;
int ret;
- cards_found++;
- if (cards_found == 1)
- pr_info("Intel 6300ESB WatchDog Timer Driver v%s\n",
- ESB_VERSION);
-
- if (cards_found > 1) {
- pr_err("This driver only supports 1 device\n");
- return -ENODEV;
- }
+ edev = devm_kzalloc(&pdev->dev, sizeof(*edev), GFP_KERNEL);
+ if (!edev)
+ return -ENOMEM;
/* Check whether or not the hardware watchdog is there */
- if (!esb_getdevice(pdev) || esb_pci == NULL)
+ edev->pdev = pdev;
+ if (!esb_getdevice(edev))
return -ENODEV;
- /* Check that the heartbeat value is within it's range;
- if not reset to the default */
- if (heartbeat < 0x1 || heartbeat > 2 * 0x03ff) {
- heartbeat = WATCHDOG_HEARTBEAT;
- pr_info("heartbeat value must be 1<heartbeat<2046, using %d\n",
- heartbeat);
- }
-
/* Initialize the watchdog and make sure it does not run */
- esb_initdevice();
+ edev->wdd.info = &esb_info;
+ edev->wdd.ops = &esb_ops;
+ edev->wdd.min_timeout = ESB_HEARTBEAT_MIN;
+ edev->wdd.max_timeout = ESB_HEARTBEAT_MAX;
+ edev->wdd.timeout = ESB_HEARTBEAT_DEFAULT;
+ if (watchdog_init_timeout(&edev->wdd, heartbeat, NULL))
+ dev_info(&pdev->dev,
+ "heartbeat value must be " ESB_HEARTBEAT_RANGE
+ ", using %u\n", edev->wdd.timeout);
+ watchdog_set_nowayout(&edev->wdd, nowayout);
+ watchdog_stop_on_reboot(&edev->wdd);
+ watchdog_stop_on_unregister(&edev->wdd);
+ esb_initdevice(edev);
/* Register the watchdog so that userspace has access to it */
- ret = misc_register(&esb_miscdev);
+ ret = watchdog_register_device(&edev->wdd);
if (ret != 0) {
- pr_err("cannot register miscdev on minor=%d (err=%d)\n",
- WATCHDOG_MINOR, ret);
+ dev_err(&pdev->dev,
+ "cannot register watchdog device (err=%d)\n", ret);
goto err_unmap;
}
- pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
- BASEADDR, heartbeat, nowayout);
+ dev_info(&pdev->dev,
+ "initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
+ edev->base, edev->wdd.timeout, nowayout);
return 0;
err_unmap:
- iounmap(BASEADDR);
- pci_release_region(esb_pci, 0);
- pci_disable_device(esb_pci);
- esb_pci = NULL;
+ iounmap(edev->base);
+ pci_release_region(edev->pdev, 0);
+ pci_disable_device(edev->pdev);
return ret;
}
static void esb_remove(struct pci_dev *pdev)
{
- /* Stop the timer before we leave */
- if (!nowayout)
- esb_timer_stop();
-
- /* Deregister */
- misc_deregister(&esb_miscdev);
- iounmap(BASEADDR);
- pci_release_region(esb_pci, 0);
- pci_disable_device(esb_pci);
- esb_pci = NULL;
-}
+ struct esb_dev *edev = dev_get_drvdata(&pdev->dev);
-static void esb_shutdown(struct pci_dev *pdev)
-{
- esb_timer_stop();
+ watchdog_unregister_device(&edev->wdd);
+ iounmap(edev->base);
+ pci_release_region(edev->pdev, 0);
+ pci_disable_device(edev->pdev);
}
static struct pci_driver esb_driver = {
@@ -488,7 +354,6 @@ static struct pci_driver esb_driver = {
.id_table = esb_pci_tbl,
.probe = esb_probe,
.remove = esb_remove,
- .shutdown = esb_shutdown,
};
module_pci_driver(esb_driver);
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
index f2e4e1eeb8dd..cc262284a6aa 100644
--- a/drivers/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
@@ -218,7 +218,7 @@ static long ibwdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if (ibwdt_set_heartbeat(new_margin))
return -EINVAL;
ibwdt_ping();
- /* Fall */
+ /* fall through */
case WDIOC_GETTIMEOUT:
return put_user(timeout, p);
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 4874b0f18650..518dfa1047cb 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -169,15 +169,21 @@ static int imx2_wdt_ping(struct watchdog_device *wdog)
return 0;
}
-static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
- unsigned int new_timeout)
+static void __imx2_wdt_set_timeout(struct watchdog_device *wdog,
+ unsigned int new_timeout)
{
struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
- wdog->timeout = new_timeout;
-
regmap_update_bits(wdev->regmap, IMX2_WDT_WCR, IMX2_WDT_WCR_WT,
WDOG_SEC_TO_COUNT(new_timeout));
+}
+
+static int imx2_wdt_set_timeout(struct watchdog_device *wdog,
+ unsigned int new_timeout)
+{
+ __imx2_wdt_set_timeout(wdog, new_timeout);
+
+ wdog->timeout = new_timeout;
return 0;
}
@@ -371,7 +377,11 @@ static int imx2_wdt_suspend(struct device *dev)
/* The watchdog IP block is running */
if (imx2_wdt_is_running(wdev)) {
- imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME);
+ /*
+ * Don't update wdog->timeout, we'll restore the current value
+ * during resume.
+ */
+ __imx2_wdt_set_timeout(wdog, IMX2_WDT_MAX_TIME);
imx2_wdt_ping(wdog);
}
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c
index 20627f22baf6..aafbeb96561b 100644
--- a/drivers/watchdog/jz4740_wdt.c
+++ b/drivers/watchdog/jz4740_wdt.c
@@ -146,6 +146,7 @@ static const struct watchdog_ops jz4740_wdt_ops = {
#ifdef CONFIG_OF
static const struct of_device_id jz4740_wdt_of_matches[] = {
{ .compatible = "ingenic,jz4740-watchdog", },
+ { .compatible = "ingenic,jz4780-watchdog", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, jz4740_wdt_of_matches);
diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c
index ea60b29494fb..b8194b02abe0 100644
--- a/drivers/watchdog/mei_wdt.c
+++ b/drivers/watchdog/mei_wdt.c
@@ -526,12 +526,11 @@ static ssize_t mei_dbgfs_read_state(struct file *file, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
struct mei_wdt *wdt = file->private_data;
- const size_t bufsz = 32;
- char buf[bufsz];
+ char buf[32];
ssize_t pos;
- pos = scnprintf(buf, bufsz, "state: %s\n",
- mei_wdt_state_str(wdt->state));
+ pos = scnprintf(buf, sizeof(buf), "state: %s\n",
+ mei_wdt_state_str(wdt->state));
return simple_read_from_buffer(ubuf, cnt, ppos, buf, pos);
}
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index 6610e9217dbc..aca2d6323f8a 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -22,7 +22,6 @@
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/timer.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/module.h>
@@ -31,10 +30,13 @@
#include <linux/uaccess.h>
#include <sysdev/fsl_soc.h>
+#define WATCHDOG_TIMEOUT 10
+
struct mpc8xxx_wdt {
__be32 res0;
__be32 swcrr; /* System watchdog control register */
#define SWCRR_SWTC 0xFFFF0000 /* Software Watchdog Time Count. */
+#define SWCRR_SWF 0x00000008 /* Software Watchdog Freeze (mpc8xx). */
#define SWCRR_SWEN 0x00000004 /* Watchdog Enable bit. */
#define SWCRR_SWRI 0x00000002 /* Software Watchdog Reset/Interrupt Select bit.*/
#define SWCRR_SWPR 0x00000001 /* Software Watchdog Counter Prescale bit. */
@@ -52,14 +54,15 @@ struct mpc8xxx_wdt_type {
struct mpc8xxx_wdt_ddata {
struct mpc8xxx_wdt __iomem *base;
struct watchdog_device wdd;
- struct timer_list timer;
spinlock_t lock;
+ u16 swtc;
};
-static u16 timeout = 0xffff;
+static u16 timeout;
module_param(timeout, ushort, 0);
MODULE_PARM_DESC(timeout,
- "Watchdog timeout in ticks. (0<timeout<65536, default=65535)");
+ "Watchdog timeout in seconds. (1<timeout<65535, default="
+ __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
static bool reset = 1;
module_param(reset, bool, 0);
@@ -80,31 +83,27 @@ static void mpc8xxx_wdt_keepalive(struct mpc8xxx_wdt_ddata *ddata)
spin_unlock(&ddata->lock);
}
-static void mpc8xxx_wdt_timer_ping(struct timer_list *t)
-{
- struct mpc8xxx_wdt_ddata *ddata = from_timer(ddata, t, timer);
-
- mpc8xxx_wdt_keepalive(ddata);
- /* We're pinging it twice faster than needed, just to be sure. */
- mod_timer(&ddata->timer, jiffies + HZ * ddata->wdd.timeout / 2);
-}
-
static int mpc8xxx_wdt_start(struct watchdog_device *w)
{
struct mpc8xxx_wdt_ddata *ddata =
container_of(w, struct mpc8xxx_wdt_ddata, wdd);
-
- u32 tmp = SWCRR_SWEN | SWCRR_SWPR;
+ u32 tmp = in_be32(&ddata->base->swcrr);
/* Good, fire up the show */
+ tmp &= ~(SWCRR_SWTC | SWCRR_SWF | SWCRR_SWEN | SWCRR_SWRI | SWCRR_SWPR);
+ tmp |= SWCRR_SWEN | SWCRR_SWPR | (ddata->swtc << 16);
+
if (reset)
tmp |= SWCRR_SWRI;
- tmp |= timeout << 16;
-
out_be32(&ddata->base->swcrr, tmp);
- del_timer_sync(&ddata->timer);
+ tmp = in_be32(&ddata->base->swcrr);
+ if (!(tmp & SWCRR_SWEN))
+ return -EOPNOTSUPP;
+
+ ddata->swtc = tmp >> 16;
+ set_bit(WDOG_HW_RUNNING, &ddata->wdd.status);
return 0;
}
@@ -118,17 +117,8 @@ static int mpc8xxx_wdt_ping(struct watchdog_device *w)
return 0;
}
-static int mpc8xxx_wdt_stop(struct watchdog_device *w)
-{
- struct mpc8xxx_wdt_ddata *ddata =
- container_of(w, struct mpc8xxx_wdt_ddata, wdd);
-
- mod_timer(&ddata->timer, jiffies);
- return 0;
-}
-
static struct watchdog_info mpc8xxx_wdt_info = {
- .options = WDIOF_KEEPALIVEPING,
+ .options = WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT,
.firmware_version = 1,
.identity = "MPC8xxx",
};
@@ -137,7 +127,6 @@ static struct watchdog_ops mpc8xxx_wdt_ops = {
.owner = THIS_MODULE,
.start = mpc8xxx_wdt_start,
.ping = mpc8xxx_wdt_ping,
- .stop = mpc8xxx_wdt_stop,
};
static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
@@ -148,7 +137,6 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
struct mpc8xxx_wdt_ddata *ddata;
u32 freq = fsl_get_sys_freq();
bool enabled;
- unsigned int timeout_sec;
wdt_type = of_device_get_match_data(&ofdev->dev);
if (!wdt_type)
@@ -173,26 +161,17 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
}
spin_lock_init(&ddata->lock);
- timer_setup(&ddata->timer, mpc8xxx_wdt_timer_ping, 0);
ddata->wdd.info = &mpc8xxx_wdt_info,
ddata->wdd.ops = &mpc8xxx_wdt_ops,
- /* Calculate the timeout in seconds */
- timeout_sec = (timeout * wdt_type->prescaler) / freq;
-
- ddata->wdd.timeout = timeout_sec;
+ ddata->wdd.timeout = WATCHDOG_TIMEOUT;
+ watchdog_init_timeout(&ddata->wdd, timeout, &ofdev->dev);
watchdog_set_nowayout(&ddata->wdd, nowayout);
- ret = watchdog_register_device(&ddata->wdd);
- if (ret) {
- pr_err("cannot register watchdog device (err=%d)\n", ret);
- return ret;
- }
-
- pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d (%d seconds)\n",
- reset ? "reset" : "interrupt", timeout, timeout_sec);
+ ddata->swtc = min(ddata->wdd.timeout * freq / wdt_type->prescaler,
+ 0xffffU);
/*
* If the watchdog was previously enabled or we're running on
@@ -200,7 +179,22 @@ static int mpc8xxx_wdt_probe(struct platform_device *ofdev)
* userspace handles it.
*/
if (enabled)
- mod_timer(&ddata->timer, jiffies);
+ mpc8xxx_wdt_start(&ddata->wdd);
+
+ ddata->wdd.max_hw_heartbeat_ms = (ddata->swtc * wdt_type->prescaler) /
+ (freq / 1000);
+ ddata->wdd.min_timeout = ddata->wdd.max_hw_heartbeat_ms / 1000;
+ if (ddata->wdd.timeout < ddata->wdd.min_timeout)
+ ddata->wdd.timeout = ddata->wdd.min_timeout;
+
+ ret = watchdog_register_device(&ddata->wdd);
+ if (ret) {
+ pr_err("cannot register watchdog device (err=%d)\n", ret);
+ return ret;
+ }
+
+ pr_info("WDT driver for MPC8xxx initialized. mode:%s timeout=%d sec\n",
+ reset ? "reset" : "interrupt", ddata->wdd.timeout);
platform_set_drvdata(ofdev, ddata);
return 0;
@@ -212,7 +206,6 @@ static int mpc8xxx_wdt_remove(struct platform_device *ofdev)
pr_crit("Watchdog removed, expect the %s soon!\n",
reset ? "reset" : "machine check exception");
- del_timer_sync(&ddata->timer);
watchdog_unregister_device(&ddata->wdd);
return 0;
diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c
index db38f8017218..5c4a764717c4 100644
--- a/drivers/watchdog/mt7621_wdt.c
+++ b/drivers/watchdog/mt7621_wdt.c
@@ -105,6 +105,11 @@ static int mt7621_wdt_bootcause(void)
return 0;
}
+static int mt7621_wdt_is_running(struct watchdog_device *w)
+{
+ return !!(rt_wdt_r32(TIMER_REG_TMR1CTL) & TMR1CTL_ENABLE);
+}
+
static const struct watchdog_info mt7621_wdt_info = {
.identity = "Mediatek Watchdog",
.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
@@ -128,7 +133,6 @@ static struct watchdog_device mt7621_wdt_dev = {
static int mt7621_wdt_probe(struct platform_device *pdev)
{
struct resource *res;
- int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mt7621_wdt_base = devm_ioremap_resource(&pdev->dev, res);
@@ -144,17 +148,22 @@ static int mt7621_wdt_probe(struct platform_device *pdev)
watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout,
&pdev->dev);
watchdog_set_nowayout(&mt7621_wdt_dev, nowayout);
-
- ret = watchdog_register_device(&mt7621_wdt_dev);
-
- return 0;
-}
-
-static int mt7621_wdt_remove(struct platform_device *pdev)
-{
- watchdog_unregister_device(&mt7621_wdt_dev);
-
- return 0;
+ if (mt7621_wdt_is_running(&mt7621_wdt_dev)) {
+ /*
+ * Make sure to apply timeout from watchdog core, taking
+ * the prescaler of this driver here into account (the
+ * boot loader might be using a different prescaler).
+ *
+ * To avoid spurious resets because of different scaling,
+ * we first disable the watchdog, set the new prescaler
+ * and timeout, and then re-enable the watchdog.
+ */
+ mt7621_wdt_stop(&mt7621_wdt_dev);
+ mt7621_wdt_start(&mt7621_wdt_dev);
+ set_bit(WDOG_HW_RUNNING, &mt7621_wdt_dev.status);
+ }
+
+ return devm_watchdog_register_device(&pdev->dev, &mt7621_wdt_dev);
}
static void mt7621_wdt_shutdown(struct platform_device *pdev)
@@ -170,7 +179,6 @@ MODULE_DEVICE_TABLE(of, mt7621_wdt_match);
static struct platform_driver mt7621_wdt_driver = {
.probe = mt7621_wdt_probe,
- .remove = mt7621_wdt_remove,
.shutdown = mt7621_wdt_shutdown,
.driver = {
.name = KBUILD_MODNAME,
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c
index 83af7d6cc37c..ea676d233e1e 100644
--- a/drivers/watchdog/orion_wdt.c
+++ b/drivers/watchdog/orion_wdt.c
@@ -576,7 +576,7 @@ static int orion_wdt_probe(struct platform_device *pdev)
/*
* Let's make sure the watchdog is fully stopped, unless it's
* explicitly enabled. This may be the case if the module was
- * removed and re-insterted, or if the bootloader explicitly
+ * removed and re-inserted, or if the bootloader explicitly
* set a running watchdog before booting the kernel.
*/
if (!orion_wdt_enabled(&dev->wdt))
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c
index c0d07eef2640..1f78f0908621 100644
--- a/drivers/watchdog/pcwd_pci.c
+++ b/drivers/watchdog/pcwd_pci.c
@@ -545,8 +545,8 @@ static long pcipcwd_ioctl(struct file *file, unsigned int cmd,
return -EINVAL;
pcipcwd_keepalive();
- /* Fall */
}
+ /* fall through */
case WDIOC_GETTIMEOUT:
return put_user(heartbeat, p);
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c
index b9e376c8e2e3..4d02f26156f9 100644
--- a/drivers/watchdog/pcwd_usb.c
+++ b/drivers/watchdog/pcwd_usb.c
@@ -49,12 +49,11 @@
#define DRIVER_VERSION "1.02"
#define DRIVER_AUTHOR "Wim Van Sebroeck <wim@iguana.be>"
#define DRIVER_DESC "Berkshire USB-PC Watchdog driver"
-#define DRIVER_LICENSE "GPL"
#define DRIVER_NAME "pcwd_usb"
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENSE);
+MODULE_LICENSE("GPL");
#define WATCHDOG_HEARTBEAT 0 /* default heartbeat =
delay-time from dip-switches */
@@ -456,8 +455,8 @@ static long usb_pcwd_ioctl(struct file *file, unsigned int cmd,
return -EINVAL;
usb_pcwd_keepalive(usb_pcwd_device);
- /* Fall */
}
+ /* fall through */
case WDIOC_GETTIMEOUT:
return put_user(heartbeat, p);
diff --git a/drivers/watchdog/rtd119x_wdt.c b/drivers/watchdog/rtd119x_wdt.c
new file mode 100644
index 000000000000..d001c17ddfde
--- /dev/null
+++ b/drivers/watchdog/rtd119x_wdt.c
@@ -0,0 +1,168 @@
+/*
+ * Realtek RTD129x watchdog
+ *
+ * Copyright (c) 2017 Andreas Färber
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+
+#define RTD119X_TCWCR 0x0
+#define RTD119X_TCWTR 0x4
+#define RTD119X_TCWOV 0xc
+
+#define RTD119X_TCWCR_WDEN_DISABLED 0xa5
+#define RTD119X_TCWCR_WDEN_ENABLED 0xff
+#define RTD119X_TCWCR_WDEN_MASK 0xff
+
+#define RTD119X_TCWTR_WDCLR BIT(0)
+
+struct rtd119x_watchdog_device {
+ struct watchdog_device wdt_dev;
+ void __iomem *base;
+ struct clk *clk;
+};
+
+static int rtd119x_wdt_start(struct watchdog_device *wdev)
+{
+ struct rtd119x_watchdog_device *data = watchdog_get_drvdata(wdev);
+ u32 val;
+
+ val = readl_relaxed(data->base + RTD119X_TCWCR);
+ val &= ~RTD119X_TCWCR_WDEN_MASK;
+ val |= RTD119X_TCWCR_WDEN_ENABLED;
+ writel(val, data->base + RTD119X_TCWCR);
+
+ return 0;
+}
+
+static int rtd119x_wdt_stop(struct watchdog_device *wdev)
+{
+ struct rtd119x_watchdog_device *data = watchdog_get_drvdata(wdev);
+ u32 val;
+
+ val = readl_relaxed(data->base + RTD119X_TCWCR);
+ val &= ~RTD119X_TCWCR_WDEN_MASK;
+ val |= RTD119X_TCWCR_WDEN_DISABLED;
+ writel(val, data->base + RTD119X_TCWCR);
+
+ return 0;
+}
+
+static int rtd119x_wdt_ping(struct watchdog_device *wdev)
+{
+ struct rtd119x_watchdog_device *data = watchdog_get_drvdata(wdev);
+
+ writel_relaxed(RTD119X_TCWTR_WDCLR, data->base + RTD119X_TCWTR);
+
+ return rtd119x_wdt_start(wdev);
+}
+
+static int rtd119x_wdt_set_timeout(struct watchdog_device *wdev, unsigned int val)
+{
+ struct rtd119x_watchdog_device *data = watchdog_get_drvdata(wdev);
+
+ writel(val * clk_get_rate(data->clk), data->base + RTD119X_TCWOV);
+
+ data->wdt_dev.timeout = val;
+
+ return 0;
+}
+
+static const struct watchdog_ops rtd119x_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = rtd119x_wdt_start,
+ .stop = rtd119x_wdt_stop,
+ .ping = rtd119x_wdt_ping,
+ .set_timeout = rtd119x_wdt_set_timeout,
+};
+
+static const struct watchdog_info rtd119x_wdt_info = {
+ .identity = "rtd119x-wdt",
+ .options = 0,
+};
+
+static const struct of_device_id rtd119x_wdt_dt_ids[] = {
+ { .compatible = "realtek,rtd1295-watchdog" },
+ { }
+};
+
+static int rtd119x_wdt_probe(struct platform_device *pdev)
+{
+ struct rtd119x_watchdog_device *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->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(data->base))
+ return PTR_ERR(data->base);
+
+ data->clk = of_clk_get(pdev->dev.of_node, 0);
+ if (IS_ERR(data->clk))
+ return PTR_ERR(data->clk);
+
+ ret = clk_prepare_enable(data->clk);
+ if (ret) {
+ clk_put(data->clk);
+ return ret;
+ }
+
+ data->wdt_dev.info = &rtd119x_wdt_info;
+ data->wdt_dev.ops = &rtd119x_wdt_ops;
+ data->wdt_dev.timeout = 120;
+ data->wdt_dev.max_timeout = 0xffffffff / clk_get_rate(data->clk);
+ data->wdt_dev.min_timeout = 1;
+ data->wdt_dev.parent = &pdev->dev;
+
+ watchdog_stop_on_reboot(&data->wdt_dev);
+ watchdog_set_drvdata(&data->wdt_dev, data);
+ platform_set_drvdata(pdev, data);
+
+ writel_relaxed(RTD119X_TCWTR_WDCLR, data->base + RTD119X_TCWTR);
+ rtd119x_wdt_set_timeout(&data->wdt_dev, data->wdt_dev.timeout);
+ rtd119x_wdt_stop(&data->wdt_dev);
+
+ ret = devm_watchdog_register_device(&pdev->dev, &data->wdt_dev);
+ if (ret) {
+ clk_disable_unprepare(data->clk);
+ clk_put(data->clk);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int rtd119x_wdt_remove(struct platform_device *pdev)
+{
+ struct rtd119x_watchdog_device *data = platform_get_drvdata(pdev);
+
+ watchdog_unregister_device(&data->wdt_dev);
+
+ clk_disable_unprepare(data->clk);
+ clk_put(data->clk);
+
+ return 0;
+}
+
+static struct platform_driver rtd119x_wdt_driver = {
+ .probe = rtd119x_wdt_probe,
+ .remove = rtd119x_wdt_remove,
+ .driver = {
+ .name = "rtd1295-watchdog",
+ .of_match_table = rtd119x_wdt_dt_ids,
+ },
+};
+builtin_platform_driver(rtd119x_wdt_driver);
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index 028618c5eeba..41aaae2d5287 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -16,6 +16,11 @@
* See AMD Publication 43009 "AMD SB700/710/750 Register Reference Guide",
* AMD Publication 45482 "AMD SB800-Series Southbridges Register
* Reference Guide"
+ * AMD Publication 48751 "BIOS and Kernel Developer’s Guide (BKDG)
+ * for AMD Family 16h Models 00h-0Fh Processors"
+ * AMD Publication 51192 "AMD Bolton FCH Register Reference Guide"
+ * AMD Publication 52740 "BIOS and Kernel Developer’s Guide (BKDG)
+ * for AMD Family 16h Models 30h-3Fh Processors"
*/
/*
@@ -24,38 +29,36 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/miscdevice.h>
-#include <linux/watchdog.h>
-#include <linux/init.h>
-#include <linux/fs.h>
#include <linux/pci.h>
-#include <linux/ioport.h>
#include <linux/platform_device.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
#include "sp5100_tco.h"
-/* Module and version information */
-#define TCO_VERSION "0.05"
-#define TCO_MODULE_NAME "SP5100 TCO timer"
-#define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION
+#define TCO_DRIVER_NAME "sp5100-tco"
/* internal variables */
-static u32 tcobase_phys;
-static u32 tco_wdt_fired;
-static void __iomem *tcobase;
-static unsigned int pm_iobase;
-static DEFINE_SPINLOCK(tco_lock); /* Guards the hardware */
-static unsigned long timer_alive;
-static char tco_expect_close;
-static struct pci_dev *sp5100_tco_pci;
+
+enum tco_reg_layout {
+ sp5100, sb800, efch
+};
+
+struct sp5100_tco {
+ struct watchdog_device wdd;
+ void __iomem *tcobase;
+ enum tco_reg_layout tco_reg_layout;
+};
/* the watchdog platform device */
static struct platform_device *sp5100_tco_platform_device;
+/* the associated PCI device */
+static struct pci_dev *sp5100_tco_pci;
/* module parameters */
@@ -74,83 +77,105 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started."
* Some TCO specific functions
*/
-static bool tco_has_sp5100_reg_layout(struct pci_dev *dev)
+static enum tco_reg_layout tco_reg_layout(struct pci_dev *dev)
{
- return dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
- dev->revision < 0x40;
+ if (dev->vendor == PCI_VENDOR_ID_ATI &&
+ dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
+ dev->revision < 0x40) {
+ return sp5100;
+ } else if (dev->vendor == PCI_VENDOR_ID_AMD &&
+ ((dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
+ dev->revision >= 0x41) ||
+ (dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS &&
+ dev->revision >= 0x49))) {
+ return efch;
+ }
+ return sb800;
}
-static void tco_timer_start(void)
+static int tco_timer_start(struct watchdog_device *wdd)
{
+ struct sp5100_tco *tco = watchdog_get_drvdata(wdd);
u32 val;
- unsigned long flags;
- spin_lock_irqsave(&tco_lock, flags);
- val = readl(SP5100_WDT_CONTROL(tcobase));
+ val = readl(SP5100_WDT_CONTROL(tco->tcobase));
val |= SP5100_WDT_START_STOP_BIT;
- writel(val, SP5100_WDT_CONTROL(tcobase));
- spin_unlock_irqrestore(&tco_lock, flags);
+ writel(val, SP5100_WDT_CONTROL(tco->tcobase));
+
+ return 0;
}
-static void tco_timer_stop(void)
+static int tco_timer_stop(struct watchdog_device *wdd)
{
+ struct sp5100_tco *tco = watchdog_get_drvdata(wdd);
u32 val;
- unsigned long flags;
- spin_lock_irqsave(&tco_lock, flags);
- val = readl(SP5100_WDT_CONTROL(tcobase));
+ val = readl(SP5100_WDT_CONTROL(tco->tcobase));
val &= ~SP5100_WDT_START_STOP_BIT;
- writel(val, SP5100_WDT_CONTROL(tcobase));
- spin_unlock_irqrestore(&tco_lock, flags);
+ writel(val, SP5100_WDT_CONTROL(tco->tcobase));
+
+ return 0;
}
-static void tco_timer_keepalive(void)
+static int tco_timer_ping(struct watchdog_device *wdd)
{
+ struct sp5100_tco *tco = watchdog_get_drvdata(wdd);
u32 val;
- unsigned long flags;
- spin_lock_irqsave(&tco_lock, flags);
- val = readl(SP5100_WDT_CONTROL(tcobase));
+ val = readl(SP5100_WDT_CONTROL(tco->tcobase));
val |= SP5100_WDT_TRIGGER_BIT;
- writel(val, SP5100_WDT_CONTROL(tcobase));
- spin_unlock_irqrestore(&tco_lock, flags);
+ writel(val, SP5100_WDT_CONTROL(tco->tcobase));
+
+ return 0;
}
-static int tco_timer_set_heartbeat(int t)
+static int tco_timer_set_timeout(struct watchdog_device *wdd,
+ unsigned int t)
{
- unsigned long flags;
-
- if (t < 0 || t > 0xffff)
- return -EINVAL;
+ struct sp5100_tco *tco = watchdog_get_drvdata(wdd);
/* Write new heartbeat to watchdog */
- spin_lock_irqsave(&tco_lock, flags);
- writel(t, SP5100_WDT_COUNT(tcobase));
- spin_unlock_irqrestore(&tco_lock, flags);
+ writel(t, SP5100_WDT_COUNT(tco->tcobase));
+
+ wdd->timeout = t;
- heartbeat = t;
return 0;
}
-static void tco_timer_enable(void)
+static u8 sp5100_tco_read_pm_reg8(u8 index)
+{
+ outb(index, SP5100_IO_PM_INDEX_REG);
+ return inb(SP5100_IO_PM_DATA_REG);
+}
+
+static void sp5100_tco_update_pm_reg8(u8 index, u8 reset, u8 set)
+{
+ u8 val;
+
+ outb(index, SP5100_IO_PM_INDEX_REG);
+ val = inb(SP5100_IO_PM_DATA_REG);
+ val &= reset;
+ val |= set;
+ outb(val, SP5100_IO_PM_DATA_REG);
+}
+
+static void tco_timer_enable(struct sp5100_tco *tco)
{
- int val;
+ u32 val;
- if (!tco_has_sp5100_reg_layout(sp5100_tco_pci)) {
+ switch (tco->tco_reg_layout) {
+ case sb800:
/* For SB800 or later */
/* Set the Watchdog timer resolution to 1 sec */
- outb(SB800_PM_WATCHDOG_CONFIG, SB800_IO_PM_INDEX_REG);
- val = inb(SB800_IO_PM_DATA_REG);
- val |= SB800_PM_WATCHDOG_SECOND_RES;
- outb(val, SB800_IO_PM_DATA_REG);
+ sp5100_tco_update_pm_reg8(SB800_PM_WATCHDOG_CONFIG,
+ 0xff, SB800_PM_WATCHDOG_SECOND_RES);
/* Enable watchdog decode bit and watchdog timer */
- outb(SB800_PM_WATCHDOG_CONTROL, SB800_IO_PM_INDEX_REG);
- val = inb(SB800_IO_PM_DATA_REG);
- val |= SB800_PCI_WATCHDOG_DECODE_EN;
- val &= ~SB800_PM_WATCHDOG_DISABLE;
- outb(val, SB800_IO_PM_DATA_REG);
- } else {
+ sp5100_tco_update_pm_reg8(SB800_PM_WATCHDOG_CONTROL,
+ ~SB800_PM_WATCHDOG_DISABLE,
+ SB800_PCI_WATCHDOG_DECODE_EN);
+ break;
+ case sp5100:
/* For SP5100 or SB7x0 */
/* Enable watchdog decode bit */
pci_read_config_dword(sp5100_tco_pci,
@@ -164,409 +189,287 @@ static void tco_timer_enable(void)
val);
/* Enable Watchdog timer and set the resolution to 1 sec */
- outb(SP5100_PM_WATCHDOG_CONTROL, SP5100_IO_PM_INDEX_REG);
- val = inb(SP5100_IO_PM_DATA_REG);
- val |= SP5100_PM_WATCHDOG_SECOND_RES;
- val &= ~SP5100_PM_WATCHDOG_DISABLE;
- outb(val, SP5100_IO_PM_DATA_REG);
+ sp5100_tco_update_pm_reg8(SP5100_PM_WATCHDOG_CONTROL,
+ ~SP5100_PM_WATCHDOG_DISABLE,
+ SP5100_PM_WATCHDOG_SECOND_RES);
+ break;
+ case efch:
+ /* Set the Watchdog timer resolution to 1 sec and enable */
+ sp5100_tco_update_pm_reg8(EFCH_PM_DECODEEN3,
+ ~EFCH_PM_WATCHDOG_DISABLE,
+ EFCH_PM_DECODEEN_SECOND_RES);
+ break;
}
}
-/*
- * /dev/watchdog handling
- */
-
-static int sp5100_tco_open(struct inode *inode, struct file *file)
+static u32 sp5100_tco_read_pm_reg32(u8 index)
{
- /* /dev/watchdog can only be opened once */
- if (test_and_set_bit(0, &timer_alive))
- return -EBUSY;
-
- /* Reload and activate timer */
- tco_timer_start();
- tco_timer_keepalive();
- return nonseekable_open(inode, file);
-}
-
-static int sp5100_tco_release(struct inode *inode, struct file *file)
-{
- /* Shut off the timer. */
- if (tco_expect_close == 42) {
- tco_timer_stop();
- } else {
- pr_crit("Unexpected close, not stopping watchdog!\n");
- tco_timer_keepalive();
- }
- clear_bit(0, &timer_alive);
- tco_expect_close = 0;
- return 0;
-}
-
-static ssize_t sp5100_tco_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
-{
- /* See if we got the magic character 'V' and reload the timer */
- if (len) {
- if (!nowayout) {
- size_t i;
-
- /* note: just in case someone wrote the magic character
- * five months ago... */
- tco_expect_close = 0;
+ u32 val = 0;
+ int i;
- /* scan to see whether or not we got the magic character
- */
- for (i = 0; i != len; i++) {
- char c;
- if (get_user(c, data + i))
- return -EFAULT;
- if (c == 'V')
- tco_expect_close = 42;
- }
- }
+ for (i = 3; i >= 0; i--)
+ val = (val << 8) + sp5100_tco_read_pm_reg8(index + i);
- /* someone wrote to us, we should reload the timer */
- tco_timer_keepalive();
- }
- return len;
+ return val;
}
-static long sp5100_tco_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
+static int sp5100_tco_setupdevice(struct device *dev,
+ struct watchdog_device *wdd)
{
- int new_options, retval = -EINVAL;
- int new_heartbeat;
- void __user *argp = (void __user *)arg;
- int __user *p = argp;
- static const struct watchdog_info ident = {
- .options = WDIOF_SETTIMEOUT |
- WDIOF_KEEPALIVEPING |
- WDIOF_MAGICCLOSE,
- .firmware_version = 0,
- .identity = TCO_MODULE_NAME,
- };
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- return copy_to_user(argp, &ident,
- sizeof(ident)) ? -EFAULT : 0;
- case WDIOC_GETSTATUS:
- case WDIOC_GETBOOTSTATUS:
- return put_user(0, p);
- case WDIOC_SETOPTIONS:
- if (get_user(new_options, p))
- return -EFAULT;
- if (new_options & WDIOS_DISABLECARD) {
- tco_timer_stop();
- retval = 0;
- }
- if (new_options & WDIOS_ENABLECARD) {
- tco_timer_start();
- tco_timer_keepalive();
- retval = 0;
- }
- return retval;
- case WDIOC_KEEPALIVE:
- tco_timer_keepalive();
- return 0;
- case WDIOC_SETTIMEOUT:
- if (get_user(new_heartbeat, p))
- return -EFAULT;
- if (tco_timer_set_heartbeat(new_heartbeat))
- return -EINVAL;
- tco_timer_keepalive();
- /* Fall through */
- case WDIOC_GETTIMEOUT:
- return put_user(heartbeat, p);
- default:
- return -ENOTTY;
- }
-}
-
-/*
- * Kernel Interfaces
- */
-
-static const struct file_operations sp5100_tco_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = sp5100_tco_write,
- .unlocked_ioctl = sp5100_tco_ioctl,
- .open = sp5100_tco_open,
- .release = sp5100_tco_release,
-};
-
-static struct miscdevice sp5100_tco_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &sp5100_tco_fops,
-};
-
-/*
- * Data for PCI driver interface
- *
- * This data only exists for exporting the supported
- * PCI ids via MODULE_DEVICE_TABLE. We do not actually
- * register a pci_driver, because someone else might
- * want to register another driver on the same PCI id.
- */
-static const struct pci_device_id sp5100_tco_pci_tbl[] = {
- { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, PCI_ANY_ID,
- PCI_ANY_ID, },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, PCI_ANY_ID,
- PCI_ANY_ID, },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, PCI_ANY_ID,
- PCI_ANY_ID, },
- { 0, }, /* End of list */
-};
-MODULE_DEVICE_TABLE(pci, sp5100_tco_pci_tbl);
-
-/*
- * Init & exit routines
- */
-static unsigned char sp5100_tco_setupdevice(void)
-{
- struct pci_dev *dev = NULL;
- const char *dev_name = NULL;
- u32 val;
- u32 index_reg, data_reg, base_addr;
+ struct sp5100_tco *tco = watchdog_get_drvdata(wdd);
+ const char *dev_name;
+ u32 mmio_addr = 0, val;
+ int ret;
- /* Match the PCI device */
- for_each_pci_dev(dev) {
- if (pci_match_id(sp5100_tco_pci_tbl, dev) != NULL) {
- sp5100_tco_pci = dev;
- break;
- }
+ /* Request the IO ports used by this driver */
+ if (!request_muxed_region(SP5100_IO_PM_INDEX_REG,
+ SP5100_PM_IOPORTS_SIZE, "sp5100_tco")) {
+ dev_err(dev, "I/O address 0x%04x already in use\n",
+ SP5100_IO_PM_INDEX_REG);
+ return -EBUSY;
}
- if (!sp5100_tco_pci)
- return 0;
-
- pr_info("PCI Vendor ID: 0x%x, Device ID: 0x%x, Revision ID: 0x%x\n",
- sp5100_tco_pci->vendor, sp5100_tco_pci->device,
- sp5100_tco_pci->revision);
-
/*
* Determine type of southbridge chipset.
*/
- if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) {
+ switch (tco->tco_reg_layout) {
+ case sp5100:
dev_name = SP5100_DEVNAME;
- index_reg = SP5100_IO_PM_INDEX_REG;
- data_reg = SP5100_IO_PM_DATA_REG;
- base_addr = SP5100_PM_WATCHDOG_BASE;
- } else {
+ mmio_addr = sp5100_tco_read_pm_reg32(SP5100_PM_WATCHDOG_BASE) &
+ 0xfffffff8;
+ break;
+ case sb800:
dev_name = SB800_DEVNAME;
- index_reg = SB800_IO_PM_INDEX_REG;
- data_reg = SB800_IO_PM_DATA_REG;
- base_addr = SB800_PM_WATCHDOG_BASE;
- }
-
- /* Request the IO ports used by this driver */
- pm_iobase = SP5100_IO_PM_INDEX_REG;
- if (!request_region(pm_iobase, SP5100_PM_IOPORTS_SIZE, dev_name)) {
- pr_err("I/O address 0x%04x already in use\n", pm_iobase);
- goto exit;
+ mmio_addr = sp5100_tco_read_pm_reg32(SB800_PM_WATCHDOG_BASE) &
+ 0xfffffff8;
+ break;
+ case efch:
+ dev_name = SB800_DEVNAME;
+ val = sp5100_tco_read_pm_reg8(EFCH_PM_DECODEEN);
+ if (val & EFCH_PM_DECODEEN_WDT_TMREN)
+ mmio_addr = EFCH_PM_WDT_ADDR;
+ break;
+ default:
+ return -ENODEV;
}
- /*
- * First, Find the watchdog timer MMIO address from indirect I/O.
- */
- outb(base_addr+3, index_reg);
- val = inb(data_reg);
- outb(base_addr+2, index_reg);
- val = val << 8 | inb(data_reg);
- outb(base_addr+1, index_reg);
- val = val << 8 | inb(data_reg);
- outb(base_addr+0, index_reg);
- /* Low three bits of BASE are reserved */
- val = val << 8 | (inb(data_reg) & 0xf8);
-
- pr_debug("Got 0x%04x from indirect I/O\n", val);
-
/* Check MMIO address conflict */
- if (request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
- dev_name))
- goto setup_wdt;
- else
- pr_debug("MMIO address 0x%04x already in use\n", val);
-
- /*
- * Secondly, Find the watchdog timer MMIO address
- * from SBResource_MMIO register.
- */
- if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) {
- /* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */
- pci_read_config_dword(sp5100_tco_pci,
- SP5100_SB_RESOURCE_MMIO_BASE, &val);
- } else {
- /* Read SBResource_MMIO from AcpiMmioEn(PM_Reg: 24h) */
- outb(SB800_PM_ACPI_MMIO_EN+3, SB800_IO_PM_INDEX_REG);
- val = inb(SB800_IO_PM_DATA_REG);
- outb(SB800_PM_ACPI_MMIO_EN+2, SB800_IO_PM_INDEX_REG);
- val = val << 8 | inb(SB800_IO_PM_DATA_REG);
- outb(SB800_PM_ACPI_MMIO_EN+1, SB800_IO_PM_INDEX_REG);
- val = val << 8 | inb(SB800_IO_PM_DATA_REG);
- outb(SB800_PM_ACPI_MMIO_EN+0, SB800_IO_PM_INDEX_REG);
- val = val << 8 | inb(SB800_IO_PM_DATA_REG);
+ if (!mmio_addr ||
+ !devm_request_mem_region(dev, mmio_addr, SP5100_WDT_MEM_MAP_SIZE,
+ dev_name)) {
+ if (mmio_addr)
+ dev_dbg(dev, "MMIO address 0x%08x already in use\n",
+ mmio_addr);
+ switch (tco->tco_reg_layout) {
+ case sp5100:
+ /*
+ * Secondly, Find the watchdog timer MMIO address
+ * from SBResource_MMIO register.
+ */
+ /* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */
+ pci_read_config_dword(sp5100_tco_pci,
+ SP5100_SB_RESOURCE_MMIO_BASE,
+ &mmio_addr);
+ if ((mmio_addr & (SB800_ACPI_MMIO_DECODE_EN |
+ SB800_ACPI_MMIO_SEL)) !=
+ SB800_ACPI_MMIO_DECODE_EN) {
+ ret = -ENODEV;
+ goto unreg_region;
+ }
+ mmio_addr &= ~0xFFF;
+ mmio_addr += SB800_PM_WDT_MMIO_OFFSET;
+ break;
+ case sb800:
+ /* Read SBResource_MMIO from AcpiMmioEn(PM_Reg: 24h) */
+ mmio_addr =
+ sp5100_tco_read_pm_reg32(SB800_PM_ACPI_MMIO_EN);
+ if ((mmio_addr & (SB800_ACPI_MMIO_DECODE_EN |
+ SB800_ACPI_MMIO_SEL)) !=
+ SB800_ACPI_MMIO_DECODE_EN) {
+ ret = -ENODEV;
+ goto unreg_region;
+ }
+ mmio_addr &= ~0xFFF;
+ mmio_addr += SB800_PM_WDT_MMIO_OFFSET;
+ break;
+ case efch:
+ val = sp5100_tco_read_pm_reg8(EFCH_PM_ISACONTROL);
+ if (!(val & EFCH_PM_ISACONTROL_MMIOEN)) {
+ ret = -ENODEV;
+ goto unreg_region;
+ }
+ mmio_addr = EFCH_PM_ACPI_MMIO_ADDR +
+ EFCH_PM_ACPI_MMIO_WDT_OFFSET;
+ break;
+ }
+ dev_dbg(dev, "Got 0x%08x from SBResource_MMIO register\n",
+ mmio_addr);
+ if (!devm_request_mem_region(dev, mmio_addr,
+ SP5100_WDT_MEM_MAP_SIZE,
+ dev_name)) {
+ dev_dbg(dev, "MMIO address 0x%08x already in use\n",
+ mmio_addr);
+ ret = -EBUSY;
+ goto unreg_region;
+ }
}
- /* The SBResource_MMIO is enabled and mapped memory space? */
- if ((val & (SB800_ACPI_MMIO_DECODE_EN | SB800_ACPI_MMIO_SEL)) ==
- SB800_ACPI_MMIO_DECODE_EN) {
- /* Clear unnecessary the low twelve bits */
- val &= ~0xFFF;
- /* Add the Watchdog Timer offset to base address. */
- val += SB800_PM_WDT_MMIO_OFFSET;
- /* Check MMIO address conflict */
- if (request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
- dev_name)) {
- pr_debug("Got 0x%04x from SBResource_MMIO register\n",
- val);
- goto setup_wdt;
- } else
- pr_debug("MMIO address 0x%04x already in use\n", val);
- } else
- pr_debug("SBResource_MMIO is disabled(0x%04x)\n", val);
-
- pr_notice("failed to find MMIO address, giving up.\n");
- goto unreg_region;
-
-setup_wdt:
- tcobase_phys = val;
-
- tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE);
- if (!tcobase) {
- pr_err("failed to get tcobase address\n");
- goto unreg_mem_region;
+ tco->tcobase = devm_ioremap(dev, mmio_addr, SP5100_WDT_MEM_MAP_SIZE);
+ if (!tco->tcobase) {
+ dev_err(dev, "failed to get tcobase address\n");
+ ret = -ENOMEM;
+ goto unreg_region;
}
- pr_info("Using 0x%04x for watchdog MMIO address\n", val);
+ dev_info(dev, "Using 0x%08x for watchdog MMIO address\n", mmio_addr);
/* Setup the watchdog timer */
- tco_timer_enable();
+ tco_timer_enable(tco);
+
+ val = readl(SP5100_WDT_CONTROL(tco->tcobase));
+ if (val & SP5100_WDT_DISABLED) {
+ dev_err(dev, "Watchdog hardware is disabled\n");
+ ret = -ENODEV;
+ goto unreg_region;
+ }
- /* Check that the watchdog action is set to reset the system */
- val = readl(SP5100_WDT_CONTROL(tcobase));
/*
* Save WatchDogFired status, because WatchDogFired flag is
* cleared here.
*/
- tco_wdt_fired = val & SP5100_PM_WATCHDOG_FIRED;
- val &= ~SP5100_PM_WATCHDOG_ACTION_RESET;
- writel(val, SP5100_WDT_CONTROL(tcobase));
+ if (val & SP5100_WDT_FIRED)
+ wdd->bootstatus = WDIOF_CARDRESET;
+ /* Set watchdog action to reset the system */
+ val &= ~SP5100_WDT_ACTION_RESET;
+ writel(val, SP5100_WDT_CONTROL(tco->tcobase));
/* Set a reasonable heartbeat before we stop the timer */
- tco_timer_set_heartbeat(heartbeat);
+ tco_timer_set_timeout(wdd, wdd->timeout);
/*
* Stop the TCO before we change anything so we don't race with
* a zeroed timer.
*/
- tco_timer_stop();
+ tco_timer_stop(wdd);
- /* Done */
- return 1;
+ release_region(SP5100_IO_PM_INDEX_REG, SP5100_PM_IOPORTS_SIZE);
-unreg_mem_region:
- release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
-unreg_region:
- release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
-exit:
return 0;
-}
-static int sp5100_tco_init(struct platform_device *dev)
-{
- int ret;
+unreg_region:
+ release_region(SP5100_IO_PM_INDEX_REG, SP5100_PM_IOPORTS_SIZE);
+ return ret;
+}
- /*
- * Check whether or not the hardware watchdog is there. If found, then
- * set it up.
- */
- if (!sp5100_tco_setupdevice())
- return -ENODEV;
+static struct watchdog_info sp5100_tco_wdt_info = {
+ .identity = "SP5100 TCO timer",
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
+};
- /* Check to see if last reboot was due to watchdog timeout */
- pr_info("Last reboot was %striggered by watchdog.\n",
- tco_wdt_fired ? "" : "not ");
+static const struct watchdog_ops sp5100_tco_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = tco_timer_start,
+ .stop = tco_timer_stop,
+ .ping = tco_timer_ping,
+ .set_timeout = tco_timer_set_timeout,
+};
- /*
- * Check that the heartbeat value is within it's range.
- * If not, reset to the default.
- */
- if (tco_timer_set_heartbeat(heartbeat)) {
- heartbeat = WATCHDOG_HEARTBEAT;
- tco_timer_set_heartbeat(heartbeat);
- }
+static int sp5100_tco_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct watchdog_device *wdd;
+ struct sp5100_tco *tco;
+ int ret;
- ret = misc_register(&sp5100_tco_miscdev);
- if (ret != 0) {
- pr_err("cannot register miscdev on minor=%d (err=%d)\n",
- WATCHDOG_MINOR, ret);
- goto exit;
+ tco = devm_kzalloc(dev, sizeof(*tco), GFP_KERNEL);
+ if (!tco)
+ return -ENOMEM;
+
+ tco->tco_reg_layout = tco_reg_layout(sp5100_tco_pci);
+
+ wdd = &tco->wdd;
+ wdd->parent = dev;
+ wdd->info = &sp5100_tco_wdt_info;
+ wdd->ops = &sp5100_tco_wdt_ops;
+ wdd->timeout = WATCHDOG_HEARTBEAT;
+ wdd->min_timeout = 1;
+ wdd->max_timeout = 0xffff;
+
+ if (watchdog_init_timeout(wdd, heartbeat, NULL))
+ dev_info(dev, "timeout value invalid, using %d\n",
+ wdd->timeout);
+ watchdog_set_nowayout(wdd, nowayout);
+ watchdog_stop_on_reboot(wdd);
+ watchdog_stop_on_unregister(wdd);
+ watchdog_set_drvdata(wdd, tco);
+
+ ret = sp5100_tco_setupdevice(dev, wdd);
+ if (ret)
+ return ret;
+
+ ret = devm_watchdog_register_device(dev, wdd);
+ if (ret) {
+ dev_err(dev, "cannot register watchdog device (err=%d)\n", ret);
+ return ret;
}
- clear_bit(0, &timer_alive);
-
/* Show module parameters */
- pr_info("initialized (0x%p). heartbeat=%d sec (nowayout=%d)\n",
- tcobase, heartbeat, nowayout);
-
- return 0;
-
-exit:
- iounmap(tcobase);
- release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
- release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
- return ret;
-}
-
-static void sp5100_tco_cleanup(void)
-{
- /* Stop the timer before we leave */
- if (!nowayout)
- tco_timer_stop();
-
- /* Deregister */
- misc_deregister(&sp5100_tco_miscdev);
- iounmap(tcobase);
- release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
- release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
-}
+ dev_info(dev, "initialized. heartbeat=%d sec (nowayout=%d)\n",
+ wdd->timeout, nowayout);
-static int sp5100_tco_remove(struct platform_device *dev)
-{
- if (tcobase)
- sp5100_tco_cleanup();
return 0;
}
-static void sp5100_tco_shutdown(struct platform_device *dev)
-{
- tco_timer_stop();
-}
-
static struct platform_driver sp5100_tco_driver = {
- .probe = sp5100_tco_init,
- .remove = sp5100_tco_remove,
- .shutdown = sp5100_tco_shutdown,
+ .probe = sp5100_tco_probe,
.driver = {
- .name = TCO_MODULE_NAME,
+ .name = TCO_DRIVER_NAME,
},
};
-static int __init sp5100_tco_init_module(void)
+/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE. We do not actually
+ * register a pci_driver, because someone else might
+ * want to register another driver on the same PCI id.
+ */
+static const struct pci_device_id sp5100_tco_pci_tbl[] = {
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, PCI_ANY_ID,
+ PCI_ANY_ID, },
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, PCI_ANY_ID,
+ PCI_ANY_ID, },
+ { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, PCI_ANY_ID,
+ PCI_ANY_ID, },
+ { 0, }, /* End of list */
+};
+MODULE_DEVICE_TABLE(pci, sp5100_tco_pci_tbl);
+
+static int __init sp5100_tco_init(void)
{
+ struct pci_dev *dev = NULL;
int err;
- pr_info("SP5100/SB800 TCO WatchDog Timer Driver v%s\n", TCO_VERSION);
+ /* Match the PCI device */
+ for_each_pci_dev(dev) {
+ if (pci_match_id(sp5100_tco_pci_tbl, dev) != NULL) {
+ sp5100_tco_pci = dev;
+ break;
+ }
+ }
+
+ if (!sp5100_tco_pci)
+ return -ENODEV;
+
+ pr_info("SP5100/SB800 TCO WatchDog Timer Driver\n");
err = platform_driver_register(&sp5100_tco_driver);
if (err)
return err;
- sp5100_tco_platform_device = platform_device_register_simple(
- TCO_MODULE_NAME, -1, NULL, 0);
+ sp5100_tco_platform_device =
+ platform_device_register_simple(TCO_DRIVER_NAME, -1, NULL, 0);
if (IS_ERR(sp5100_tco_platform_device)) {
err = PTR_ERR(sp5100_tco_platform_device);
goto unreg_platform_driver;
@@ -579,15 +482,14 @@ unreg_platform_driver:
return err;
}
-static void __exit sp5100_tco_cleanup_module(void)
+static void __exit sp5100_tco_exit(void)
{
platform_device_unregister(sp5100_tco_platform_device);
platform_driver_unregister(&sp5100_tco_driver);
- pr_info("SP5100/SB800 TCO Watchdog Module Unloaded\n");
}
-module_init(sp5100_tco_init_module);
-module_exit(sp5100_tco_cleanup_module);
+module_init(sp5100_tco_init);
+module_exit(sp5100_tco_exit);
MODULE_AUTHOR("Priyanka Gupta");
MODULE_DESCRIPTION("TCO timer driver for SP5100/SB800 chipset");
diff --git a/drivers/watchdog/sp5100_tco.h b/drivers/watchdog/sp5100_tco.h
index 1af4dee71337..87eaf357ae01 100644
--- a/drivers/watchdog/sp5100_tco.h
+++ b/drivers/watchdog/sp5100_tco.h
@@ -7,6 +7,8 @@
* TCO timer driver for sp5100 chipsets
*/
+#include <linux/bitops.h>
+
/*
* Some address definitions for the Watchdog
*/
@@ -14,8 +16,11 @@
#define SP5100_WDT_CONTROL(base) ((base) + 0x00) /* Watchdog Control */
#define SP5100_WDT_COUNT(base) ((base) + 0x04) /* Watchdog Count */
-#define SP5100_WDT_START_STOP_BIT (1 << 0)
-#define SP5100_WDT_TRIGGER_BIT (1 << 7)
+#define SP5100_WDT_START_STOP_BIT BIT(0)
+#define SP5100_WDT_FIRED BIT(1)
+#define SP5100_WDT_ACTION_RESET BIT(2)
+#define SP5100_WDT_DISABLED BIT(3)
+#define SP5100_WDT_TRIGGER_BIT BIT(7)
#define SP5100_PM_IOPORTS_SIZE 0x02
@@ -24,43 +29,57 @@
* read them from a register.
*/
-/* For SP5100/SB7x0 chipset */
+/* For SP5100/SB7x0/SB8x0 chipset */
#define SP5100_IO_PM_INDEX_REG 0xCD6
#define SP5100_IO_PM_DATA_REG 0xCD7
+/* For SP5100/SB7x0 chipset */
#define SP5100_SB_RESOURCE_MMIO_BASE 0x9C
#define SP5100_PM_WATCHDOG_CONTROL 0x69
#define SP5100_PM_WATCHDOG_BASE 0x6C
-#define SP5100_PM_WATCHDOG_FIRED (1 << 1)
-#define SP5100_PM_WATCHDOG_ACTION_RESET (1 << 2)
-
#define SP5100_PCI_WATCHDOG_MISC_REG 0x41
-#define SP5100_PCI_WATCHDOG_DECODE_EN (1 << 3)
+#define SP5100_PCI_WATCHDOG_DECODE_EN BIT(3)
-#define SP5100_PM_WATCHDOG_DISABLE (1 << 0)
-#define SP5100_PM_WATCHDOG_SECOND_RES (3 << 1)
+#define SP5100_PM_WATCHDOG_DISABLE ((u8)BIT(0))
+#define SP5100_PM_WATCHDOG_SECOND_RES GENMASK(2, 1)
#define SP5100_DEVNAME "SP5100 TCO"
-
/* For SB8x0(or later) chipset */
-#define SB800_IO_PM_INDEX_REG 0xCD6
-#define SB800_IO_PM_DATA_REG 0xCD7
-
#define SB800_PM_ACPI_MMIO_EN 0x24
#define SB800_PM_WATCHDOG_CONTROL 0x48
#define SB800_PM_WATCHDOG_BASE 0x48
#define SB800_PM_WATCHDOG_CONFIG 0x4C
-#define SB800_PCI_WATCHDOG_DECODE_EN (1 << 0)
-#define SB800_PM_WATCHDOG_DISABLE (1 << 2)
-#define SB800_PM_WATCHDOG_SECOND_RES (3 << 0)
-#define SB800_ACPI_MMIO_DECODE_EN (1 << 0)
-#define SB800_ACPI_MMIO_SEL (1 << 1)
-
+#define SB800_PCI_WATCHDOG_DECODE_EN BIT(0)
+#define SB800_PM_WATCHDOG_DISABLE ((u8)BIT(1))
+#define SB800_PM_WATCHDOG_SECOND_RES GENMASK(1, 0)
+#define SB800_ACPI_MMIO_DECODE_EN BIT(0)
+#define SB800_ACPI_MMIO_SEL BIT(1)
#define SB800_PM_WDT_MMIO_OFFSET 0xB00
#define SB800_DEVNAME "SB800 TCO"
+
+/* For recent chips with embedded FCH (rev 40+) */
+
+#define EFCH_PM_DECODEEN 0x00
+
+#define EFCH_PM_DECODEEN_WDT_TMREN BIT(7)
+
+
+#define EFCH_PM_DECODEEN3 0x00
+#define EFCH_PM_DECODEEN_SECOND_RES GENMASK(1, 0)
+#define EFCH_PM_WATCHDOG_DISABLE ((u8)GENMASK(3, 2))
+
+/* WDT MMIO if enabled with PM00_DECODEEN_WDT_TMREN */
+#define EFCH_PM_WDT_ADDR 0xfeb00000
+
+#define EFCH_PM_ISACONTROL 0x04
+
+#define EFCH_PM_ISACONTROL_MMIOEN BIT(1)
+
+#define EFCH_PM_ACPI_MMIO_ADDR 0xfed80000
+#define EFCH_PM_ACPI_MMIO_WDT_OFFSET 0x00000b00
diff --git a/drivers/watchdog/sprd_wdt.c b/drivers/watchdog/sprd_wdt.c
new file mode 100644
index 000000000000..a8b280ff33e0
--- /dev/null
+++ b/drivers/watchdog/sprd_wdt.c
@@ -0,0 +1,399 @@
+/*
+ * Spreadtrum watchdog driver
+ * Copyright (C) 2017 Spreadtrum - http://www.spreadtrum.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+
+#define SPRD_WDT_LOAD_LOW 0x0
+#define SPRD_WDT_LOAD_HIGH 0x4
+#define SPRD_WDT_CTRL 0x8
+#define SPRD_WDT_INT_CLR 0xc
+#define SPRD_WDT_INT_RAW 0x10
+#define SPRD_WDT_INT_MSK 0x14
+#define SPRD_WDT_CNT_LOW 0x18
+#define SPRD_WDT_CNT_HIGH 0x1c
+#define SPRD_WDT_LOCK 0x20
+#define SPRD_WDT_IRQ_LOAD_LOW 0x2c
+#define SPRD_WDT_IRQ_LOAD_HIGH 0x30
+
+/* WDT_CTRL */
+#define SPRD_WDT_INT_EN_BIT BIT(0)
+#define SPRD_WDT_CNT_EN_BIT BIT(1)
+#define SPRD_WDT_NEW_VER_EN BIT(2)
+#define SPRD_WDT_RST_EN_BIT BIT(3)
+
+/* WDT_INT_CLR */
+#define SPRD_WDT_INT_CLEAR_BIT BIT(0)
+#define SPRD_WDT_RST_CLEAR_BIT BIT(3)
+
+/* WDT_INT_RAW */
+#define SPRD_WDT_INT_RAW_BIT BIT(0)
+#define SPRD_WDT_RST_RAW_BIT BIT(3)
+#define SPRD_WDT_LD_BUSY_BIT BIT(4)
+
+/* 1s equal to 32768 counter steps */
+#define SPRD_WDT_CNT_STEP 32768
+
+#define SPRD_WDT_UNLOCK_KEY 0xe551
+#define SPRD_WDT_MIN_TIMEOUT 3
+#define SPRD_WDT_MAX_TIMEOUT 60
+
+#define SPRD_WDT_CNT_HIGH_SHIFT 16
+#define SPRD_WDT_LOW_VALUE_MASK GENMASK(15, 0)
+#define SPRD_WDT_LOAD_TIMEOUT 1000
+
+struct sprd_wdt {
+ void __iomem *base;
+ struct watchdog_device wdd;
+ struct clk *enable;
+ struct clk *rtc_enable;
+ int irq;
+};
+
+static inline struct sprd_wdt *to_sprd_wdt(struct watchdog_device *wdd)
+{
+ return container_of(wdd, struct sprd_wdt, wdd);
+}
+
+static inline void sprd_wdt_lock(void __iomem *addr)
+{
+ writel_relaxed(0x0, addr + SPRD_WDT_LOCK);
+}
+
+static inline void sprd_wdt_unlock(void __iomem *addr)
+{
+ writel_relaxed(SPRD_WDT_UNLOCK_KEY, addr + SPRD_WDT_LOCK);
+}
+
+static irqreturn_t sprd_wdt_isr(int irq, void *dev_id)
+{
+ struct sprd_wdt *wdt = (struct sprd_wdt *)dev_id;
+
+ sprd_wdt_unlock(wdt->base);
+ writel_relaxed(SPRD_WDT_INT_CLEAR_BIT, wdt->base + SPRD_WDT_INT_CLR);
+ sprd_wdt_lock(wdt->base);
+ watchdog_notify_pretimeout(&wdt->wdd);
+ return IRQ_HANDLED;
+}
+
+static u32 sprd_wdt_get_cnt_value(struct sprd_wdt *wdt)
+{
+ u32 val;
+
+ val = readl_relaxed(wdt->base + SPRD_WDT_CNT_HIGH) <<
+ SPRD_WDT_CNT_HIGH_SHIFT;
+ val |= readl_relaxed(wdt->base + SPRD_WDT_CNT_LOW) &
+ SPRD_WDT_LOW_VALUE_MASK;
+
+ return val;
+}
+
+static int sprd_wdt_load_value(struct sprd_wdt *wdt, u32 timeout,
+ u32 pretimeout)
+{
+ u32 val, delay_cnt = 0;
+ u32 tmr_step = timeout * SPRD_WDT_CNT_STEP;
+ u32 prtmr_step = pretimeout * SPRD_WDT_CNT_STEP;
+
+ sprd_wdt_unlock(wdt->base);
+ writel_relaxed((tmr_step >> SPRD_WDT_CNT_HIGH_SHIFT) &
+ SPRD_WDT_LOW_VALUE_MASK, wdt->base + SPRD_WDT_LOAD_HIGH);
+ writel_relaxed((tmr_step & SPRD_WDT_LOW_VALUE_MASK),
+ wdt->base + SPRD_WDT_LOAD_LOW);
+ writel_relaxed((prtmr_step >> SPRD_WDT_CNT_HIGH_SHIFT) &
+ SPRD_WDT_LOW_VALUE_MASK,
+ wdt->base + SPRD_WDT_IRQ_LOAD_HIGH);
+ writel_relaxed(prtmr_step & SPRD_WDT_LOW_VALUE_MASK,
+ wdt->base + SPRD_WDT_IRQ_LOAD_LOW);
+ sprd_wdt_lock(wdt->base);
+
+ /*
+ * Waiting the load value operation done,
+ * it needs two or three RTC clock cycles.
+ */
+ do {
+ val = readl_relaxed(wdt->base + SPRD_WDT_INT_RAW);
+ if (!(val & SPRD_WDT_LD_BUSY_BIT))
+ break;
+
+ cpu_relax();
+ } while (delay_cnt++ < SPRD_WDT_LOAD_TIMEOUT);
+
+ if (delay_cnt >= SPRD_WDT_LOAD_TIMEOUT)
+ return -EBUSY;
+ return 0;
+}
+
+static int sprd_wdt_enable(struct sprd_wdt *wdt)
+{
+ u32 val;
+ int ret;
+
+ ret = clk_prepare_enable(wdt->enable);
+ if (ret)
+ return ret;
+ ret = clk_prepare_enable(wdt->rtc_enable);
+ if (ret)
+ return ret;
+
+ sprd_wdt_unlock(wdt->base);
+ val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
+ val |= SPRD_WDT_NEW_VER_EN;
+ writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
+ sprd_wdt_lock(wdt->base);
+ return 0;
+}
+
+static void sprd_wdt_disable(void *_data)
+{
+ struct sprd_wdt *wdt = _data;
+
+ sprd_wdt_unlock(wdt->base);
+ writel_relaxed(0x0, wdt->base + SPRD_WDT_CTRL);
+ sprd_wdt_lock(wdt->base);
+
+ clk_disable_unprepare(wdt->rtc_enable);
+ clk_disable_unprepare(wdt->enable);
+}
+
+static int sprd_wdt_start(struct watchdog_device *wdd)
+{
+ struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+ u32 val;
+ int ret;
+
+ ret = sprd_wdt_load_value(wdt, wdd->timeout, wdd->pretimeout);
+ if (ret)
+ return ret;
+
+ sprd_wdt_unlock(wdt->base);
+ val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
+ val |= SPRD_WDT_CNT_EN_BIT | SPRD_WDT_INT_EN_BIT | SPRD_WDT_RST_EN_BIT;
+ writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
+ sprd_wdt_lock(wdt->base);
+ set_bit(WDOG_HW_RUNNING, &wdd->status);
+
+ return 0;
+}
+
+static int sprd_wdt_stop(struct watchdog_device *wdd)
+{
+ struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+ u32 val;
+
+ sprd_wdt_unlock(wdt->base);
+ val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
+ val &= ~(SPRD_WDT_CNT_EN_BIT | SPRD_WDT_RST_EN_BIT |
+ SPRD_WDT_INT_EN_BIT);
+ writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
+ sprd_wdt_lock(wdt->base);
+ return 0;
+}
+
+static int sprd_wdt_set_timeout(struct watchdog_device *wdd,
+ u32 timeout)
+{
+ struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+
+ if (timeout == wdd->timeout)
+ return 0;
+
+ wdd->timeout = timeout;
+
+ return sprd_wdt_load_value(wdt, timeout, wdd->pretimeout);
+}
+
+static int sprd_wdt_set_pretimeout(struct watchdog_device *wdd,
+ u32 new_pretimeout)
+{
+ struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+
+ if (new_pretimeout < wdd->min_timeout)
+ return -EINVAL;
+
+ wdd->pretimeout = new_pretimeout;
+
+ return sprd_wdt_load_value(wdt, wdd->timeout, new_pretimeout);
+}
+
+static u32 sprd_wdt_get_timeleft(struct watchdog_device *wdd)
+{
+ struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+ u32 val;
+
+ val = sprd_wdt_get_cnt_value(wdt);
+ val = val / SPRD_WDT_CNT_STEP;
+
+ return val;
+}
+
+static const struct watchdog_ops sprd_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = sprd_wdt_start,
+ .stop = sprd_wdt_stop,
+ .set_timeout = sprd_wdt_set_timeout,
+ .set_pretimeout = sprd_wdt_set_pretimeout,
+ .get_timeleft = sprd_wdt_get_timeleft,
+};
+
+static const struct watchdog_info sprd_wdt_info = {
+ .options = WDIOF_SETTIMEOUT |
+ WDIOF_PRETIMEOUT |
+ WDIOF_MAGICCLOSE |
+ WDIOF_KEEPALIVEPING,
+ .identity = "Spreadtrum Watchdog Timer",
+};
+
+static int sprd_wdt_probe(struct platform_device *pdev)
+{
+ struct resource *wdt_res;
+ struct sprd_wdt *wdt;
+ int ret;
+
+ wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ if (!wdt)
+ return -ENOMEM;
+
+ wdt_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ wdt->base = devm_ioremap_resource(&pdev->dev, wdt_res);
+ if (IS_ERR(wdt->base)) {
+ dev_err(&pdev->dev, "failed to map memory resource\n");
+ return PTR_ERR(wdt->base);
+ }
+
+ wdt->enable = devm_clk_get(&pdev->dev, "enable");
+ if (IS_ERR(wdt->enable)) {
+ dev_err(&pdev->dev, "can't get the enable clock\n");
+ return PTR_ERR(wdt->enable);
+ }
+
+ wdt->rtc_enable = devm_clk_get(&pdev->dev, "rtc_enable");
+ if (IS_ERR(wdt->rtc_enable)) {
+ dev_err(&pdev->dev, "can't get the rtc enable clock\n");
+ return PTR_ERR(wdt->rtc_enable);
+ }
+
+ wdt->irq = platform_get_irq(pdev, 0);
+ if (wdt->irq < 0) {
+ dev_err(&pdev->dev, "failed to get IRQ resource\n");
+ return wdt->irq;
+ }
+
+ ret = devm_request_irq(&pdev->dev, wdt->irq, sprd_wdt_isr,
+ IRQF_NO_SUSPEND, "sprd-wdt", (void *)wdt);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register irq\n");
+ return ret;
+ }
+
+ wdt->wdd.info = &sprd_wdt_info;
+ wdt->wdd.ops = &sprd_wdt_ops;
+ wdt->wdd.parent = &pdev->dev;
+ wdt->wdd.min_timeout = SPRD_WDT_MIN_TIMEOUT;
+ wdt->wdd.max_timeout = SPRD_WDT_MAX_TIMEOUT;
+ wdt->wdd.timeout = SPRD_WDT_MAX_TIMEOUT;
+
+ ret = sprd_wdt_enable(wdt);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable wdt\n");
+ return ret;
+ }
+ ret = devm_add_action(&pdev->dev, sprd_wdt_disable, wdt);
+ if (ret) {
+ sprd_wdt_disable(wdt);
+ dev_err(&pdev->dev, "Failed to add wdt disable action\n");
+ return ret;
+ }
+
+ watchdog_set_nowayout(&wdt->wdd, WATCHDOG_NOWAYOUT);
+ watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
+
+ ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
+ if (ret) {
+ sprd_wdt_disable(wdt);
+ dev_err(&pdev->dev, "failed to register watchdog\n");
+ return ret;
+ }
+ platform_set_drvdata(pdev, wdt);
+
+ return 0;
+}
+
+static int __maybe_unused sprd_wdt_pm_suspend(struct device *dev)
+{
+ struct watchdog_device *wdd = dev_get_drvdata(dev);
+ struct sprd_wdt *wdt = dev_get_drvdata(dev);
+
+ if (watchdog_active(wdd))
+ sprd_wdt_stop(&wdt->wdd);
+ sprd_wdt_disable(wdt);
+
+ return 0;
+}
+
+static int __maybe_unused sprd_wdt_pm_resume(struct device *dev)
+{
+ struct watchdog_device *wdd = dev_get_drvdata(dev);
+ struct sprd_wdt *wdt = dev_get_drvdata(dev);
+ int ret;
+
+ ret = sprd_wdt_enable(wdt);
+ if (ret)
+ return ret;
+
+ if (watchdog_active(wdd)) {
+ ret = sprd_wdt_start(&wdt->wdd);
+ if (ret) {
+ sprd_wdt_disable(wdt);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops sprd_wdt_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(sprd_wdt_pm_suspend,
+ sprd_wdt_pm_resume)
+};
+
+static const struct of_device_id sprd_wdt_match_table[] = {
+ { .compatible = "sprd,sp9860-wdt", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sprd_wdt_match_table);
+
+static struct platform_driver sprd_watchdog_driver = {
+ .probe = sprd_wdt_probe,
+ .driver = {
+ .name = "sprd-wdt",
+ .of_match_table = sprd_wdt_match_table,
+ .pm = &sprd_wdt_pm_ops,
+ },
+};
+module_platform_driver(sprd_watchdog_driver);
+
+MODULE_AUTHOR("Eric Long <eric.long@spreadtrum.com>");
+MODULE_DESCRIPTION("Spreadtrum Watchdog Timer Controller Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c
index be64a8699de3..c97ad5619cb0 100644
--- a/drivers/watchdog/stm32_iwdg.c
+++ b/drivers/watchdog/stm32_iwdg.c
@@ -1,12 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Driver for STM32 Independent Watchdog
*
- * Copyright (C) Yannick Fertre 2017
- * Author: Yannick Fertre <yannick.fertre@st.com>
+ * Copyright (C) STMicroelectronics 2017
+ * Author: Yannick Fertre <yannick.fertre@st.com> for STMicroelectronics.
*
* This driver is based on tegra_wdt.c
*
- * License terms: GNU General Public License (GPL), version 2
*/
#include <linux/clk.h>
diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c
index 9728fa32c357..802e31b1416d 100644
--- a/drivers/watchdog/sunxi_wdt.c
+++ b/drivers/watchdog/sunxi_wdt.c
@@ -234,7 +234,6 @@ MODULE_DEVICE_TABLE(of, sunxi_wdt_dt_ids);
static int sunxi_wdt_probe(struct platform_device *pdev)
{
struct sunxi_wdt_dev *sunxi_wdt;
- const struct of_device_id *device;
struct resource *res;
int err;
@@ -242,12 +241,10 @@ static int sunxi_wdt_probe(struct platform_device *pdev)
if (!sunxi_wdt)
return -EINVAL;
- device = of_match_device(sunxi_wdt_dt_ids, &pdev->dev);
- if (!device)
+ sunxi_wdt->wdt_regs = of_device_get_match_data(&pdev->dev);
+ if (!sunxi_wdt->wdt_regs)
return -ENODEV;
- sunxi_wdt->wdt_regs = device->data;
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
sunxi_wdt->wdt_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(sunxi_wdt->wdt_base))
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
index 8a8d952f8df9..eb8fa25f8eb2 100644
--- a/drivers/watchdog/watchdog_core.c
+++ b/drivers/watchdog/watchdog_core.c
@@ -97,6 +97,7 @@ static void watchdog_check_min_max_timeout(struct watchdog_device *wdd)
/**
* watchdog_init_timeout() - initialize the timeout field
+ * @wdd: watchdog device
* @timeout_parm: timeout module parameter
* @dev: Device that stores the timeout-sec property
*
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
index 1e971a50d7fb..ffbdc4642ea5 100644
--- a/drivers/watchdog/watchdog_dev.c
+++ b/drivers/watchdog/watchdog_dev.c
@@ -36,9 +36,10 @@
#include <linux/errno.h> /* For the -ENODEV/... values */
#include <linux/fs.h> /* For file operations */
#include <linux/init.h> /* For __init/__exit/... */
-#include <linux/jiffies.h> /* For timeout functions */
+#include <linux/hrtimer.h> /* For hrtimers */
#include <linux/kernel.h> /* For printk/panic/... */
#include <linux/kref.h> /* For data references */
+#include <linux/kthread.h> /* For kthread_work */
#include <linux/miscdevice.h> /* For handling misc devices */
#include <linux/module.h> /* For module stuff/... */
#include <linux/mutex.h> /* For mutexes */
@@ -46,9 +47,10 @@
#include <linux/slab.h> /* For memory functions */
#include <linux/types.h> /* For standard types (like size_t) */
#include <linux/watchdog.h> /* For watchdog specific items */
-#include <linux/workqueue.h> /* For workqueue */
#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
+#include <uapi/linux/sched/types.h> /* For struct sched_param */
+
#include "watchdog_core.h"
#include "watchdog_pretimeout.h"
@@ -65,9 +67,10 @@ struct watchdog_core_data {
struct cdev cdev;
struct watchdog_device *wdd;
struct mutex lock;
- unsigned long last_keepalive;
- unsigned long last_hw_keepalive;
- struct delayed_work work;
+ ktime_t last_keepalive;
+ ktime_t last_hw_keepalive;
+ struct hrtimer timer;
+ struct kthread_work work;
unsigned long status; /* Internal status bits */
#define _WDOG_DEV_OPEN 0 /* Opened ? */
#define _WDOG_ALLOW_RELEASE 1 /* Did we receive the magic char ? */
@@ -79,7 +82,7 @@ static dev_t watchdog_devt;
/* Reference to watchdog device behind /dev/watchdog */
static struct watchdog_core_data *old_wd_data;
-static struct workqueue_struct *watchdog_wq;
+static struct kthread_worker *watchdog_kworker;
static bool handle_boot_enabled =
IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED);
@@ -107,18 +110,19 @@ static inline bool watchdog_need_worker(struct watchdog_device *wdd)
(t && !watchdog_active(wdd) && watchdog_hw_running(wdd));
}
-static long watchdog_next_keepalive(struct watchdog_device *wdd)
+static ktime_t watchdog_next_keepalive(struct watchdog_device *wdd)
{
struct watchdog_core_data *wd_data = wdd->wd_data;
unsigned int timeout_ms = wdd->timeout * 1000;
- unsigned long keepalive_interval;
- unsigned long last_heartbeat;
- unsigned long virt_timeout;
+ ktime_t keepalive_interval;
+ ktime_t last_heartbeat, latest_heartbeat;
+ ktime_t virt_timeout;
unsigned int hw_heartbeat_ms;
- virt_timeout = wd_data->last_keepalive + msecs_to_jiffies(timeout_ms);
+ virt_timeout = ktime_add(wd_data->last_keepalive,
+ ms_to_ktime(timeout_ms));
hw_heartbeat_ms = min_not_zero(timeout_ms, wdd->max_hw_heartbeat_ms);
- keepalive_interval = msecs_to_jiffies(hw_heartbeat_ms / 2);
+ keepalive_interval = ms_to_ktime(hw_heartbeat_ms / 2);
if (!watchdog_active(wdd))
return keepalive_interval;
@@ -128,8 +132,11 @@ static long watchdog_next_keepalive(struct watchdog_device *wdd)
* after the most recent ping from userspace, the last
* worker ping has to come in hw_heartbeat_ms before this timeout.
*/
- last_heartbeat = virt_timeout - msecs_to_jiffies(hw_heartbeat_ms);
- return min_t(long, last_heartbeat - jiffies, keepalive_interval);
+ last_heartbeat = ktime_sub(virt_timeout, ms_to_ktime(hw_heartbeat_ms));
+ latest_heartbeat = ktime_sub(last_heartbeat, ktime_get());
+ if (ktime_before(latest_heartbeat, keepalive_interval))
+ return latest_heartbeat;
+ return keepalive_interval;
}
static inline void watchdog_update_worker(struct watchdog_device *wdd)
@@ -137,29 +144,33 @@ static inline void watchdog_update_worker(struct watchdog_device *wdd)
struct watchdog_core_data *wd_data = wdd->wd_data;
if (watchdog_need_worker(wdd)) {
- long t = watchdog_next_keepalive(wdd);
+ ktime_t t = watchdog_next_keepalive(wdd);
if (t > 0)
- mod_delayed_work(watchdog_wq, &wd_data->work, t);
+ hrtimer_start(&wd_data->timer, t, HRTIMER_MODE_REL);
} else {
- cancel_delayed_work(&wd_data->work);
+ hrtimer_cancel(&wd_data->timer);
}
}
static int __watchdog_ping(struct watchdog_device *wdd)
{
struct watchdog_core_data *wd_data = wdd->wd_data;
- unsigned long earliest_keepalive = wd_data->last_hw_keepalive +
- msecs_to_jiffies(wdd->min_hw_heartbeat_ms);
+ ktime_t earliest_keepalive, now;
int err;
- if (time_is_after_jiffies(earliest_keepalive)) {
- mod_delayed_work(watchdog_wq, &wd_data->work,
- earliest_keepalive - jiffies);
+ earliest_keepalive = ktime_add(wd_data->last_hw_keepalive,
+ ms_to_ktime(wdd->min_hw_heartbeat_ms));
+ now = ktime_get();
+
+ if (ktime_after(earliest_keepalive, now)) {
+ hrtimer_start(&wd_data->timer,
+ ktime_sub(earliest_keepalive, now),
+ HRTIMER_MODE_REL);
return 0;
}
- wd_data->last_hw_keepalive = jiffies;
+ wd_data->last_hw_keepalive = now;
if (wdd->ops->ping)
err = wdd->ops->ping(wdd); /* ping the watchdog */
@@ -192,7 +203,7 @@ static int watchdog_ping(struct watchdog_device *wdd)
set_bit(_WDOG_KEEPALIVE, &wd_data->status);
- wd_data->last_keepalive = jiffies;
+ wd_data->last_keepalive = ktime_get();
return __watchdog_ping(wdd);
}
@@ -203,12 +214,11 @@ static bool watchdog_worker_should_ping(struct watchdog_core_data *wd_data)
return wdd && (watchdog_active(wdd) || watchdog_hw_running(wdd));
}
-static void watchdog_ping_work(struct work_struct *work)
+static void watchdog_ping_work(struct kthread_work *work)
{
struct watchdog_core_data *wd_data;
- wd_data = container_of(to_delayed_work(work), struct watchdog_core_data,
- work);
+ wd_data = container_of(work, struct watchdog_core_data, work);
mutex_lock(&wd_data->lock);
if (watchdog_worker_should_ping(wd_data))
@@ -216,6 +226,16 @@ static void watchdog_ping_work(struct work_struct *work)
mutex_unlock(&wd_data->lock);
}
+static enum hrtimer_restart watchdog_timer_expired(struct hrtimer *timer)
+{
+ struct watchdog_core_data *wd_data;
+
+ wd_data = container_of(timer, struct watchdog_core_data, timer);
+
+ kthread_queue_work(watchdog_kworker, &wd_data->work);
+ return HRTIMER_NORESTART;
+}
+
/*
* watchdog_start: wrapper to start the watchdog.
* @wdd: the watchdog device to start
@@ -230,7 +250,7 @@ static void watchdog_ping_work(struct work_struct *work)
static int watchdog_start(struct watchdog_device *wdd)
{
struct watchdog_core_data *wd_data = wdd->wd_data;
- unsigned long started_at;
+ ktime_t started_at;
int err;
if (watchdog_active(wdd))
@@ -238,7 +258,7 @@ static int watchdog_start(struct watchdog_device *wdd)
set_bit(_WDOG_KEEPALIVE, &wd_data->status);
- started_at = jiffies;
+ started_at = ktime_get();
if (watchdog_hw_running(wdd) && wdd->ops->ping)
err = wdd->ops->ping(wdd);
else
@@ -720,7 +740,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
err = watchdog_ping(wdd);
if (err < 0)
break;
- /* Fall */
+ /* fall through */
case WDIOC_GETTIMEOUT:
/* timeout == 0 means that we don't know the timeout */
if (wdd->timeout == 0) {
@@ -769,6 +789,7 @@ static int watchdog_open(struct inode *inode, struct file *file)
{
struct watchdog_core_data *wd_data;
struct watchdog_device *wdd;
+ bool hw_running;
int err;
/* Get the corresponding watchdog device */
@@ -788,7 +809,8 @@ static int watchdog_open(struct inode *inode, struct file *file)
* If the /dev/watchdog device is open, we don't want the module
* to be unloaded.
*/
- if (!watchdog_hw_running(wdd) && !try_module_get(wdd->ops->owner)) {
+ hw_running = watchdog_hw_running(wdd);
+ if (!hw_running && !try_module_get(wdd->ops->owner)) {
err = -EBUSY;
goto out_clear;
}
@@ -799,7 +821,7 @@ static int watchdog_open(struct inode *inode, struct file *file)
file->private_data = wd_data;
- if (!watchdog_hw_running(wdd))
+ if (!hw_running)
kref_get(&wd_data->kref);
/* dev/watchdog is a virtual (and thus non-seekable) filesystem */
@@ -919,10 +941,12 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
wd_data->wdd = wdd;
wdd->wd_data = wd_data;
- if (!watchdog_wq)
+ if (IS_ERR_OR_NULL(watchdog_kworker))
return -ENODEV;
- INIT_DELAYED_WORK(&wd_data->work, watchdog_ping_work);
+ kthread_init_work(&wd_data->work, watchdog_ping_work);
+ hrtimer_init(&wd_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ wd_data->timer.function = watchdog_timer_expired;
if (wdd->id == 0) {
old_wd_data = wd_data;
@@ -958,21 +982,20 @@ static int watchdog_cdev_register(struct watchdog_device *wdd, dev_t devno)
}
/* Record time of most recent heartbeat as 'just before now'. */
- wd_data->last_hw_keepalive = jiffies - 1;
+ wd_data->last_hw_keepalive = ktime_sub(ktime_get(), 1);
/*
* If the watchdog is running, prevent its driver from being unloaded,
* and schedule an immediate ping.
*/
if (watchdog_hw_running(wdd)) {
- if (handle_boot_enabled) {
- __module_get(wdd->ops->owner);
- kref_get(&wd_data->kref);
- queue_delayed_work(watchdog_wq, &wd_data->work, 0);
- } else {
+ __module_get(wdd->ops->owner);
+ kref_get(&wd_data->kref);
+ if (handle_boot_enabled)
+ hrtimer_start(&wd_data->timer, 0, HRTIMER_MODE_REL);
+ else
pr_info("watchdog%d running and kernel based pre-userspace handler disabled\n",
- wdd->id);
- }
+ wdd->id);
}
return 0;
@@ -1006,7 +1029,8 @@ static void watchdog_cdev_unregister(struct watchdog_device *wdd)
watchdog_stop(wdd);
}
- cancel_delayed_work_sync(&wd_data->work);
+ hrtimer_cancel(&wd_data->timer);
+ kthread_cancel_work_sync(&wd_data->work);
kref_put(&wd_data->kref, watchdog_core_data_release);
}
@@ -1110,13 +1134,14 @@ void watchdog_dev_unregister(struct watchdog_device *wdd)
int __init watchdog_dev_init(void)
{
int err;
+ struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1,};
- watchdog_wq = alloc_workqueue("watchdogd",
- WQ_HIGHPRI | WQ_MEM_RECLAIM, 0);
- if (!watchdog_wq) {
- pr_err("Failed to create watchdog workqueue\n");
- return -ENOMEM;
+ watchdog_kworker = kthread_create_worker(0, "watchdogd");
+ if (IS_ERR(watchdog_kworker)) {
+ pr_err("Failed to create watchdog kworker\n");
+ return PTR_ERR(watchdog_kworker);
}
+ sched_setscheduler(watchdog_kworker->task, SCHED_FIFO, &param);
err = class_register(&watchdog_class);
if (err < 0) {
@@ -1135,7 +1160,7 @@ int __init watchdog_dev_init(void)
err_alloc:
class_unregister(&watchdog_class);
err_register:
- destroy_workqueue(watchdog_wq);
+ kthread_destroy_worker(watchdog_kworker);
return err;
}
@@ -1149,7 +1174,7 @@ void __exit watchdog_dev_exit(void)
{
unregister_chrdev_region(watchdog_devt, MAX_DOGS);
class_unregister(&watchdog_class);
- destroy_workqueue(watchdog_wq);
+ kthread_destroy_worker(watchdog_kworker);
}
module_param(handle_boot_enabled, bool, 0444);
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c
index bc7addc2dc06..10e2cda0ee5a 100644
--- a/drivers/watchdog/wdt_pci.c
+++ b/drivers/watchdog/wdt_pci.c
@@ -430,7 +430,7 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd,
if (wdtpci_set_heartbeat(new_heartbeat))
return -EINVAL;
wdtpci_ping();
- /* Fall */
+ /* fall through */
case WDIOC_GETTIMEOUT:
return put_user(heartbeat, p);
default:
diff --git a/drivers/watchdog/xen_wdt.c b/drivers/watchdog/xen_wdt.c
index cf0e650c2015..f1c016d015b3 100644
--- a/drivers/watchdog/xen_wdt.c
+++ b/drivers/watchdog/xen_wdt.c
@@ -9,10 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define DRV_NAME "wdt"
-#define DRV_VERSION "0.01"
+#define DRV_NAME "xen_wdt"
#include <linux/bug.h>
#include <linux/errno.h>
@@ -21,25 +18,20 @@
#include <linux/kernel.h>
#include <linux/ktime.h>
#include <linux/init.h>
-#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/platform_device.h>
-#include <linux/spinlock.h>
-#include <linux/uaccess.h>
#include <linux/watchdog.h>
#include <xen/xen.h>
#include <asm/xen/hypercall.h>
#include <xen/interface/sched.h>
static struct platform_device *platform_device;
-static DEFINE_SPINLOCK(wdt_lock);
static struct sched_watchdog wdt;
-static __kernel_time_t wdt_expires;
-static bool is_active, expect_release;
+static time64_t wdt_expires;
#define WATCHDOG_TIMEOUT 60 /* in seconds */
-static unsigned int timeout = WATCHDOG_TIMEOUT;
+static unsigned int timeout;
module_param(timeout, uint, S_IRUGO);
MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds "
"(default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
@@ -49,20 +41,18 @@ module_param(nowayout, bool, S_IRUGO);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-static inline __kernel_time_t set_timeout(void)
+static inline time64_t set_timeout(struct watchdog_device *wdd)
{
- wdt.timeout = timeout;
- return ktime_to_timespec(ktime_get()).tv_sec + timeout;
+ wdt.timeout = wdd->timeout;
+ return ktime_get_seconds() + wdd->timeout;
}
-static int xen_wdt_start(void)
+static int xen_wdt_start(struct watchdog_device *wdd)
{
- __kernel_time_t expires;
+ time64_t expires;
int err;
- spin_lock(&wdt_lock);
-
- expires = set_timeout();
+ expires = set_timeout(wdd);
if (!wdt.id)
err = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wdt);
else
@@ -74,36 +64,28 @@ static int xen_wdt_start(void)
} else
BUG_ON(!err);
- spin_unlock(&wdt_lock);
-
return err;
}
-static int xen_wdt_stop(void)
+static int xen_wdt_stop(struct watchdog_device *wdd)
{
int err = 0;
- spin_lock(&wdt_lock);
-
wdt.timeout = 0;
if (wdt.id)
err = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wdt);
if (!err)
wdt.id = 0;
- spin_unlock(&wdt_lock);
-
return err;
}
-static int xen_wdt_kick(void)
+static int xen_wdt_kick(struct watchdog_device *wdd)
{
- __kernel_time_t expires;
+ time64_t expires;
int err;
- spin_lock(&wdt_lock);
-
- expires = set_timeout();
+ expires = set_timeout(wdd);
if (wdt.id)
err = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wdt);
else
@@ -111,195 +93,72 @@ static int xen_wdt_kick(void)
if (!err)
wdt_expires = expires;
- spin_unlock(&wdt_lock);
-
- return err;
-}
-
-static int xen_wdt_open(struct inode *inode, struct file *file)
-{
- int err;
-
- /* /dev/watchdog can only be opened once */
- if (xchg(&is_active, true))
- return -EBUSY;
-
- err = xen_wdt_start();
- if (err == -EBUSY)
- err = xen_wdt_kick();
- return err ?: nonseekable_open(inode, file);
-}
-
-static int xen_wdt_release(struct inode *inode, struct file *file)
-{
- int err = 0;
-
- if (expect_release)
- err = xen_wdt_stop();
- else {
- pr_crit("unexpected close, not stopping watchdog!\n");
- xen_wdt_kick();
- }
- is_active = err;
- expect_release = false;
return err;
}
-static ssize_t xen_wdt_write(struct file *file, const char __user *data,
- size_t len, loff_t *ppos)
+static unsigned int xen_wdt_get_timeleft(struct watchdog_device *wdd)
{
- /* See if we got the magic character 'V' and reload the timer */
- if (len) {
- if (!nowayout) {
- size_t i;
-
- /* in case it was set long ago */
- expect_release = false;
-
- /* scan to see whether or not we got the magic
- character */
- for (i = 0; i != len; i++) {
- char c;
- if (get_user(c, data + i))
- return -EFAULT;
- if (c == 'V')
- expect_release = true;
- }
- }
-
- /* someone wrote to us, we should reload the timer */
- xen_wdt_kick();
- }
- return len;
+ return wdt_expires - ktime_get_seconds();
}
-static long xen_wdt_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- int new_options, retval = -EINVAL;
- int new_timeout;
- int __user *argp = (void __user *)arg;
- static const struct watchdog_info ident = {
- .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
- .firmware_version = 0,
- .identity = DRV_NAME,
- };
-
- switch (cmd) {
- case WDIOC_GETSUPPORT:
- return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
-
- case WDIOC_GETSTATUS:
- case WDIOC_GETBOOTSTATUS:
- return put_user(0, argp);
-
- case WDIOC_SETOPTIONS:
- if (get_user(new_options, argp))
- return -EFAULT;
-
- if (new_options & WDIOS_DISABLECARD)
- retval = xen_wdt_stop();
- if (new_options & WDIOS_ENABLECARD) {
- retval = xen_wdt_start();
- if (retval == -EBUSY)
- retval = xen_wdt_kick();
- }
- return retval;
-
- case WDIOC_KEEPALIVE:
- xen_wdt_kick();
- return 0;
-
- case WDIOC_SETTIMEOUT:
- if (get_user(new_timeout, argp))
- return -EFAULT;
- if (!new_timeout)
- return -EINVAL;
- timeout = new_timeout;
- xen_wdt_kick();
- /* fall through */
- case WDIOC_GETTIMEOUT:
- return put_user(timeout, argp);
-
- case WDIOC_GETTIMELEFT:
- retval = wdt_expires - ktime_to_timespec(ktime_get()).tv_sec;
- return put_user(retval, argp);
- }
-
- return -ENOTTY;
-}
+static struct watchdog_info xen_wdt_info = {
+ .identity = DRV_NAME,
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
+};
-static const struct file_operations xen_wdt_fops = {
- .owner = THIS_MODULE,
- .llseek = no_llseek,
- .write = xen_wdt_write,
- .unlocked_ioctl = xen_wdt_ioctl,
- .open = xen_wdt_open,
- .release = xen_wdt_release,
+static const struct watchdog_ops xen_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = xen_wdt_start,
+ .stop = xen_wdt_stop,
+ .ping = xen_wdt_kick,
+ .get_timeleft = xen_wdt_get_timeleft,
};
-static struct miscdevice xen_wdt_miscdev = {
- .minor = WATCHDOG_MINOR,
- .name = "watchdog",
- .fops = &xen_wdt_fops,
+static struct watchdog_device xen_wdt_dev = {
+ .info = &xen_wdt_info,
+ .ops = &xen_wdt_ops,
+ .timeout = WATCHDOG_TIMEOUT,
};
-static int xen_wdt_probe(struct platform_device *dev)
+static int xen_wdt_probe(struct platform_device *pdev)
{
struct sched_watchdog wd = { .id = ~0 };
int ret = HYPERVISOR_sched_op(SCHEDOP_watchdog, &wd);
- switch (ret) {
- case -EINVAL:
- if (!timeout) {
- timeout = WATCHDOG_TIMEOUT;
- pr_info("timeout value invalid, using %d\n", timeout);
- }
-
- ret = misc_register(&xen_wdt_miscdev);
- if (ret) {
- pr_err("cannot register miscdev on minor=%d (%d)\n",
- WATCHDOG_MINOR, ret);
- break;
- }
-
- pr_info("initialized (timeout=%ds, nowayout=%d)\n",
- timeout, nowayout);
- break;
-
- case -ENOSYS:
- pr_info("not supported\n");
- ret = -ENODEV;
- break;
-
- default:
- pr_info("bogus return value %d\n", ret);
- break;
+ if (ret == -ENOSYS) {
+ dev_err(&pdev->dev, "watchdog not supported by hypervisor\n");
+ return -ENODEV;
}
- return ret;
-}
+ if (ret != -EINVAL) {
+ dev_err(&pdev->dev, "unexpected hypervisor error (%d)\n", ret);
+ return -ENODEV;
+ }
-static int xen_wdt_remove(struct platform_device *dev)
-{
- /* Stop the timer before we leave */
- if (!nowayout)
- xen_wdt_stop();
+ if (watchdog_init_timeout(&xen_wdt_dev, timeout, NULL))
+ dev_info(&pdev->dev, "timeout value invalid, using %d\n",
+ xen_wdt_dev.timeout);
+ watchdog_set_nowayout(&xen_wdt_dev, nowayout);
+ watchdog_stop_on_reboot(&xen_wdt_dev);
+ watchdog_stop_on_unregister(&xen_wdt_dev);
+
+ ret = devm_watchdog_register_device(&pdev->dev, &xen_wdt_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "cannot register watchdog device (%d)\n",
+ ret);
+ return ret;
+ }
- misc_deregister(&xen_wdt_miscdev);
+ dev_info(&pdev->dev, "initialized (timeout=%ds, nowayout=%d)\n",
+ xen_wdt_dev.timeout, nowayout);
return 0;
}
-static void xen_wdt_shutdown(struct platform_device *dev)
-{
- xen_wdt_stop();
-}
-
static int xen_wdt_suspend(struct platform_device *dev, pm_message_t state)
{
typeof(wdt.id) id = wdt.id;
- int rc = xen_wdt_stop();
+ int rc = xen_wdt_stop(&xen_wdt_dev);
wdt.id = id;
return rc;
@@ -310,13 +169,11 @@ static int xen_wdt_resume(struct platform_device *dev)
if (!wdt.id)
return 0;
wdt.id = 0;
- return xen_wdt_start();
+ return xen_wdt_start(&xen_wdt_dev);
}
static struct platform_driver xen_wdt_driver = {
.probe = xen_wdt_probe,
- .remove = xen_wdt_remove,
- .shutdown = xen_wdt_shutdown,
.suspend = xen_wdt_suspend,
.resume = xen_wdt_resume,
.driver = {
@@ -331,8 +188,6 @@ static int __init xen_wdt_init_module(void)
if (!xen_domain())
return -ENODEV;
- pr_info("Xen WatchDog Timer Driver v%s\n", DRV_VERSION);
-
err = platform_driver_register(&xen_wdt_driver);
if (err)
return err;
@@ -351,7 +206,6 @@ static void __exit xen_wdt_cleanup_module(void)
{
platform_device_unregister(platform_device);
platform_driver_unregister(&xen_wdt_driver);
- pr_info("module unloaded\n");
}
module_init(xen_wdt_init_module);
@@ -359,5 +213,4 @@ module_exit(xen_wdt_cleanup_module);
MODULE_AUTHOR("Jan Beulich <jbeulich@novell.com>");
MODULE_DESCRIPTION("Xen WatchDog Timer Driver");
-MODULE_VERSION(DRV_VERSION);
MODULE_LICENSE("GPL");
diff --git a/fs/Kconfig b/fs/Kconfig
index 9774588da60e..bc821a86d965 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -58,6 +58,13 @@ config FS_DAX_PMD
depends on ZONE_DEVICE
depends on TRANSPARENT_HUGEPAGE
+# Selected by DAX drivers that do not expect filesystem DAX to support
+# get_user_pages() of DAX mappings. I.e. "limited" indicates no support
+# for fork() of processes with MAP_SHARED mappings or support for
+# direct-I/O to a DAX mapping.
+config FS_DAX_LIMITED
+ bool
+
endif # BLOCK
# Posix ACL utility routines
diff --git a/fs/affs/dir.c b/fs/affs/dir.c
index d180b46453cf..b2bf7016e1b3 100644
--- a/fs/affs/dir.c
+++ b/fs/affs/dir.c
@@ -81,7 +81,7 @@ affs_readdir(struct file *file, struct dir_context *ctx)
* we can jump directly to where we left off.
*/
ino = (u32)(long)file->private_data;
- if (ino && inode_cmp_iversion(inode, file->f_version) == 0) {
+ if (ino && inode_eq_iversion(inode, file->f_version)) {
pr_debug("readdir() left off=%d\n", ino);
goto inside;
}
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 83732fef510d..bdb201230bae 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1599,6 +1599,8 @@ static int fill_files_note(struct memelfnote *note)
/* *Estimated* file count and total data size needed */
count = current->mm->map_count;
+ if (count > UINT_MAX / 64)
+ return -EINVAL;
size = count * 64;
names_ofs = (2 + 3 * count) * sizeof(data[0]);
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 5fc5dc660600..ef80085ed564 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -1218,23 +1218,11 @@ COMPATIBLE_IOCTL(DMX_SET_PES_FILTER)
COMPATIBLE_IOCTL(DMX_SET_BUFFER_SIZE)
COMPATIBLE_IOCTL(DMX_GET_PES_PIDS)
COMPATIBLE_IOCTL(DMX_GET_STC)
-COMPATIBLE_IOCTL(FE_GET_INFO)
-COMPATIBLE_IOCTL(FE_DISEQC_RESET_OVERLOAD)
-COMPATIBLE_IOCTL(FE_DISEQC_SEND_MASTER_CMD)
-COMPATIBLE_IOCTL(FE_DISEQC_RECV_SLAVE_REPLY)
-COMPATIBLE_IOCTL(FE_DISEQC_SEND_BURST)
-COMPATIBLE_IOCTL(FE_SET_TONE)
-COMPATIBLE_IOCTL(FE_SET_VOLTAGE)
-COMPATIBLE_IOCTL(FE_ENABLE_HIGH_LNB_VOLTAGE)
-COMPATIBLE_IOCTL(FE_READ_STATUS)
-COMPATIBLE_IOCTL(FE_READ_BER)
-COMPATIBLE_IOCTL(FE_READ_SIGNAL_STRENGTH)
-COMPATIBLE_IOCTL(FE_READ_SNR)
-COMPATIBLE_IOCTL(FE_READ_UNCORRECTED_BLOCKS)
-COMPATIBLE_IOCTL(FE_SET_FRONTEND)
-COMPATIBLE_IOCTL(FE_GET_FRONTEND)
-COMPATIBLE_IOCTL(FE_GET_EVENT)
-COMPATIBLE_IOCTL(FE_DISHNETWORK_SEND_LEGACY_CMD)
+COMPATIBLE_IOCTL(DMX_REQBUFS)
+COMPATIBLE_IOCTL(DMX_QUERYBUF)
+COMPATIBLE_IOCTL(DMX_EXPBUF)
+COMPATIBLE_IOCTL(DMX_QBUF)
+COMPATIBLE_IOCTL(DMX_DQBUF)
COMPATIBLE_IOCTL(VIDEO_STOP)
COMPATIBLE_IOCTL(VIDEO_PLAY)
COMPATIBLE_IOCTL(VIDEO_FREEZE)
diff --git a/fs/dcache.c b/fs/dcache.c
index cca2b377ff0a..7c38f39958bc 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1698,9 +1698,15 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
}
EXPORT_SYMBOL(d_alloc);
+struct dentry *d_alloc_anon(struct super_block *sb)
+{
+ return __d_alloc(sb, NULL);
+}
+EXPORT_SYMBOL(d_alloc_anon);
+
struct dentry *d_alloc_cursor(struct dentry * parent)
{
- struct dentry *dentry = __d_alloc(parent->d_sb, NULL);
+ struct dentry *dentry = d_alloc_anon(parent->d_sb);
if (dentry) {
dentry->d_flags |= DCACHE_RCUACCESS | DCACHE_DENTRY_CURSOR;
dentry->d_parent = dget(parent);
@@ -1886,7 +1892,7 @@ struct dentry *d_make_root(struct inode *root_inode)
struct dentry *res = NULL;
if (root_inode) {
- res = __d_alloc(root_inode->i_sb, NULL);
+ res = d_alloc_anon(root_inode->i_sb);
if (res)
d_instantiate(res, root_inode);
else
@@ -1925,33 +1931,19 @@ struct dentry *d_find_any_alias(struct inode *inode)
}
EXPORT_SYMBOL(d_find_any_alias);
-static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
+static struct dentry *__d_instantiate_anon(struct dentry *dentry,
+ struct inode *inode,
+ bool disconnected)
{
- struct dentry *tmp;
struct dentry *res;
unsigned add_flags;
- if (!inode)
- return ERR_PTR(-ESTALE);
- if (IS_ERR(inode))
- return ERR_CAST(inode);
-
- res = d_find_any_alias(inode);
- if (res)
- goto out_iput;
-
- tmp = __d_alloc(inode->i_sb, NULL);
- if (!tmp) {
- res = ERR_PTR(-ENOMEM);
- goto out_iput;
- }
-
- security_d_instantiate(tmp, inode);
+ security_d_instantiate(dentry, inode);
spin_lock(&inode->i_lock);
res = __d_find_any_alias(inode);
if (res) {
spin_unlock(&inode->i_lock);
- dput(tmp);
+ dput(dentry);
goto out_iput;
}
@@ -1961,24 +1953,57 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
if (disconnected)
add_flags |= DCACHE_DISCONNECTED;
- spin_lock(&tmp->d_lock);
- __d_set_inode_and_type(tmp, inode, add_flags);
- hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry);
+ spin_lock(&dentry->d_lock);
+ __d_set_inode_and_type(dentry, inode, add_flags);
+ hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
if (!disconnected) {
- hlist_bl_lock(&tmp->d_sb->s_roots);
- hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_roots);
- hlist_bl_unlock(&tmp->d_sb->s_roots);
+ hlist_bl_lock(&dentry->d_sb->s_roots);
+ hlist_bl_add_head(&dentry->d_hash, &dentry->d_sb->s_roots);
+ hlist_bl_unlock(&dentry->d_sb->s_roots);
}
- spin_unlock(&tmp->d_lock);
+ spin_unlock(&dentry->d_lock);
spin_unlock(&inode->i_lock);
- return tmp;
+ return dentry;
out_iput:
iput(inode);
return res;
}
+struct dentry *d_instantiate_anon(struct dentry *dentry, struct inode *inode)
+{
+ return __d_instantiate_anon(dentry, inode, true);
+}
+EXPORT_SYMBOL(d_instantiate_anon);
+
+static struct dentry *__d_obtain_alias(struct inode *inode, bool disconnected)
+{
+ struct dentry *tmp;
+ struct dentry *res;
+
+ if (!inode)
+ return ERR_PTR(-ESTALE);
+ if (IS_ERR(inode))
+ return ERR_CAST(inode);
+
+ res = d_find_any_alias(inode);
+ if (res)
+ goto out_iput;
+
+ tmp = d_alloc_anon(inode->i_sb);
+ if (!tmp) {
+ res = ERR_PTR(-ENOMEM);
+ goto out_iput;
+ }
+
+ return __d_instantiate_anon(tmp, inode, disconnected);
+
+out_iput:
+ iput(inode);
+ return res;
+}
+
/**
* d_obtain_alias - find or allocate a DISCONNECTED dentry for a given inode
* @inode: inode to allocate the dentry for
@@ -1999,7 +2024,7 @@ static struct dentry *__d_obtain_alias(struct inode *inode, int disconnected)
*/
struct dentry *d_obtain_alias(struct inode *inode)
{
- return __d_obtain_alias(inode, 1);
+ return __d_obtain_alias(inode, true);
}
EXPORT_SYMBOL(d_obtain_alias);
@@ -2020,7 +2045,7 @@ EXPORT_SYMBOL(d_obtain_alias);
*/
struct dentry *d_obtain_root(struct inode *inode)
{
- return __d_obtain_alias(inode, 0);
+ return __d_obtain_alias(inode, false);
}
EXPORT_SYMBOL(d_obtain_root);
@@ -3527,6 +3552,7 @@ bool is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)
return result;
}
+EXPORT_SYMBOL(is_subdir);
static enum d_walk_ret d_genocide_kill(void *data, struct dentry *dentry)
{
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c
index c5a53fcc43ea..f0138674c1ed 100644
--- a/fs/exofs/dir.c
+++ b/fs/exofs/dir.c
@@ -242,7 +242,7 @@ exofs_readdir(struct file *file, struct dir_context *ctx)
unsigned long n = pos >> PAGE_SHIFT;
unsigned long npages = dir_pages(inode);
unsigned chunk_mask = ~(exofs_chunk_size(inode)-1);
- bool need_revalidate = inode_cmp_iversion(inode, file->f_version);
+ bool need_revalidate = !inode_eq_iversion(inode, file->f_version);
if (pos > inode->i_size - EXOFS_DIR_REC_LEN(1))
return 0;
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 4111085a129f..3b8114def693 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -294,7 +294,7 @@ ext2_readdir(struct file *file, struct dir_context *ctx)
unsigned long npages = dir_pages(inode);
unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
unsigned char *types = NULL;
- bool need_revalidate = inode_cmp_iversion(inode, file->f_version);
+ bool need_revalidate = !inode_eq_iversion(inode, file->f_version);
if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
return 0;
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index db5f9daa7780..7666c065b96f 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -962,8 +962,11 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
if (sbi->s_mount_opt & EXT2_MOUNT_DAX) {
err = bdev_dax_supported(sb, blocksize);
- if (err)
- goto failed_mount;
+ if (err) {
+ ext2_msg(sb, KERN_ERR,
+ "DAX unsupported by block device. Turning off DAX.");
+ sbi->s_mount_opt &= ~EXT2_MOUNT_DAX;
+ }
}
/* If the blocksize doesn't match, re-read the thing.. */
@@ -1228,7 +1231,7 @@ static void ext2_clear_super_error(struct super_block *sb)
* write and hope for the best.
*/
ext2_msg(sb, KERN_ERR,
- "previous I/O error to superblock detected\n");
+ "previous I/O error to superblock detected");
clear_buffer_write_io_error(sbh);
set_buffer_uptodate(sbh);
}
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index afda0a0499ce..da87cf757f7d 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -209,7 +209,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
* readdir(2), then we might be pointing to an invalid
* dirent right now. Scan from the start of the block
* to make sure. */
- if (inode_cmp_iversion(inode, file->f_version)) {
+ if (!inode_eq_iversion(inode, file->f_version)) {
for (i = 0; i < sb->s_blocksize && i < offset; ) {
de = (struct ext4_dir_entry_2 *)
(bh->b_data + i);
@@ -569,7 +569,7 @@ static int ext4_dx_readdir(struct file *file, struct dir_context *ctx)
* cached entries.
*/
if ((!info->curr_node) ||
- inode_cmp_iversion(inode, file->f_version)) {
+ !inode_eq_iversion(inode, file->f_version)) {
info->curr_node = NULL;
free_rb_tree_fname(&info->root);
file->f_version = inode_query_iversion(inode);
diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index 7c4165b88505..70cf4c7b268a 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -1487,7 +1487,7 @@ int ext4_read_inline_dir(struct file *file,
* dirent right now. Scan from the start of the inline
* dir to make sure.
*/
- if (inode_cmp_iversion(inode, file->f_version)) {
+ if (!inode_eq_iversion(inode, file->f_version)) {
for (i = 0; i < extra_size && i < offset;) {
/*
* "." is with offset 0 and
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 421222ec3509..39bf464c35f1 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3712,11 +3712,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
if (ext4_has_feature_inline_data(sb)) {
ext4_msg(sb, KERN_ERR, "Cannot use DAX on a filesystem"
" that may contain inline data");
- goto failed_mount;
+ sbi->s_mount_opt &= ~EXT4_MOUNT_DAX;
}
err = bdev_dax_supported(sb, blocksize);
- if (err)
- goto failed_mount;
+ if (err) {
+ ext4_msg(sb, KERN_ERR,
+ "DAX unsupported by block device. Turning off DAX.");
+ sbi->s_mount_opt &= ~EXT4_MOUNT_DAX;
+ }
}
if (ext4_has_feature_encrypt(sb) && es->s_encryption_level) {
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index cefea792cde8..2649759c478a 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -46,7 +46,7 @@ static int vfat_revalidate_shortname(struct dentry *dentry)
{
int ret = 1;
spin_lock(&dentry->d_lock);
- if (inode_cmp_iversion(d_inode(dentry->d_parent), vfat_d_version(dentry)))
+ if (!inode_eq_iversion(d_inode(dentry->d_parent), vfat_d_version(dentry)))
ret = 0;
spin_unlock(&dentry->d_lock);
return ret;
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index e8120a282435..15e06fb552da 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -444,7 +444,7 @@ static int hfsplus_symlink(struct inode *dir, struct dentry *dentry,
int res = -ENOMEM;
mutex_lock(&sbi->vh_mutex);
- inode = hfsplus_new_inode(dir->i_sb, S_IFLNK | S_IRWXUGO);
+ inode = hfsplus_new_inode(dir->i_sb, dir, S_IFLNK | S_IRWXUGO);
if (!inode)
goto out;
@@ -486,7 +486,7 @@ static int hfsplus_mknod(struct inode *dir, struct dentry *dentry,
int res = -ENOMEM;
mutex_lock(&sbi->vh_mutex);
- inode = hfsplus_new_inode(dir->i_sb, mode);
+ inode = hfsplus_new_inode(dir->i_sb, dir, mode);
if (!inode)
goto out;
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index a015044daa05..d9255abafb81 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -478,7 +478,8 @@ extern const struct address_space_operations hfsplus_aops;
extern const struct address_space_operations hfsplus_btree_aops;
extern const struct dentry_operations hfsplus_dentry_operations;
-struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode);
+struct inode *hfsplus_new_inode(struct super_block *sb, struct inode *dir,
+ umode_t mode);
void hfsplus_delete_inode(struct inode *inode);
void hfsplus_inode_read_fork(struct inode *inode,
struct hfsplus_fork_raw *fork);
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 190c60efbc99..c0c8d433864f 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -354,7 +354,8 @@ static const struct file_operations hfsplus_file_operations = {
.unlocked_ioctl = hfsplus_ioctl,
};
-struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode)
+struct inode *hfsplus_new_inode(struct super_block *sb, struct inode *dir,
+ umode_t mode)
{
struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
struct inode *inode = new_inode(sb);
@@ -364,9 +365,7 @@ struct inode *hfsplus_new_inode(struct super_block *sb, umode_t mode)
return NULL;
inode->i_ino = sbi->next_cnid++;
- inode->i_mode = mode;
- inode->i_uid = current_fsuid();
- inode->i_gid = current_fsgid();
+ inode_init_owner(inode, dir, mode);
set_nlink(inode, 1);
inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 1d458b716957..513c357c734b 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -549,7 +549,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
if (!sbi->hidden_dir) {
mutex_lock(&sbi->vh_mutex);
- sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR);
+ sbi->hidden_dir = hfsplus_new_inode(sb, root, S_IFDIR);
if (!sbi->hidden_dir) {
mutex_unlock(&sbi->vh_mutex);
err = -ENOMEM;
diff --git a/fs/inode.c b/fs/inode.c
index e2ca0f4b5151..ef362364d396 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -498,7 +498,6 @@ EXPORT_SYMBOL(__remove_inode_hash);
void clear_inode(struct inode *inode)
{
- might_sleep();
/*
* We have to cycle tree_lock here because reclaim can be still in the
* process of removing the last page (in __delete_from_page_cache())
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index ceeaf0fb6657..7d893543cf3b 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1314,7 +1314,7 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr
if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
&& (fattr->valid & NFS_ATTR_FATTR_CHANGE)
- && !inode_cmp_iversion_raw(inode, fattr->pre_change_attr)) {
+ && inode_eq_iversion_raw(inode, fattr->pre_change_attr)) {
inode_set_iversion_raw(inode, fattr->change_attr);
if (S_ISDIR(inode->i_mode))
nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
@@ -1373,7 +1373,7 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
if (!nfs_file_has_buffered_writers(nfsi)) {
/* Verify a few of the more important attributes */
- if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && inode_cmp_iversion_raw(inode, fattr->change_attr))
+ if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && !inode_eq_iversion_raw(inode, fattr->change_attr))
invalid |= NFS_INO_INVALID_ATTR | NFS_INO_REVAL_PAGECACHE;
if ((fattr->valid & NFS_ATTR_FATTR_MTIME) && !timespec_equal(&inode->i_mtime, &fattr->mtime))
@@ -1803,7 +1803,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
/* More cache consistency checks */
if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
- if (inode_cmp_iversion_raw(inode, fattr->change_attr)) {
+ if (!inode_eq_iversion_raw(inode, fattr->change_attr)) {
dprintk("NFS: change_attr change on server for file %s/%ld\n",
inode->i_sb->s_id, inode->i_ino);
/* Could it be a race with writeback? */
diff --git a/fs/nilfs2/segbuf.c b/fs/nilfs2/segbuf.c
index 6c5009cc4e6f..68cb9e4740b4 100644
--- a/fs/nilfs2/segbuf.c
+++ b/fs/nilfs2/segbuf.c
@@ -130,7 +130,7 @@ int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *segbuf,
}
int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned int flags,
- time_t ctime, __u64 cno)
+ time64_t ctime, __u64 cno)
{
int err;
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
index 7bbccc099709..10e16935fff6 100644
--- a/fs/nilfs2/segbuf.h
+++ b/fs/nilfs2/segbuf.h
@@ -46,7 +46,7 @@ struct nilfs_segsum_info {
unsigned long nfileblk;
u64 seg_seq;
__u64 cno;
- time_t ctime;
+ time64_t ctime;
sector_t next;
};
@@ -120,7 +120,7 @@ void nilfs_segbuf_map_cont(struct nilfs_segment_buffer *segbuf,
struct nilfs_segment_buffer *prev);
void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64,
struct the_nilfs *);
-int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned int, time_t,
+int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned int, time64_t,
__u64);
int nilfs_segbuf_extend_segsum(struct nilfs_segment_buffer *);
int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *,
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index 9f3ffba41533..0953635e7d48 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2040,7 +2040,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
goto out;
/* Update time stamp */
- sci->sc_seg_ctime = get_seconds();
+ sci->sc_seg_ctime = ktime_get_real_seconds();
err = nilfs_segctor_collect(sci, nilfs, mode);
if (unlikely(err))
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 84084a4d9b3e..04634e3e3d58 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -157,7 +157,7 @@ struct nilfs_sc_info {
unsigned long sc_blk_cnt;
unsigned long sc_datablk_cnt;
unsigned long sc_nblk_this_inc;
- time_t sc_seg_ctime;
+ time64_t sc_seg_ctime;
__u64 sc_cno;
unsigned long sc_flags;
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index 1341a41e7b43..c7fa139d50e8 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -526,7 +526,7 @@ int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum)
* @modtime: modification time (option)
*/
int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
- unsigned long nblocks, time_t modtime)
+ unsigned long nblocks, time64_t modtime)
{
struct buffer_head *bh;
struct nilfs_segment_usage *su;
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
index 158a9190c8ec..673a891350f4 100644
--- a/fs/nilfs2/sufile.h
+++ b/fs/nilfs2/sufile.h
@@ -35,7 +35,7 @@ int nilfs_sufile_set_alloc_range(struct inode *sufile, __u64 start, __u64 end);
int nilfs_sufile_alloc(struct inode *, __u64 *);
int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum);
int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum,
- unsigned long nblocks, time_t modtime);
+ unsigned long nblocks, time64_t modtime);
int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned int,
size_t);
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 3073b646e1ba..6ffeca84d7c3 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -283,10 +283,10 @@ int nilfs_commit_super(struct super_block *sb, int flag)
{
struct the_nilfs *nilfs = sb->s_fs_info;
struct nilfs_super_block **sbp = nilfs->ns_sbp;
- time_t t;
+ time64_t t;
/* nilfs->ns_sem must be locked by the caller. */
- t = get_seconds();
+ t = ktime_get_real_seconds();
nilfs->ns_sbwtime = t;
sbp[0]->s_wtime = cpu_to_le64(t);
sbp[0]->s_sum = 0;
diff --git a/fs/nilfs2/sysfs.c b/fs/nilfs2/sysfs.c
index 490303e3d517..4b25837e7724 100644
--- a/fs/nilfs2/sysfs.c
+++ b/fs/nilfs2/sysfs.c
@@ -31,7 +31,7 @@ static struct kset *nilfs_kset;
#define NILFS_SHOW_TIME(time_t_val, buf) ({ \
struct tm res; \
int count = 0; \
- time_to_tm(time_t_val, 0, &res); \
+ time64_to_tm(time_t_val, 0, &res); \
res.tm_year += 1900; \
res.tm_mon += 1; \
count = scnprintf(buf, PAGE_SIZE, \
@@ -579,7 +579,7 @@ nilfs_segctor_last_seg_write_time_show(struct nilfs_segctor_attr *attr,
struct the_nilfs *nilfs,
char *buf)
{
- time_t ctime;
+ time64_t ctime;
down_read(&nilfs->ns_segctor_sem);
ctime = nilfs->ns_ctime;
@@ -593,13 +593,13 @@ nilfs_segctor_last_seg_write_time_secs_show(struct nilfs_segctor_attr *attr,
struct the_nilfs *nilfs,
char *buf)
{
- time_t ctime;
+ time64_t ctime;
down_read(&nilfs->ns_segctor_sem);
ctime = nilfs->ns_ctime;
up_read(&nilfs->ns_segctor_sem);
- return snprintf(buf, PAGE_SIZE, "%llu\n", (unsigned long long)ctime);
+ return snprintf(buf, PAGE_SIZE, "%llu\n", ctime);
}
static ssize_t
@@ -607,7 +607,7 @@ nilfs_segctor_last_nongc_write_time_show(struct nilfs_segctor_attr *attr,
struct the_nilfs *nilfs,
char *buf)
{
- time_t nongc_ctime;
+ time64_t nongc_ctime;
down_read(&nilfs->ns_segctor_sem);
nongc_ctime = nilfs->ns_nongc_ctime;
@@ -621,14 +621,13 @@ nilfs_segctor_last_nongc_write_time_secs_show(struct nilfs_segctor_attr *attr,
struct the_nilfs *nilfs,
char *buf)
{
- time_t nongc_ctime;
+ time64_t nongc_ctime;
down_read(&nilfs->ns_segctor_sem);
nongc_ctime = nilfs->ns_nongc_ctime;
up_read(&nilfs->ns_segctor_sem);
- return snprintf(buf, PAGE_SIZE, "%llu\n",
- (unsigned long long)nongc_ctime);
+ return snprintf(buf, PAGE_SIZE, "%llu\n", nongc_ctime);
}
static ssize_t
@@ -728,7 +727,7 @@ nilfs_superblock_sb_write_time_show(struct nilfs_superblock_attr *attr,
struct the_nilfs *nilfs,
char *buf)
{
- time_t sbwtime;
+ time64_t sbwtime;
down_read(&nilfs->ns_sem);
sbwtime = nilfs->ns_sbwtime;
@@ -742,13 +741,13 @@ nilfs_superblock_sb_write_time_secs_show(struct nilfs_superblock_attr *attr,
struct the_nilfs *nilfs,
char *buf)
{
- time_t sbwtime;
+ time64_t sbwtime;
down_read(&nilfs->ns_sem);
sbwtime = nilfs->ns_sbwtime;
up_read(&nilfs->ns_sem);
- return snprintf(buf, PAGE_SIZE, "%llu\n", (unsigned long long)sbwtime);
+ return snprintf(buf, PAGE_SIZE, "%llu\n", sbwtime);
}
static ssize_t
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 883d732b0259..36da1779f976 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -116,7 +116,7 @@ struct the_nilfs {
*/
struct buffer_head *ns_sbh[2];
struct nilfs_super_block *ns_sbp[2];
- time_t ns_sbwtime;
+ time64_t ns_sbwtime;
unsigned int ns_sbwcount;
unsigned int ns_sbsize;
unsigned int ns_mount_state;
@@ -131,8 +131,8 @@ struct the_nilfs {
__u64 ns_nextnum;
unsigned long ns_pseg_offset;
__u64 ns_cno;
- time_t ns_ctime;
- time_t ns_nongc_ctime;
+ time64_t ns_ctime;
+ time64_t ns_nongc_ctime;
atomic_t ns_ndirtyblks;
/*
@@ -267,7 +267,7 @@ struct nilfs_root {
static inline int nilfs_sb_need_update(struct the_nilfs *nilfs)
{
- u64 t = get_seconds();
+ u64 t = ktime_get_real_seconds();
return t < nilfs->ns_sbwtime ||
t > nilfs->ns_sbwtime + nilfs->ns_sb_update_freq;
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index b7520e20a770..977763d4c27d 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -1776,7 +1776,7 @@ static int ocfs2_dir_foreach_blk_id(struct inode *inode,
* readdir(2), then we might be pointing to an invalid
* dirent right now. Scan from the start of the block
* to make sure. */
- if (inode_cmp_iversion(inode, *f_version)) {
+ if (!inode_eq_iversion(inode, *f_version)) {
for (i = 0; i < i_size_read(inode) && i < offset; ) {
de = (struct ocfs2_dir_entry *)
(data->id_data + i);
@@ -1870,7 +1870,7 @@ static int ocfs2_dir_foreach_blk_el(struct inode *inode,
* readdir(2), then we might be pointing to an invalid
* dirent right now. Scan from the start of the block
* to make sure. */
- if (inode_cmp_iversion(inode, *f_version)) {
+ if (!inode_eq_iversion(inode, *f_version)) {
for (i = 0; i < sb->s_blocksize && i < offset; ) {
de = (struct ocfs2_dir_entry *) (bh->b_data + i);
/* It's too expensive to do a full
diff --git a/fs/overlayfs/Kconfig b/fs/overlayfs/Kconfig
index 5ac415466861..406e72de88f6 100644
--- a/fs/overlayfs/Kconfig
+++ b/fs/overlayfs/Kconfig
@@ -47,9 +47,28 @@ config OVERLAY_FS_INDEX
The inodes index feature prevents breaking of lower hardlinks on copy
up.
- Note, that the inodes index feature is read-only backward compatible.
- That is, mounting an overlay which has an index dir on a kernel that
- doesn't support this feature read-only, will not have any negative
- outcomes. However, mounting the same overlay with an old kernel
- read-write and then mounting it again with a new kernel, will have
- unexpected results.
+ Note, that the inodes index feature is not backward compatible.
+ That is, mounting an overlay which has an inodes index on a kernel
+ that doesn't support this feature will have unexpected results.
+
+config OVERLAY_FS_NFS_EXPORT
+ bool "Overlayfs: turn on NFS export feature by default"
+ depends on OVERLAY_FS
+ depends on OVERLAY_FS_INDEX
+ help
+ If this config option is enabled then overlay filesystems will use
+ the inodes index dir to decode overlay NFS file handles by default.
+ In this case, it is still possible to turn off NFS export support
+ globally with the "nfs_export=off" module option or on a filesystem
+ instance basis with the "nfs_export=off" mount option.
+
+ The NFS export feature creates an index on copy up of every file and
+ directory. This full index is used to detect overlay filesystems
+ inconsistencies on lookup, like redirect from multiple upper dirs to
+ the same lower dir. The full index may incur some overhead on mount
+ time, especially when verifying that directory file handles are not
+ stale.
+
+ Note, that the NFS export feature is not backward compatible.
+ That is, mounting an overlay which has a full index on a kernel
+ that doesn't support this feature will have unexpected results.
diff --git a/fs/overlayfs/Makefile b/fs/overlayfs/Makefile
index 99373bbc1478..30802347a020 100644
--- a/fs/overlayfs/Makefile
+++ b/fs/overlayfs/Makefile
@@ -4,4 +4,5 @@
obj-$(CONFIG_OVERLAY_FS) += overlay.o
-overlay-objs := super.o namei.o util.o inode.o dir.o readdir.o copy_up.o
+overlay-objs := super.o namei.o util.o inode.o dir.o readdir.o copy_up.o \
+ export.o
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index eb3b8d39fb61..d855f508fa20 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -232,13 +232,13 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat)
return err;
}
-struct ovl_fh *ovl_encode_fh(struct dentry *lower, bool is_upper)
+struct ovl_fh *ovl_encode_fh(struct dentry *real, bool is_upper)
{
struct ovl_fh *fh;
int fh_type, fh_len, dwords;
void *buf;
int buflen = MAX_HANDLE_SZ;
- uuid_t *uuid = &lower->d_sb->s_uuid;
+ uuid_t *uuid = &real->d_sb->s_uuid;
buf = kmalloc(buflen, GFP_KERNEL);
if (!buf)
@@ -250,7 +250,7 @@ struct ovl_fh *ovl_encode_fh(struct dentry *lower, bool is_upper)
* the price or reconnecting the dentry.
*/
dwords = buflen >> 2;
- fh_type = exportfs_encode_fh(lower, buf, &dwords, 0);
+ fh_type = exportfs_encode_fh(real, buf, &dwords, 0);
buflen = (dwords << 2);
fh = ERR_PTR(-EIO);
@@ -288,8 +288,8 @@ out:
return fh;
}
-static int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
- struct dentry *upper)
+int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
+ struct dentry *upper)
{
const struct ovl_fh *fh = NULL;
int err;
@@ -315,6 +315,94 @@ static int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
return err;
}
+/* Store file handle of @upper dir in @index dir entry */
+static int ovl_set_upper_fh(struct dentry *upper, struct dentry *index)
+{
+ const struct ovl_fh *fh;
+ int err;
+
+ fh = ovl_encode_fh(upper, true);
+ if (IS_ERR(fh))
+ return PTR_ERR(fh);
+
+ err = ovl_do_setxattr(index, OVL_XATTR_UPPER, fh, fh->len, 0);
+
+ kfree(fh);
+ return err;
+}
+
+/*
+ * Create and install index entry.
+ *
+ * Caller must hold i_mutex on indexdir.
+ */
+static int ovl_create_index(struct dentry *dentry, struct dentry *origin,
+ struct dentry *upper)
+{
+ struct dentry *indexdir = ovl_indexdir(dentry->d_sb);
+ struct inode *dir = d_inode(indexdir);
+ struct dentry *index = NULL;
+ struct dentry *temp = NULL;
+ struct qstr name = { };
+ int err;
+
+ /*
+ * For now this is only used for creating index entry for directories,
+ * because non-dir are copied up directly to index and then hardlinked
+ * to upper dir.
+ *
+ * TODO: implement create index for non-dir, so we can call it when
+ * encoding file handle for non-dir in case index does not exist.
+ */
+ if (WARN_ON(!d_is_dir(dentry)))
+ return -EIO;
+
+ /* Directory not expected to be indexed before copy up */
+ if (WARN_ON(ovl_test_flag(OVL_INDEX, d_inode(dentry))))
+ return -EIO;
+
+ err = ovl_get_index_name(origin, &name);
+ if (err)
+ return err;
+
+ temp = ovl_lookup_temp(indexdir);
+ if (IS_ERR(temp))
+ goto temp_err;
+
+ err = ovl_do_mkdir(dir, temp, S_IFDIR, true);
+ if (err)
+ goto out;
+
+ err = ovl_set_upper_fh(upper, temp);
+ if (err)
+ goto out_cleanup;
+
+ index = lookup_one_len(name.name, indexdir, name.len);
+ if (IS_ERR(index)) {
+ err = PTR_ERR(index);
+ } else {
+ err = ovl_do_rename(dir, temp, dir, index, 0);
+ dput(index);
+ }
+
+ if (err)
+ goto out_cleanup;
+
+out:
+ dput(temp);
+ kfree(name.name);
+ return err;
+
+temp_err:
+ err = PTR_ERR(temp);
+ temp = NULL;
+ goto out;
+
+out_cleanup:
+ ovl_cleanup(dir, temp);
+ goto out;
+}
+
struct ovl_copy_up_ctx {
struct dentry *parent;
struct dentry *dentry;
@@ -327,6 +415,7 @@ struct ovl_copy_up_ctx {
struct dentry *workdir;
bool tmpfile;
bool origin;
+ bool indexed;
};
static int ovl_link_up(struct ovl_copy_up_ctx *c)
@@ -361,7 +450,10 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)
}
}
inode_unlock(udir);
- ovl_set_nlink_upper(c->dentry);
+ if (err)
+ return err;
+
+ err = ovl_set_nlink_upper(c->dentry);
return err;
}
@@ -498,6 +590,12 @@ static int ovl_copy_up_locked(struct ovl_copy_up_ctx *c)
if (err)
goto out_cleanup;
+ if (S_ISDIR(c->stat.mode) && c->indexed) {
+ err = ovl_create_index(c->dentry, c->lowerpath.dentry, temp);
+ if (err)
+ goto out_cleanup;
+ }
+
if (c->tmpfile) {
inode_lock_nested(udir, I_MUTEX_PARENT);
err = ovl_install_temp(c, temp, &newdentry);
@@ -536,20 +634,33 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
{
int err;
struct ovl_fs *ofs = c->dentry->d_sb->s_fs_info;
- bool indexed = false;
+ bool to_index = false;
- if (ovl_indexdir(c->dentry->d_sb) && !S_ISDIR(c->stat.mode) &&
- c->stat.nlink > 1)
- indexed = true;
+ /*
+ * Indexed non-dir is copied up directly to the index entry and then
+ * hardlinked to upper dir. Indexed dir is copied up to indexdir,
+ * then index entry is created and then copied up dir installed.
+ * Copying dir up to indexdir instead of workdir simplifies locking.
+ */
+ if (ovl_need_index(c->dentry)) {
+ c->indexed = true;
+ if (S_ISDIR(c->stat.mode))
+ c->workdir = ovl_indexdir(c->dentry->d_sb);
+ else
+ to_index = true;
+ }
- if (S_ISDIR(c->stat.mode) || c->stat.nlink == 1 || indexed)
+ if (S_ISDIR(c->stat.mode) || c->stat.nlink == 1 || to_index)
c->origin = true;
- if (indexed) {
+ if (to_index) {
c->destdir = ovl_indexdir(c->dentry->d_sb);
err = ovl_get_index_name(c->lowerpath.dentry, &c->destname);
if (err)
return err;
+ } else if (WARN_ON(!c->parent)) {
+ /* Disconnected dentry must be copied up to index dir */
+ return -EIO;
} else {
/*
* Mark parent "impure" because it may now contain non-pure
@@ -572,11 +683,17 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
}
}
- if (indexed) {
- if (!err)
- ovl_set_flag(OVL_INDEX, d_inode(c->dentry));
- kfree(c->destname.name);
- } else if (!err) {
+
+ if (err)
+ goto out;
+
+ if (c->indexed)
+ ovl_set_flag(OVL_INDEX, d_inode(c->dentry));
+
+ if (to_index) {
+ /* Initialize nlink for copy up of disconnected dentry */
+ err = ovl_set_nlink_upper(c->dentry);
+ } else {
struct inode *udir = d_inode(c->destdir);
/* Restore timestamps on parent (best effort) */
@@ -587,6 +704,9 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
ovl_dentry_set_upper_alias(c->dentry);
}
+out:
+ if (to_index)
+ kfree(c->destname.name);
return err;
}
@@ -611,14 +731,17 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
if (err)
return err;
- ovl_path_upper(parent, &parentpath);
- ctx.destdir = parentpath.dentry;
- ctx.destname = dentry->d_name;
+ if (parent) {
+ ovl_path_upper(parent, &parentpath);
+ ctx.destdir = parentpath.dentry;
+ ctx.destname = dentry->d_name;
- err = vfs_getattr(&parentpath, &ctx.pstat,
- STATX_ATIME | STATX_MTIME, AT_STATX_SYNC_AS_STAT);
- if (err)
- return err;
+ err = vfs_getattr(&parentpath, &ctx.pstat,
+ STATX_ATIME | STATX_MTIME,
+ AT_STATX_SYNC_AS_STAT);
+ if (err)
+ return err;
+ }
/* maybe truncate regular file. this has no effect on dirs */
if (flags & O_TRUNC)
@@ -639,7 +762,7 @@ static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
} else {
if (!ovl_dentry_upper(dentry))
err = ovl_do_copy_up(&ctx);
- if (!err && !ovl_dentry_has_upper_alias(dentry))
+ if (!err && parent && !ovl_dentry_has_upper_alias(dentry))
err = ovl_link_up(&ctx);
ovl_copy_up_end(dentry);
}
@@ -652,10 +775,19 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags)
{
int err = 0;
const struct cred *old_cred = ovl_override_creds(dentry->d_sb);
+ bool disconnected = (dentry->d_flags & DCACHE_DISCONNECTED);
+
+ /*
+ * With NFS export, copy up can get called for a disconnected non-dir.
+ * In this case, we will copy up lower inode to index dir without
+ * linking it to upper dir.
+ */
+ if (WARN_ON(disconnected && d_is_dir(dentry)))
+ return -EIO;
while (!err) {
struct dentry *next;
- struct dentry *parent;
+ struct dentry *parent = NULL;
/*
* Check if copy-up has happened as well as for upper alias (in
@@ -671,12 +803,12 @@ int ovl_copy_up_flags(struct dentry *dentry, int flags)
* with rename.
*/
if (ovl_dentry_upper(dentry) &&
- ovl_dentry_has_upper_alias(dentry))
+ (ovl_dentry_has_upper_alias(dentry) || disconnected))
break;
next = dget(dentry);
/* find the topmost dentry not yet copied up */
- for (;;) {
+ for (; !disconnected;) {
parent = dget_parent(next);
if (ovl_dentry_upper(parent))
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index f9788bc116a8..839709c7803a 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -63,8 +63,7 @@ struct dentry *ovl_lookup_temp(struct dentry *workdir)
}
/* caller holds i_mutex on workdir */
-static struct dentry *ovl_whiteout(struct dentry *workdir,
- struct dentry *dentry)
+static struct dentry *ovl_whiteout(struct dentry *workdir)
{
int err;
struct dentry *whiteout;
@@ -83,6 +82,38 @@ static struct dentry *ovl_whiteout(struct dentry *workdir,
return whiteout;
}
+/* Caller must hold i_mutex on both workdir and dir */
+int ovl_cleanup_and_whiteout(struct dentry *workdir, struct inode *dir,
+ struct dentry *dentry)
+{
+ struct inode *wdir = workdir->d_inode;
+ struct dentry *whiteout;
+ int err;
+ int flags = 0;
+
+ whiteout = ovl_whiteout(workdir);
+ err = PTR_ERR(whiteout);
+ if (IS_ERR(whiteout))
+ return err;
+
+ if (d_is_dir(dentry))
+ flags = RENAME_EXCHANGE;
+
+ err = ovl_do_rename(wdir, whiteout, dir, dentry, flags);
+ if (err)
+ goto kill_whiteout;
+ if (flags)
+ ovl_cleanup(wdir, dentry);
+
+out:
+ dput(whiteout);
+ return err;
+
+kill_whiteout:
+ ovl_cleanup(wdir, whiteout);
+ goto out;
+}
+
int ovl_create_real(struct inode *dir, struct dentry *newdentry,
struct cattr *attr, struct dentry *hardlink, bool debug)
{
@@ -181,11 +212,6 @@ static bool ovl_type_origin(struct dentry *dentry)
return OVL_TYPE_ORIGIN(ovl_path_type(dentry));
}
-static bool ovl_may_have_whiteouts(struct dentry *dentry)
-{
- return ovl_test_flag(OVL_WHITEOUTS, d_inode(dentry));
-}
-
static int ovl_create_upper(struct dentry *dentry, struct inode *inode,
struct cattr *attr, struct dentry *hardlink)
{
@@ -301,37 +327,6 @@ out:
return ERR_PTR(err);
}
-static struct dentry *ovl_check_empty_and_clear(struct dentry *dentry)
-{
- int err;
- struct dentry *ret = NULL;
- LIST_HEAD(list);
-
- err = ovl_check_empty_dir(dentry, &list);
- if (err) {
- ret = ERR_PTR(err);
- goto out_free;
- }
-
- /*
- * When removing an empty opaque directory, then it makes no sense to
- * replace it with an exact replica of itself.
- *
- * If upperdentry has whiteouts, clear them.
- *
- * Can race with copy-up, since we don't hold the upperdir mutex.
- * Doesn't matter, since copy-up can't create a non-empty directory
- * from an empty one.
- */
- if (!list_empty(&list))
- ret = ovl_clear_empty(dentry, &list);
-
-out_free:
- ovl_cache_free(&list);
-
- return ret;
-}
-
static int ovl_set_upper_acl(struct dentry *upperdentry, const char *name,
const struct posix_acl *acl)
{
@@ -623,23 +618,20 @@ static bool ovl_matches_upper(struct dentry *dentry, struct dentry *upper)
return d_inode(ovl_dentry_upper(dentry)) == d_inode(upper);
}
-static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir)
+static int ovl_remove_and_whiteout(struct dentry *dentry,
+ struct list_head *list)
{
struct dentry *workdir = ovl_workdir(dentry);
- struct inode *wdir = workdir->d_inode;
struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
- struct inode *udir = upperdir->d_inode;
- struct dentry *whiteout;
struct dentry *upper;
struct dentry *opaquedir = NULL;
int err;
- int flags = 0;
if (WARN_ON(!workdir))
return -EROFS;
- if (is_dir) {
- opaquedir = ovl_check_empty_and_clear(dentry);
+ if (!list_empty(list)) {
+ opaquedir = ovl_clear_empty(dentry, list);
err = PTR_ERR(opaquedir);
if (IS_ERR(opaquedir))
goto out;
@@ -662,24 +654,13 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir)
goto out_dput_upper;
}
- whiteout = ovl_whiteout(workdir, dentry);
- err = PTR_ERR(whiteout);
- if (IS_ERR(whiteout))
- goto out_dput_upper;
-
- if (d_is_dir(upper))
- flags = RENAME_EXCHANGE;
-
- err = ovl_do_rename(wdir, whiteout, udir, upper, flags);
+ err = ovl_cleanup_and_whiteout(workdir, d_inode(upperdir), upper);
if (err)
- goto kill_whiteout;
- if (flags)
- ovl_cleanup(wdir, upper);
+ goto out_d_drop;
ovl_dentry_version_inc(dentry->d_parent, true);
out_d_drop:
d_drop(dentry);
- dput(whiteout);
out_dput_upper:
dput(upper);
out_unlock:
@@ -688,13 +669,10 @@ out_dput:
dput(opaquedir);
out:
return err;
-
-kill_whiteout:
- ovl_cleanup(wdir, whiteout);
- goto out_d_drop;
}
-static int ovl_remove_upper(struct dentry *dentry, bool is_dir)
+static int ovl_remove_upper(struct dentry *dentry, bool is_dir,
+ struct list_head *list)
{
struct dentry *upperdir = ovl_dentry_upper(dentry->d_parent);
struct inode *dir = upperdir->d_inode;
@@ -702,10 +680,8 @@ static int ovl_remove_upper(struct dentry *dentry, bool is_dir)
struct dentry *opaquedir = NULL;
int err;
- /* Redirect/origin dir can be !ovl_lower_positive && not clean */
- if (is_dir && (ovl_dentry_get_redirect(dentry) ||
- ovl_may_have_whiteouts(dentry))) {
- opaquedir = ovl_check_empty_and_clear(dentry);
+ if (!list_empty(list)) {
+ opaquedir = ovl_clear_empty(dentry, list);
err = PTR_ERR(opaquedir);
if (IS_ERR(opaquedir))
goto out;
@@ -746,11 +722,26 @@ out:
return err;
}
+static bool ovl_pure_upper(struct dentry *dentry)
+{
+ return !ovl_dentry_lower(dentry) &&
+ !ovl_test_flag(OVL_WHITEOUTS, d_inode(dentry));
+}
+
static int ovl_do_remove(struct dentry *dentry, bool is_dir)
{
int err;
bool locked = false;
const struct cred *old_cred;
+ bool lower_positive = ovl_lower_positive(dentry);
+ LIST_HEAD(list);
+
+ /* No need to clean pure upper removed by vfs_rmdir() */
+ if (is_dir && (lower_positive || !ovl_pure_upper(dentry))) {
+ err = ovl_check_empty_dir(dentry, &list);
+ if (err)
+ goto out;
+ }
err = ovl_want_write(dentry);
if (err)
@@ -765,10 +756,10 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir)
goto out_drop_write;
old_cred = ovl_override_creds(dentry->d_sb);
- if (!ovl_lower_positive(dentry))
- err = ovl_remove_upper(dentry, is_dir);
+ if (!lower_positive)
+ err = ovl_remove_upper(dentry, is_dir, &list);
else
- err = ovl_remove_and_whiteout(dentry, is_dir);
+ err = ovl_remove_and_whiteout(dentry, &list);
revert_creds(old_cred);
if (!err) {
if (is_dir)
@@ -780,6 +771,7 @@ static int ovl_do_remove(struct dentry *dentry, bool is_dir)
out_drop_write:
ovl_drop_write(dentry);
out:
+ ovl_cache_free(&list);
return err;
}
@@ -915,6 +907,7 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
bool samedir = olddir == newdir;
struct dentry *opaquedir = NULL;
const struct cred *old_cred = NULL;
+ LIST_HEAD(list);
err = -EINVAL;
if (flags & ~(RENAME_EXCHANGE | RENAME_NOREPLACE))
@@ -929,6 +922,27 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
if (!overwrite && !ovl_can_move(new))
goto out;
+ if (overwrite && new_is_dir && !ovl_pure_upper(new)) {
+ err = ovl_check_empty_dir(new, &list);
+ if (err)
+ goto out;
+ }
+
+ if (overwrite) {
+ if (ovl_lower_positive(old)) {
+ if (!ovl_dentry_is_whiteout(new)) {
+ /* Whiteout source */
+ flags |= RENAME_WHITEOUT;
+ } else {
+ /* Switch whiteouts */
+ flags |= RENAME_EXCHANGE;
+ }
+ } else if (is_dir && ovl_dentry_is_whiteout(new)) {
+ flags |= RENAME_EXCHANGE;
+ cleanup_whiteout = true;
+ }
+ }
+
err = ovl_want_write(old);
if (err)
goto out;
@@ -952,9 +966,8 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
old_cred = ovl_override_creds(old->d_sb);
- if (overwrite && new_is_dir && (ovl_type_merge_or_lower(new) ||
- ovl_may_have_whiteouts(new))) {
- opaquedir = ovl_check_empty_and_clear(new);
+ if (!list_empty(&list)) {
+ opaquedir = ovl_clear_empty(new, &list);
err = PTR_ERR(opaquedir);
if (IS_ERR(opaquedir)) {
opaquedir = NULL;
@@ -962,21 +975,6 @@ static int ovl_rename(struct inode *olddir, struct dentry *old,
}
}
- if (overwrite) {
- if (ovl_lower_positive(old)) {
- if (!ovl_dentry_is_whiteout(new)) {
- /* Whiteout source */
- flags |= RENAME_WHITEOUT;
- } else {
- /* Switch whiteouts */
- flags |= RENAME_EXCHANGE;
- }
- } else if (is_dir && ovl_dentry_is_whiteout(new)) {
- flags |= RENAME_EXCHANGE;
- cleanup_whiteout = true;
- }
- }
-
old_upperdir = ovl_dentry_upper(old->d_parent);
new_upperdir = ovl_dentry_upper(new->d_parent);
@@ -1094,6 +1092,7 @@ out_drop_write:
ovl_drop_write(old);
out:
dput(opaquedir);
+ ovl_cache_free(&list);
return err;
}
diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c
new file mode 100644
index 000000000000..bb94ce9da5c8
--- /dev/null
+++ b/fs/overlayfs/export.c
@@ -0,0 +1,715 @@
+/*
+ * Overlayfs NFS export support.
+ *
+ * Amir Goldstein <amir73il@gmail.com>
+ *
+ * Copyright (C) 2017-2018 CTERA Networks. 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/fs.h>
+#include <linux/cred.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/xattr.h>
+#include <linux/exportfs.h>
+#include <linux/ratelimit.h>
+#include "overlayfs.h"
+
+/*
+ * We only need to encode origin if there is a chance that the same object was
+ * encoded pre copy up and then we need to stay consistent with the same
+ * encoding also after copy up. If non-pure upper is not indexed, then it was
+ * copied up before NFS export was enabled. In that case we don't need to worry
+ * about staying consistent with pre copy up encoding and we encode an upper
+ * file handle. Overlay root dentry is a private case of non-indexed upper.
+ *
+ * The following table summarizes the different file handle encodings used for
+ * different overlay object types:
+ *
+ * Object type | Encoding
+ * --------------------------------
+ * Pure upper | U
+ * Non-indexed upper | U
+ * Indexed upper | L (*)
+ * Non-upper | L (*)
+ *
+ * U = upper file handle
+ * L = lower file handle
+ *
+ * (*) Connecting an overlay dir from real lower dentry is not always
+ * possible when there are redirects in lower layers. To mitigate this case,
+ * we copy up the lower dir first and then encode an upper dir file handle.
+ */
+static bool ovl_should_encode_origin(struct dentry *dentry)
+{
+ struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
+
+ if (!ovl_dentry_lower(dentry))
+ return false;
+
+ /*
+ * Decoding a merge dir, whose origin's parent is under a redirected
+ * lower dir is not always possible. As a simple aproximation, we do
+ * not encode lower dir file handles when overlay has multiple lower
+ * layers and origin is below the topmost lower layer.
+ *
+ * TODO: copy up only the parent that is under redirected lower.
+ */
+ if (d_is_dir(dentry) && ofs->upper_mnt &&
+ OVL_E(dentry)->lowerstack[0].layer->idx > 1)
+ return false;
+
+ /* Decoding a non-indexed upper from origin is not implemented */
+ if (ovl_dentry_upper(dentry) &&
+ !ovl_test_flag(OVL_INDEX, d_inode(dentry)))
+ return false;
+
+ return true;
+}
+
+static int ovl_encode_maybe_copy_up(struct dentry *dentry)
+{
+ int err;
+
+ if (ovl_dentry_upper(dentry))
+ return 0;
+
+ err = ovl_want_write(dentry);
+ if (err)
+ return err;
+
+ err = ovl_copy_up(dentry);
+
+ ovl_drop_write(dentry);
+ return err;
+}
+
+static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
+{
+ struct dentry *origin = ovl_dentry_lower(dentry);
+ struct ovl_fh *fh = NULL;
+ int err;
+
+ /*
+ * If we should not encode a lower dir file handle, copy up and encode
+ * an upper dir file handle.
+ */
+ if (!ovl_should_encode_origin(dentry)) {
+ err = ovl_encode_maybe_copy_up(dentry);
+ if (err)
+ goto fail;
+
+ origin = NULL;
+ }
+
+ /* Encode an upper or origin file handle */
+ fh = ovl_encode_fh(origin ?: ovl_dentry_upper(dentry), !origin);
+ err = PTR_ERR(fh);
+ if (IS_ERR(fh))
+ goto fail;
+
+ err = -EOVERFLOW;
+ if (fh->len > buflen)
+ goto fail;
+
+ memcpy(buf, (char *)fh, fh->len);
+ err = fh->len;
+
+out:
+ kfree(fh);
+ return err;
+
+fail:
+ pr_warn_ratelimited("overlayfs: failed to encode file handle (%pd2, err=%i, buflen=%d, len=%d, type=%d)\n",
+ dentry, err, buflen, fh ? (int)fh->len : 0,
+ fh ? fh->type : 0);
+ goto out;
+}
+
+static int ovl_dentry_to_fh(struct dentry *dentry, u32 *fid, int *max_len)
+{
+ int res, len = *max_len << 2;
+
+ res = ovl_d_to_fh(dentry, (char *)fid, len);
+ if (res <= 0)
+ return FILEID_INVALID;
+
+ len = res;
+
+ /* Round up to dwords */
+ *max_len = (len + 3) >> 2;
+ return OVL_FILEID;
+}
+
+static int ovl_encode_inode_fh(struct inode *inode, u32 *fid, int *max_len,
+ struct inode *parent)
+{
+ struct dentry *dentry;
+ int type;
+
+ /* TODO: encode connectable file handles */
+ if (parent)
+ return FILEID_INVALID;
+
+ dentry = d_find_any_alias(inode);
+ if (WARN_ON(!dentry))
+ return FILEID_INVALID;
+
+ type = ovl_dentry_to_fh(dentry, fid, max_len);
+
+ dput(dentry);
+ return type;
+}
+
+/*
+ * Find or instantiate an overlay dentry from real dentries and index.
+ */
+static struct dentry *ovl_obtain_alias(struct super_block *sb,
+ struct dentry *upper_alias,
+ struct ovl_path *lowerpath,
+ struct dentry *index)
+{
+ struct dentry *lower = lowerpath ? lowerpath->dentry : NULL;
+ struct dentry *upper = upper_alias ?: index;
+ struct dentry *dentry;
+ struct inode *inode;
+ struct ovl_entry *oe;
+
+ /* We get overlay directory dentries with ovl_lookup_real() */
+ if (d_is_dir(upper ?: lower))
+ return ERR_PTR(-EIO);
+
+ inode = ovl_get_inode(sb, dget(upper), lower, index, !!lower);
+ if (IS_ERR(inode)) {
+ dput(upper);
+ return ERR_CAST(inode);
+ }
+
+ if (index)
+ ovl_set_flag(OVL_INDEX, inode);
+
+ dentry = d_find_any_alias(inode);
+ if (!dentry) {
+ dentry = d_alloc_anon(inode->i_sb);
+ if (!dentry)
+ goto nomem;
+ oe = ovl_alloc_entry(lower ? 1 : 0);
+ if (!oe)
+ goto nomem;
+
+ if (lower) {
+ oe->lowerstack->dentry = dget(lower);
+ oe->lowerstack->layer = lowerpath->layer;
+ }
+ dentry->d_fsdata = oe;
+ if (upper_alias)
+ ovl_dentry_set_upper_alias(dentry);
+ }
+
+ return d_instantiate_anon(dentry, inode);
+
+nomem:
+ iput(inode);
+ dput(dentry);
+ return ERR_PTR(-ENOMEM);
+}
+
+/* Get the upper or lower dentry in stach whose on layer @idx */
+static struct dentry *ovl_dentry_real_at(struct dentry *dentry, int idx)
+{
+ struct ovl_entry *oe = dentry->d_fsdata;
+ int i;
+
+ if (!idx)
+ return ovl_dentry_upper(dentry);
+
+ for (i = 0; i < oe->numlower; i++) {
+ if (oe->lowerstack[i].layer->idx == idx)
+ return oe->lowerstack[i].dentry;
+ }
+
+ return NULL;
+}
+
+/*
+ * Lookup a child overlay dentry to get a connected overlay dentry whose real
+ * dentry is @real. If @real is on upper layer, we lookup a child overlay
+ * dentry with the same name as the real dentry. Otherwise, we need to consult
+ * index for lookup.
+ */
+static struct dentry *ovl_lookup_real_one(struct dentry *connected,
+ struct dentry *real,
+ struct ovl_layer *layer)
+{
+ struct inode *dir = d_inode(connected);
+ struct dentry *this, *parent = NULL;
+ struct name_snapshot name;
+ int err;
+
+ /*
+ * Lookup child overlay dentry by real name. The dir mutex protects us
+ * from racing with overlay rename. If the overlay dentry that is above
+ * real has already been moved to a parent that is not under the
+ * connected overlay dir, we return -ECHILD and restart the lookup of
+ * connected real path from the top.
+ */
+ inode_lock_nested(dir, I_MUTEX_PARENT);
+ err = -ECHILD;
+ parent = dget_parent(real);
+ if (ovl_dentry_real_at(connected, layer->idx) != parent)
+ goto fail;
+
+ /*
+ * We also need to take a snapshot of real dentry name to protect us
+ * from racing with underlying layer rename. In this case, we don't
+ * care about returning ESTALE, only from dereferencing a free name
+ * pointer because we hold no lock on the real dentry.
+ */
+ take_dentry_name_snapshot(&name, real);
+ this = lookup_one_len(name.name, connected, strlen(name.name));
+ err = PTR_ERR(this);
+ if (IS_ERR(this)) {
+ goto fail;
+ } else if (!this || !this->d_inode) {
+ dput(this);
+ err = -ENOENT;
+ goto fail;
+ } else if (ovl_dentry_real_at(this, layer->idx) != real) {
+ dput(this);
+ err = -ESTALE;
+ goto fail;
+ }
+
+out:
+ release_dentry_name_snapshot(&name);
+ dput(parent);
+ inode_unlock(dir);
+ return this;
+
+fail:
+ pr_warn_ratelimited("overlayfs: failed to lookup one by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
+ real, layer->idx, connected, err);
+ this = ERR_PTR(err);
+ goto out;
+}
+
+static struct dentry *ovl_lookup_real(struct super_block *sb,
+ struct dentry *real,
+ struct ovl_layer *layer);
+
+/*
+ * Lookup an indexed or hashed overlay dentry by real inode.
+ */
+static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
+ struct dentry *real,
+ struct ovl_layer *layer)
+{
+ struct ovl_fs *ofs = sb->s_fs_info;
+ struct ovl_layer upper_layer = { .mnt = ofs->upper_mnt };
+ struct dentry *index = NULL;
+ struct dentry *this = NULL;
+ struct inode *inode;
+
+ /*
+ * Decoding upper dir from index is expensive, so first try to lookup
+ * overlay dentry in inode/dcache.
+ */
+ inode = ovl_lookup_inode(sb, real, !layer->idx);
+ if (IS_ERR(inode))
+ return ERR_CAST(inode);
+ if (inode) {
+ this = d_find_any_alias(inode);
+ iput(inode);
+ }
+
+ /*
+ * For decoded lower dir file handle, lookup index by origin to check
+ * if lower dir was copied up and and/or removed.
+ */
+ if (!this && layer->idx && ofs->indexdir && !WARN_ON(!d_is_dir(real))) {
+ index = ovl_lookup_index(ofs, NULL, real, false);
+ if (IS_ERR(index))
+ return index;
+ }
+
+ /* Get connected upper overlay dir from index */
+ if (index) {
+ struct dentry *upper = ovl_index_upper(ofs, index);
+
+ dput(index);
+ if (IS_ERR_OR_NULL(upper))
+ return upper;
+
+ /*
+ * ovl_lookup_real() in lower layer may call recursively once to
+ * ovl_lookup_real() in upper layer. The first level call walks
+ * back lower parents to the topmost indexed parent. The second
+ * recursive call walks back from indexed upper to the topmost
+ * connected/hashed upper parent (or up to root).
+ */
+ this = ovl_lookup_real(sb, upper, &upper_layer);
+ dput(upper);
+ }
+
+ if (!this)
+ return NULL;
+
+ if (WARN_ON(ovl_dentry_real_at(this, layer->idx) != real)) {
+ dput(this);
+ this = ERR_PTR(-EIO);
+ }
+
+ return this;
+}
+
+/*
+ * Lookup an indexed or hashed overlay dentry, whose real dentry is an
+ * ancestor of @real.
+ */
+static struct dentry *ovl_lookup_real_ancestor(struct super_block *sb,
+ struct dentry *real,
+ struct ovl_layer *layer)
+{
+ struct dentry *next, *parent = NULL;
+ struct dentry *ancestor = ERR_PTR(-EIO);
+
+ if (real == layer->mnt->mnt_root)
+ return dget(sb->s_root);
+
+ /* Find the topmost indexed or hashed ancestor */
+ next = dget(real);
+ for (;;) {
+ parent = dget_parent(next);
+
+ /*
+ * Lookup a matching overlay dentry in inode/dentry
+ * cache or in index by real inode.
+ */
+ ancestor = ovl_lookup_real_inode(sb, next, layer);
+ if (ancestor)
+ break;
+
+ if (parent == layer->mnt->mnt_root) {
+ ancestor = dget(sb->s_root);
+ break;
+ }
+
+ /*
+ * If @real has been moved out of the layer root directory,
+ * we will eventully hit the real fs root. This cannot happen
+ * by legit overlay rename, so we return error in that case.
+ */
+ if (parent == next) {
+ ancestor = ERR_PTR(-EXDEV);
+ break;
+ }
+
+ dput(next);
+ next = parent;
+ }
+
+ dput(parent);
+ dput(next);
+
+ return ancestor;
+}
+
+/*
+ * Lookup a connected overlay dentry whose real dentry is @real.
+ * If @real is on upper layer, we lookup a child overlay dentry with the same
+ * path the real dentry. Otherwise, we need to consult index for lookup.
+ */
+static struct dentry *ovl_lookup_real(struct super_block *sb,
+ struct dentry *real,
+ struct ovl_layer *layer)
+{
+ struct dentry *connected;
+ int err = 0;
+
+ connected = ovl_lookup_real_ancestor(sb, real, layer);
+ if (IS_ERR(connected))
+ return connected;
+
+ while (!err) {
+ struct dentry *next, *this;
+ struct dentry *parent = NULL;
+ struct dentry *real_connected = ovl_dentry_real_at(connected,
+ layer->idx);
+
+ if (real_connected == real)
+ break;
+
+ /* Find the topmost dentry not yet connected */
+ next = dget(real);
+ for (;;) {
+ parent = dget_parent(next);
+
+ if (parent == real_connected)
+ break;
+
+ /*
+ * If real has been moved out of 'real_connected',
+ * we will not find 'real_connected' and hit the layer
+ * root. In that case, we need to restart connecting.
+ * This game can go on forever in the worst case. We
+ * may want to consider taking s_vfs_rename_mutex if
+ * this happens more than once.
+ */
+ if (parent == layer->mnt->mnt_root) {
+ dput(connected);
+ connected = dget(sb->s_root);
+ break;
+ }
+
+ /*
+ * If real file has been moved out of the layer root
+ * directory, we will eventully hit the real fs root.
+ * This cannot happen by legit overlay rename, so we
+ * return error in that case.
+ */
+ if (parent == next) {
+ err = -EXDEV;
+ break;
+ }
+
+ dput(next);
+ next = parent;
+ }
+
+ if (!err) {
+ this = ovl_lookup_real_one(connected, next, layer);
+ if (IS_ERR(this))
+ err = PTR_ERR(this);
+
+ /*
+ * Lookup of child in overlay can fail when racing with
+ * overlay rename of child away from 'connected' parent.
+ * In this case, we need to restart the lookup from the
+ * top, because we cannot trust that 'real_connected' is
+ * still an ancestor of 'real'. There is a good chance
+ * that the renamed overlay ancestor is now in cache, so
+ * ovl_lookup_real_ancestor() will find it and we can
+ * continue to connect exactly from where lookup failed.
+ */
+ if (err == -ECHILD) {
+ this = ovl_lookup_real_ancestor(sb, real,
+ layer);
+ err = IS_ERR(this) ? PTR_ERR(this) : 0;
+ }
+ if (!err) {
+ dput(connected);
+ connected = this;
+ }
+ }
+
+ dput(parent);
+ dput(next);
+ }
+
+ if (err)
+ goto fail;
+
+ return connected;
+
+fail:
+ pr_warn_ratelimited("overlayfs: failed to lookup by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
+ real, layer->idx, connected, err);
+ dput(connected);
+ return ERR_PTR(err);
+}
+
+/*
+ * Get an overlay dentry from upper/lower real dentries and index.
+ */
+static struct dentry *ovl_get_dentry(struct super_block *sb,
+ struct dentry *upper,
+ struct ovl_path *lowerpath,
+ struct dentry *index)
+{
+ struct ovl_fs *ofs = sb->s_fs_info;
+ struct ovl_layer upper_layer = { .mnt = ofs->upper_mnt };
+ struct ovl_layer *layer = upper ? &upper_layer : lowerpath->layer;
+ struct dentry *real = upper ?: (index ?: lowerpath->dentry);
+
+ /*
+ * Obtain a disconnected overlay dentry from a non-dir real dentry
+ * and index.
+ */
+ if (!d_is_dir(real))
+ return ovl_obtain_alias(sb, upper, lowerpath, index);
+
+ /* Removed empty directory? */
+ if ((real->d_flags & DCACHE_DISCONNECTED) || d_unhashed(real))
+ return ERR_PTR(-ENOENT);
+
+ /*
+ * If real dentry is connected and hashed, get a connected overlay
+ * dentry whose real dentry is @real.
+ */
+ return ovl_lookup_real(sb, real, layer);
+}
+
+static struct dentry *ovl_upper_fh_to_d(struct super_block *sb,
+ struct ovl_fh *fh)
+{
+ struct ovl_fs *ofs = sb->s_fs_info;
+ struct dentry *dentry;
+ struct dentry *upper;
+
+ if (!ofs->upper_mnt)
+ return ERR_PTR(-EACCES);
+
+ upper = ovl_decode_fh(fh, ofs->upper_mnt);
+ if (IS_ERR_OR_NULL(upper))
+ return upper;
+
+ dentry = ovl_get_dentry(sb, upper, NULL, NULL);
+ dput(upper);
+
+ return dentry;
+}
+
+static struct dentry *ovl_lower_fh_to_d(struct super_block *sb,
+ struct ovl_fh *fh)
+{
+ struct ovl_fs *ofs = sb->s_fs_info;
+ struct ovl_path origin = { };
+ struct ovl_path *stack = &origin;
+ struct dentry *dentry = NULL;
+ struct dentry *index = NULL;
+ struct inode *inode = NULL;
+ bool is_deleted = false;
+ int err;
+
+ /* First lookup indexed upper by fh */
+ if (ofs->indexdir) {
+ index = ovl_get_index_fh(ofs, fh);
+ err = PTR_ERR(index);
+ if (IS_ERR(index)) {
+ if (err != -ESTALE)
+ return ERR_PTR(err);
+
+ /* Found a whiteout index - treat as deleted inode */
+ is_deleted = true;
+ index = NULL;
+ }
+ }
+
+ /* Then try to get upper dir by index */
+ if (index && d_is_dir(index)) {
+ struct dentry *upper = ovl_index_upper(ofs, index);
+
+ err = PTR_ERR(upper);
+ if (IS_ERR_OR_NULL(upper))
+ goto out_err;
+
+ dentry = ovl_get_dentry(sb, upper, NULL, NULL);
+ dput(upper);
+ goto out;
+ }
+
+ /* Then lookup origin by fh */
+ err = ovl_check_origin_fh(ofs, fh, NULL, &stack);
+ if (err) {
+ goto out_err;
+ } else if (index) {
+ err = ovl_verify_origin(index, origin.dentry, false);
+ if (err)
+ goto out_err;
+ } else if (is_deleted) {
+ /* Lookup deleted non-dir by origin inode */
+ if (!d_is_dir(origin.dentry))
+ inode = ovl_lookup_inode(sb, origin.dentry, false);
+ err = -ESTALE;
+ if (!inode || atomic_read(&inode->i_count) == 1)
+ goto out_err;
+
+ /* Deleted but still open? */
+ index = dget(ovl_i_dentry_upper(inode));
+ }
+
+ dentry = ovl_get_dentry(sb, NULL, &origin, index);
+
+out:
+ dput(origin.dentry);
+ dput(index);
+ iput(inode);
+ return dentry;
+
+out_err:
+ dentry = ERR_PTR(err);
+ goto out;
+}
+
+static struct dentry *ovl_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ struct dentry *dentry = NULL;
+ struct ovl_fh *fh = (struct ovl_fh *) fid;
+ int len = fh_len << 2;
+ unsigned int flags = 0;
+ int err;
+
+ err = -EINVAL;
+ if (fh_type != OVL_FILEID)
+ goto out_err;
+
+ err = ovl_check_fh_len(fh, len);
+ if (err)
+ goto out_err;
+
+ flags = fh->flags;
+ dentry = (flags & OVL_FH_FLAG_PATH_UPPER) ?
+ ovl_upper_fh_to_d(sb, fh) :
+ ovl_lower_fh_to_d(sb, fh);
+ err = PTR_ERR(dentry);
+ if (IS_ERR(dentry) && err != -ESTALE)
+ goto out_err;
+
+ return dentry;
+
+out_err:
+ pr_warn_ratelimited("overlayfs: failed to decode file handle (len=%d, type=%d, flags=%x, err=%i)\n",
+ len, fh_type, flags, err);
+ return ERR_PTR(err);
+}
+
+static struct dentry *ovl_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ pr_warn_ratelimited("overlayfs: connectable file handles not supported; use 'no_subtree_check' exportfs option.\n");
+ return ERR_PTR(-EACCES);
+}
+
+static int ovl_get_name(struct dentry *parent, char *name,
+ struct dentry *child)
+{
+ /*
+ * ovl_fh_to_dentry() returns connected dir overlay dentries and
+ * ovl_fh_to_parent() is not implemented, so we should not get here.
+ */
+ WARN_ON_ONCE(1);
+ return -EIO;
+}
+
+static struct dentry *ovl_get_parent(struct dentry *dentry)
+{
+ /*
+ * ovl_fh_to_dentry() returns connected dir overlay dentries, so we
+ * should not get here.
+ */
+ WARN_ON_ONCE(1);
+ return ERR_PTR(-EIO);
+}
+
+const struct export_operations ovl_export_operations = {
+ .encode_fh = ovl_encode_inode_fh,
+ .fh_to_dentry = ovl_fh_to_dentry,
+ .fh_to_parent = ovl_fh_to_parent,
+ .get_name = ovl_get_name,
+ .get_parent = ovl_get_parent,
+};
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 00b6b294272a..fcd97b783fa1 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -105,12 +105,20 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
* Lower hardlinks may be broken on copy up to different
* upper files, so we cannot use the lower origin st_ino
* for those different files, even for the same fs case.
+ *
+ * Similarly, several redirected dirs can point to the
+ * same dir on a lower layer. With the "verify_lower"
+ * feature, we do not use the lower origin st_ino, if
+ * we haven't verified that this redirect is unique.
+ *
* With inodes index enabled, it is safe to use st_ino
- * of an indexed hardlinked origin. The index validates
- * that the upper hardlink is not broken.
+ * of an indexed origin. The index validates that the
+ * upper hardlink is not broken and that a redirected
+ * dir is the only redirect to that origin.
*/
- if (is_dir || lowerstat.nlink == 1 ||
- ovl_test_flag(OVL_INDEX, d_inode(dentry)))
+ if (ovl_test_flag(OVL_INDEX, d_inode(dentry)) ||
+ (!ovl_verify_lower(dentry->d_sb) &&
+ (is_dir || lowerstat.nlink == 1)))
stat->ino = lowerstat.ino;
if (samefs)
@@ -343,8 +351,10 @@ struct posix_acl *ovl_get_acl(struct inode *inode, int type)
static bool ovl_open_need_copy_up(struct dentry *dentry, int flags)
{
+ /* Copy up of disconnected dentry does not set upper alias */
if (ovl_dentry_upper(dentry) &&
- ovl_dentry_has_upper_alias(dentry))
+ (ovl_dentry_has_upper_alias(dentry) ||
+ (dentry->d_flags & DCACHE_DISCONNECTED)))
return false;
if (special_file(d_inode(dentry)->i_mode))
@@ -604,9 +614,25 @@ static int ovl_inode_set(struct inode *inode, void *data)
}
static bool ovl_verify_inode(struct inode *inode, struct dentry *lowerdentry,
- struct dentry *upperdentry)
+ struct dentry *upperdentry, bool strict)
{
/*
+ * For directories, @strict verify from lookup path performs consistency
+ * checks, so NULL lower/upper in dentry must match NULL lower/upper in
+ * inode. Non @strict verify from NFS handle decode path passes NULL for
+ * 'unknown' lower/upper.
+ */
+ if (S_ISDIR(inode->i_mode) && strict) {
+ /* Real lower dir moved to upper layer under us? */
+ if (!lowerdentry && ovl_inode_lower(inode))
+ return false;
+
+ /* Lookup of an uncovered redirect origin? */
+ if (!upperdentry && ovl_inode_upper(inode))
+ return false;
+ }
+
+ /*
* Allow non-NULL lower inode in ovl_inode even if lowerdentry is NULL.
* This happens when finding a copied up overlay inode for a renamed
* or hardlinked overlay dentry and lower dentry cannot be followed
@@ -625,14 +651,35 @@ static bool ovl_verify_inode(struct inode *inode, struct dentry *lowerdentry,
return true;
}
-struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry,
- struct dentry *index)
+struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real,
+ bool is_upper)
{
- struct dentry *lowerdentry = ovl_dentry_lower(dentry);
+ struct inode *inode, *key = d_inode(real);
+
+ inode = ilookup5(sb, (unsigned long) key, ovl_inode_test, key);
+ if (!inode)
+ return NULL;
+
+ if (!ovl_verify_inode(inode, is_upper ? NULL : real,
+ is_upper ? real : NULL, false)) {
+ iput(inode);
+ return ERR_PTR(-ESTALE);
+ }
+
+ return inode;
+}
+
+struct inode *ovl_get_inode(struct super_block *sb, struct dentry *upperdentry,
+ struct dentry *lowerdentry, struct dentry *index,
+ unsigned int numlower)
+{
+ struct ovl_fs *ofs = sb->s_fs_info;
struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL;
struct inode *inode;
/* Already indexed or could be indexed on copy up? */
- bool indexed = (index || (ovl_indexdir(dentry->d_sb) && !upperdentry));
+ bool indexed = (index || (ovl_indexdir(sb) && !upperdentry));
+ struct dentry *origin = indexed ? lowerdentry : NULL;
+ bool is_dir;
if (WARN_ON(upperdentry && indexed && !lowerdentry))
return ERR_PTR(-EIO);
@@ -641,17 +688,22 @@ struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry,
realinode = d_inode(lowerdentry);
/*
- * Copy up origin (lower) may exist for non-indexed upper, but we must
- * not use lower as hash key in that case.
- * Hash inodes that are or could be indexed by origin inode and
- * non-indexed upper inodes that could be hard linked by upper inode.
+ * Copy up origin (lower) may exist for non-indexed non-dir upper, but
+ * we must not use lower as hash key in that case.
+ * Hash non-dir that is or could be indexed by origin inode.
+ * Hash dir that is or could be merged by origin inode.
+ * Hash pure upper and non-indexed non-dir by upper inode.
+ * Hash non-indexed dir by upper inode for NFS export.
*/
- if (!S_ISDIR(realinode->i_mode) && (upperdentry || indexed)) {
- struct inode *key = d_inode(indexed ? lowerdentry :
- upperdentry);
- unsigned int nlink;
+ is_dir = S_ISDIR(realinode->i_mode);
+ if (is_dir && (indexed || !sb->s_export_op || !ofs->upper_mnt))
+ origin = lowerdentry;
+
+ if (upperdentry || origin) {
+ struct inode *key = d_inode(origin ?: upperdentry);
+ unsigned int nlink = is_dir ? 1 : realinode->i_nlink;
- inode = iget5_locked(dentry->d_sb, (unsigned long) key,
+ inode = iget5_locked(sb, (unsigned long) key,
ovl_inode_test, ovl_inode_set, key);
if (!inode)
goto out_nomem;
@@ -660,7 +712,8 @@ struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry,
* Verify that the underlying files stored in the inode
* match those in the dentry.
*/
- if (!ovl_verify_inode(inode, lowerdentry, upperdentry)) {
+ if (!ovl_verify_inode(inode, lowerdentry, upperdentry,
+ true)) {
iput(inode);
inode = ERR_PTR(-ESTALE);
goto out;
@@ -670,11 +723,12 @@ struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry,
goto out;
}
- nlink = ovl_get_nlink(lowerdentry, upperdentry,
- realinode->i_nlink);
+ /* Recalculate nlink for non-dir due to indexing */
+ if (!is_dir)
+ nlink = ovl_get_nlink(lowerdentry, upperdentry, nlink);
set_nlink(inode, nlink);
} else {
- inode = new_inode(dentry->d_sb);
+ inode = new_inode(sb);
if (!inode)
goto out_nomem;
}
@@ -685,10 +739,8 @@ struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry,
ovl_set_flag(OVL_IMPURE, inode);
/* Check for non-merge dir that may have whiteouts */
- if (S_ISDIR(realinode->i_mode)) {
- struct ovl_entry *oe = dentry->d_fsdata;
-
- if (((upperdentry && lowerdentry) || oe->numlower > 1) ||
+ if (is_dir) {
+ if (((upperdentry && lowerdentry) || numlower > 1) ||
ovl_check_origin_xattr(upperdentry ?: lowerdentry)) {
ovl_set_flag(OVL_WHITEOUTS, inode);
}
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index beb945e1963c..de3e6da1d5a5 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -9,6 +9,7 @@
#include <linux/fs.h>
#include <linux/cred.h>
+#include <linux/ctype.h>
#include <linux/namei.h>
#include <linux/xattr.h>
#include <linux/ratelimit.h>
@@ -84,15 +85,54 @@ invalid:
static int ovl_acceptable(void *ctx, struct dentry *dentry)
{
- return 1;
+ /*
+ * A non-dir origin may be disconnected, which is fine, because
+ * we only need it for its unique inode number.
+ */
+ if (!d_is_dir(dentry))
+ return 1;
+
+ /* Don't decode a deleted empty directory */
+ if (d_unhashed(dentry))
+ return 0;
+
+ /* Check if directory belongs to the layer we are decoding from */
+ return is_subdir(dentry, ((struct vfsmount *)ctx)->mnt_root);
}
-static struct ovl_fh *ovl_get_origin_fh(struct dentry *dentry)
+/*
+ * Check validity of an overlay file handle buffer.
+ *
+ * Return 0 for a valid file handle.
+ * Return -ENODATA for "origin unknown".
+ * Return <0 for an invalid file handle.
+ */
+int ovl_check_fh_len(struct ovl_fh *fh, int fh_len)
{
- int res;
+ if (fh_len < sizeof(struct ovl_fh) || fh_len < fh->len)
+ return -EINVAL;
+
+ if (fh->magic != OVL_FH_MAGIC)
+ return -EINVAL;
+
+ /* Treat larger version and unknown flags as "origin unknown" */
+ if (fh->version > OVL_FH_VERSION || fh->flags & ~OVL_FH_FLAG_ALL)
+ return -ENODATA;
+
+ /* Treat endianness mismatch as "origin unknown" */
+ if (!(fh->flags & OVL_FH_FLAG_ANY_ENDIAN) &&
+ (fh->flags & OVL_FH_FLAG_BIG_ENDIAN) != OVL_FH_FLAG_CPU_ENDIAN)
+ return -ENODATA;
+
+ return 0;
+}
+
+static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name)
+{
+ int res, err;
struct ovl_fh *fh = NULL;
- res = vfs_getxattr(dentry, OVL_XATTR_ORIGIN, NULL, 0);
+ res = vfs_getxattr(dentry, name, NULL, 0);
if (res < 0) {
if (res == -ENODATA || res == -EOPNOTSUPP)
return NULL;
@@ -102,28 +142,20 @@ static struct ovl_fh *ovl_get_origin_fh(struct dentry *dentry)
if (res == 0)
return NULL;
- fh = kzalloc(res, GFP_KERNEL);
+ fh = kzalloc(res, GFP_KERNEL);
if (!fh)
return ERR_PTR(-ENOMEM);
- res = vfs_getxattr(dentry, OVL_XATTR_ORIGIN, fh, res);
+ res = vfs_getxattr(dentry, name, fh, res);
if (res < 0)
goto fail;
- if (res < sizeof(struct ovl_fh) || res < fh->len)
- goto invalid;
-
- if (fh->magic != OVL_FH_MAGIC)
+ err = ovl_check_fh_len(fh, res);
+ if (err < 0) {
+ if (err == -ENODATA)
+ goto out;
goto invalid;
-
- /* Treat larger version and unknown flags as "origin unknown" */
- if (fh->version > OVL_FH_VERSION || fh->flags & ~OVL_FH_FLAG_ALL)
- goto out;
-
- /* Treat endianness mismatch as "origin unknown" */
- if (!(fh->flags & OVL_FH_FLAG_ANY_ENDIAN) &&
- (fh->flags & OVL_FH_FLAG_BIG_ENDIAN) != OVL_FH_FLAG_CPU_ENDIAN)
- goto out;
+ }
return fh;
@@ -139,47 +171,41 @@ invalid:
goto out;
}
-static struct dentry *ovl_get_origin(struct dentry *dentry,
- struct vfsmount *mnt)
+struct dentry *ovl_decode_fh(struct ovl_fh *fh, struct vfsmount *mnt)
{
- struct dentry *origin = NULL;
- struct ovl_fh *fh = ovl_get_origin_fh(dentry);
+ struct dentry *real;
int bytes;
- if (IS_ERR_OR_NULL(fh))
- return (struct dentry *)fh;
-
/*
* Make sure that the stored uuid matches the uuid of the lower
* layer where file handle will be decoded.
*/
if (!uuid_equal(&fh->uuid, &mnt->mnt_sb->s_uuid))
- goto out;
+ return NULL;
bytes = (fh->len - offsetof(struct ovl_fh, fid));
- origin = exportfs_decode_fh(mnt, (struct fid *)fh->fid,
- bytes >> 2, (int)fh->type,
- ovl_acceptable, NULL);
- if (IS_ERR(origin)) {
- /* Treat stale file handle as "origin unknown" */
- if (origin == ERR_PTR(-ESTALE))
- origin = NULL;
- goto out;
+ real = exportfs_decode_fh(mnt, (struct fid *)fh->fid,
+ bytes >> 2, (int)fh->type,
+ ovl_acceptable, mnt);
+ if (IS_ERR(real)) {
+ /*
+ * Treat stale file handle to lower file as "origin unknown".
+ * upper file handle could become stale when upper file is
+ * unlinked and this information is needed to handle stale
+ * index entries correctly.
+ */
+ if (real == ERR_PTR(-ESTALE) &&
+ !(fh->flags & OVL_FH_FLAG_PATH_UPPER))
+ real = NULL;
+ return real;
}
- if (ovl_dentry_weird(origin) ||
- ((d_inode(origin)->i_mode ^ d_inode(dentry)->i_mode) & S_IFMT))
- goto invalid;
-
-out:
- kfree(fh);
- return origin;
+ if (ovl_dentry_weird(real)) {
+ dput(real);
+ return NULL;
+ }
-invalid:
- pr_warn_ratelimited("overlayfs: invalid origin (%pd2)\n", origin);
- dput(origin);
- origin = NULL;
- goto out;
+ return real;
}
static bool ovl_is_opaquedir(struct dentry *dentry)
@@ -284,47 +310,81 @@ static int ovl_lookup_layer(struct dentry *base, struct ovl_lookup_data *d,
}
-static int ovl_check_origin(struct dentry *upperdentry,
- struct ovl_path *lower, unsigned int numlower,
- struct ovl_path **stackp, unsigned int *ctrp)
+int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh,
+ struct dentry *upperdentry, struct ovl_path **stackp)
{
- struct vfsmount *mnt;
struct dentry *origin = NULL;
int i;
- for (i = 0; i < numlower; i++) {
- mnt = lower[i].layer->mnt;
- origin = ovl_get_origin(upperdentry, mnt);
- if (IS_ERR(origin))
- return PTR_ERR(origin);
-
+ for (i = 0; i < ofs->numlower; i++) {
+ origin = ovl_decode_fh(fh, ofs->lower_layers[i].mnt);
if (origin)
break;
}
if (!origin)
- return 0;
+ return -ESTALE;
+ else if (IS_ERR(origin))
+ return PTR_ERR(origin);
+
+ if (upperdentry && !ovl_is_whiteout(upperdentry) &&
+ ((d_inode(origin)->i_mode ^ d_inode(upperdentry)->i_mode) & S_IFMT))
+ goto invalid;
- BUG_ON(*ctrp);
if (!*stackp)
*stackp = kmalloc(sizeof(struct ovl_path), GFP_KERNEL);
if (!*stackp) {
dput(origin);
return -ENOMEM;
}
- **stackp = (struct ovl_path){.dentry = origin, .layer = lower[i].layer};
- *ctrp = 1;
+ **stackp = (struct ovl_path){
+ .dentry = origin,
+ .layer = &ofs->lower_layers[i]
+ };
+
+ return 0;
+
+invalid:
+ pr_warn_ratelimited("overlayfs: invalid origin (%pd2, ftype=%x, origin ftype=%x).\n",
+ upperdentry, d_inode(upperdentry)->i_mode & S_IFMT,
+ d_inode(origin)->i_mode & S_IFMT);
+ dput(origin);
+ return -EIO;
+}
+
+static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry,
+ struct ovl_path **stackp, unsigned int *ctrp)
+{
+ struct ovl_fh *fh = ovl_get_fh(upperdentry, OVL_XATTR_ORIGIN);
+ int err;
+
+ if (IS_ERR_OR_NULL(fh))
+ return PTR_ERR(fh);
+
+ err = ovl_check_origin_fh(ofs, fh, upperdentry, stackp);
+ kfree(fh);
+
+ if (err) {
+ if (err == -ESTALE)
+ return 0;
+ return err;
+ }
+
+ if (WARN_ON(*ctrp))
+ return -EIO;
+ *ctrp = 1;
return 0;
}
/*
- * Verify that @fh matches the origin file handle stored in OVL_XATTR_ORIGIN.
+ * Verify that @fh matches the file handle stored in xattr @name.
* Return 0 on match, -ESTALE on mismatch, < 0 on error.
*/
-static int ovl_verify_origin_fh(struct dentry *dentry, const struct ovl_fh *fh)
+static int ovl_verify_fh(struct dentry *dentry, const char *name,
+ const struct ovl_fh *fh)
{
- struct ovl_fh *ofh = ovl_get_origin_fh(dentry);
+ struct ovl_fh *ofh = ovl_get_fh(dentry, name);
int err = 0;
if (!ofh)
@@ -341,28 +401,28 @@ static int ovl_verify_origin_fh(struct dentry *dentry, const struct ovl_fh *fh)
}
/*
- * Verify that an inode matches the origin file handle stored in upper inode.
+ * Verify that @real dentry matches the file handle stored in xattr @name.
*
- * If @set is true and there is no stored file handle, encode and store origin
- * file handle in OVL_XATTR_ORIGIN.
+ * If @set is true and there is no stored file handle, encode @real and store
+ * file handle in xattr @name.
*
- * Return 0 on match, -ESTALE on mismatch, < 0 on error.
+ * Return 0 on match, -ESTALE on mismatch, -ENODATA on no xattr, < 0 on error.
*/
-int ovl_verify_origin(struct dentry *dentry, struct dentry *origin,
- bool is_upper, bool set)
+int ovl_verify_set_fh(struct dentry *dentry, const char *name,
+ struct dentry *real, bool is_upper, bool set)
{
struct inode *inode;
struct ovl_fh *fh;
int err;
- fh = ovl_encode_fh(origin, is_upper);
+ fh = ovl_encode_fh(real, is_upper);
err = PTR_ERR(fh);
if (IS_ERR(fh))
goto fail;
- err = ovl_verify_origin_fh(dentry, fh);
+ err = ovl_verify_fh(dentry, name, fh);
if (set && err == -ENODATA)
- err = ovl_do_setxattr(dentry, OVL_XATTR_ORIGIN, fh, fh->len, 0);
+ err = ovl_do_setxattr(dentry, name, fh, fh->len, 0);
if (err)
goto fail;
@@ -371,45 +431,71 @@ out:
return err;
fail:
- inode = d_inode(origin);
- pr_warn_ratelimited("overlayfs: failed to verify origin (%pd2, ino=%lu, err=%i)\n",
- origin, inode ? inode->i_ino : 0, err);
+ inode = d_inode(real);
+ pr_warn_ratelimited("overlayfs: failed to verify %s (%pd2, ino=%lu, err=%i)\n",
+ is_upper ? "upper" : "origin", real,
+ inode ? inode->i_ino : 0, err);
goto out;
}
+/* Get upper dentry from index */
+struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index)
+{
+ struct ovl_fh *fh;
+ struct dentry *upper;
+
+ if (!d_is_dir(index))
+ return dget(index);
+
+ fh = ovl_get_fh(index, OVL_XATTR_UPPER);
+ if (IS_ERR_OR_NULL(fh))
+ return ERR_CAST(fh);
+
+ upper = ovl_decode_fh(fh, ofs->upper_mnt);
+ kfree(fh);
+
+ if (IS_ERR_OR_NULL(upper))
+ return upper ?: ERR_PTR(-ESTALE);
+
+ if (!d_is_dir(upper)) {
+ pr_warn_ratelimited("overlayfs: invalid index upper (%pd2, upper=%pd2).\n",
+ index, upper);
+ dput(upper);
+ return ERR_PTR(-EIO);
+ }
+
+ return upper;
+}
+
+/* Is this a leftover from create/whiteout of directory index entry? */
+static bool ovl_is_temp_index(struct dentry *index)
+{
+ return index->d_name.name[0] == '#';
+}
+
/*
* Verify that an index entry name matches the origin file handle stored in
* OVL_XATTR_ORIGIN and that origin file handle can be decoded to lower path.
* Return 0 on match, -ESTALE on mismatch or stale origin, < 0 on error.
*/
-int ovl_verify_index(struct dentry *index, struct ovl_path *lower,
- unsigned int numlower)
+int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
{
struct ovl_fh *fh = NULL;
size_t len;
struct ovl_path origin = { };
struct ovl_path *stack = &origin;
- unsigned int ctr = 0;
+ struct dentry *upper = NULL;
int err;
if (!d_inode(index))
return 0;
- /*
- * Directory index entries are going to be used for looking up
- * redirected upper dirs by lower dir fh when decoding an overlay
- * file handle of a merge dir. Whiteout index entries are going to be
- * used as an indication that an exported overlay file handle should
- * be treated as stale (i.e. after unlink of the overlay inode).
- * We don't know the verification rules for directory and whiteout
- * index entries, because they have not been implemented yet, so return
- * EINVAL if those entries are found to abort the mount to avoid
- * corrupting an index that was created by a newer kernel.
- */
- err = -EINVAL;
- if (d_is_dir(index) || ovl_is_whiteout(index))
+ /* Cleanup leftover from index create/cleanup attempt */
+ err = -ESTALE;
+ if (ovl_is_temp_index(index))
goto fail;
+ err = -EINVAL;
if (index->d_name.len < sizeof(struct ovl_fh)*2)
goto fail;
@@ -420,26 +506,68 @@ int ovl_verify_index(struct dentry *index, struct ovl_path *lower,
goto fail;
err = -EINVAL;
- if (hex2bin((u8 *)fh, index->d_name.name, len) || len != fh->len)
+ if (hex2bin((u8 *)fh, index->d_name.name, len))
goto fail;
- err = ovl_verify_origin_fh(index, fh);
+ err = ovl_check_fh_len(fh, len);
if (err)
goto fail;
- err = ovl_check_origin(index, lower, numlower, &stack, &ctr);
- if (!err && !ctr)
- err = -ESTALE;
+ /*
+ * Whiteout index entries are used as an indication that an exported
+ * overlay file handle should be treated as stale (i.e. after unlink
+ * of the overlay inode). These entries contain no origin xattr.
+ */
+ if (ovl_is_whiteout(index))
+ goto out;
+
+ /*
+ * Verifying directory index entries are not stale is expensive, so
+ * only verify stale dir index if NFS export is enabled.
+ */
+ if (d_is_dir(index) && !ofs->config.nfs_export)
+ goto out;
+
+ /*
+ * Directory index entries should have 'upper' xattr pointing to the
+ * real upper dir. Non-dir index entries are hardlinks to the upper
+ * real inode. For non-dir index, we can read the copy up origin xattr
+ * directly from the index dentry, but for dir index we first need to
+ * decode the upper directory.
+ */
+ upper = ovl_index_upper(ofs, index);
+ if (IS_ERR_OR_NULL(upper)) {
+ err = PTR_ERR(upper);
+ /*
+ * Directory index entries with no 'upper' xattr need to be
+ * removed. When dir index entry has a stale 'upper' xattr,
+ * we assume that upper dir was removed and we treat the dir
+ * index as orphan entry that needs to be whited out.
+ */
+ if (err == -ESTALE)
+ goto orphan;
+ else if (!err)
+ err = -ESTALE;
+ goto fail;
+ }
+
+ err = ovl_verify_fh(upper, OVL_XATTR_ORIGIN, fh);
+ dput(upper);
if (err)
goto fail;
- /* Check if index is orphan and don't warn before cleaning it */
- if (d_inode(index)->i_nlink == 1 &&
- ovl_get_nlink(origin.dentry, index, 0) == 0)
- err = -ENOENT;
+ /* Check if non-dir index is orphan and don't warn before cleaning it */
+ if (!d_is_dir(index) && d_inode(index)->i_nlink == 1) {
+ err = ovl_check_origin_fh(ofs, fh, index, &stack);
+ if (err)
+ goto fail;
+
+ if (ovl_get_nlink(origin.dentry, index, 0) == 0)
+ goto orphan;
+ }
- dput(origin.dentry);
out:
+ dput(origin.dentry);
kfree(fh);
return err;
@@ -447,6 +575,28 @@ fail:
pr_warn_ratelimited("overlayfs: failed to verify index (%pd2, ftype=%x, err=%i)\n",
index, d_inode(index)->i_mode & S_IFMT, err);
goto out;
+
+orphan:
+ pr_warn_ratelimited("overlayfs: orphan index entry (%pd2, ftype=%x, nlink=%u)\n",
+ index, d_inode(index)->i_mode & S_IFMT,
+ d_inode(index)->i_nlink);
+ err = -ENOENT;
+ goto out;
+}
+
+static int ovl_get_index_name_fh(struct ovl_fh *fh, struct qstr *name)
+{
+ char *n, *s;
+
+ n = kzalloc(fh->len * 2, GFP_KERNEL);
+ if (!n)
+ return -ENOMEM;
+
+ s = bin2hex(n, fh, fh->len);
+ *name = (struct qstr) QSTR_INIT(n, s - n);
+
+ return 0;
+
}
/*
@@ -466,35 +616,58 @@ fail:
*/
int ovl_get_index_name(struct dentry *origin, struct qstr *name)
{
- int err;
struct ovl_fh *fh;
- char *n, *s;
+ int err;
fh = ovl_encode_fh(origin, false);
if (IS_ERR(fh))
return PTR_ERR(fh);
- err = -ENOMEM;
- n = kzalloc(fh->len * 2, GFP_KERNEL);
- if (n) {
- s = bin2hex(n, fh, fh->len);
- *name = (struct qstr) QSTR_INIT(n, s - n);
- err = 0;
- }
- kfree(fh);
+ err = ovl_get_index_name_fh(fh, name);
+ kfree(fh);
return err;
+}
+
+/* Lookup index by file handle for NFS export */
+struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh)
+{
+ struct dentry *index;
+ struct qstr name;
+ int err;
+
+ err = ovl_get_index_name_fh(fh, &name);
+ if (err)
+ return ERR_PTR(err);
+
+ index = lookup_one_len_unlocked(name.name, ofs->indexdir, name.len);
+ kfree(name.name);
+ if (IS_ERR(index)) {
+ if (PTR_ERR(index) == -ENOENT)
+ index = NULL;
+ return index;
+ }
+ if (d_is_negative(index))
+ err = 0;
+ else if (ovl_is_whiteout(index))
+ err = -ESTALE;
+ else if (ovl_dentry_weird(index))
+ err = -EIO;
+ else
+ return index;
+
+ dput(index);
+ return ERR_PTR(err);
}
-static struct dentry *ovl_lookup_index(struct dentry *dentry,
- struct dentry *upper,
- struct dentry *origin)
+struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
+ struct dentry *origin, bool verify)
{
- struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
struct dentry *index;
struct inode *inode;
struct qstr name;
+ bool is_dir = d_is_dir(origin);
int err;
err = ovl_get_index_name(origin, &name);
@@ -518,8 +691,16 @@ static struct dentry *ovl_lookup_index(struct dentry *dentry,
inode = d_inode(index);
if (d_is_negative(index)) {
goto out_dput;
- } else if (upper && d_inode(upper) != inode) {
- goto out_dput;
+ } else if (ovl_is_whiteout(index) && !verify) {
+ /*
+ * When index lookup is called with !verify for decoding an
+ * overlay file handle, a whiteout index implies that decode
+ * should treat file handle as stale and no need to print a
+ * warning about it.
+ */
+ dput(index);
+ index = ERR_PTR(-ESTALE);
+ goto out;
} else if (ovl_dentry_weird(index) || ovl_is_whiteout(index) ||
((inode->i_mode ^ d_inode(origin)->i_mode) & S_IFMT)) {
/*
@@ -533,8 +714,25 @@ static struct dentry *ovl_lookup_index(struct dentry *dentry,
index, d_inode(index)->i_mode & S_IFMT,
d_inode(origin)->i_mode & S_IFMT);
goto fail;
- }
+ } else if (is_dir && verify) {
+ if (!upper) {
+ pr_warn_ratelimited("overlayfs: suspected uncovered redirected dir found (origin=%pd2, index=%pd2).\n",
+ origin, index);
+ goto fail;
+ }
+ /* Verify that dir index 'upper' xattr points to upper dir */
+ err = ovl_verify_upper(index, upper, false);
+ if (err) {
+ if (err == -ESTALE) {
+ pr_warn_ratelimited("overlayfs: suspected multiply redirected dir found (upper=%pd2, origin=%pd2, index=%pd2).\n",
+ upper, origin, index);
+ }
+ goto fail;
+ }
+ } else if (upper && d_inode(upper) != inode) {
+ goto out_dput;
+ }
out:
kfree(name.name);
return index;
@@ -572,16 +770,25 @@ int ovl_path_next(int idx, struct dentry *dentry, struct path *path)
return (idx < oe->numlower) ? idx + 1 : -1;
}
-static int ovl_find_layer(struct ovl_fs *ofs, struct ovl_path *path)
+/* Fix missing 'origin' xattr */
+static int ovl_fix_origin(struct dentry *dentry, struct dentry *lower,
+ struct dentry *upper)
{
- int i;
+ int err;
- for (i = 0; i < ofs->numlower; i++) {
- if (ofs->lower_layers[i].mnt == path->layer->mnt)
- break;
- }
+ if (ovl_check_origin_xattr(upper))
+ return 0;
+
+ err = ovl_want_write(dentry);
+ if (err)
+ return err;
+
+ err = ovl_set_origin(dentry, lower, upper);
+ if (!err)
+ err = ovl_set_impure(dentry->d_parent, upper->d_parent);
- return i;
+ ovl_drop_write(dentry);
+ return err;
}
struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
@@ -594,6 +801,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
struct ovl_entry *roe = dentry->d_sb->s_root->d_fsdata;
struct ovl_path *stack = NULL;
struct dentry *upperdir, *upperdentry = NULL;
+ struct dentry *origin = NULL;
struct dentry *index = NULL;
unsigned int ctr = 0;
struct inode *inode = NULL;
@@ -638,8 +846,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
* number - it's the same as if we held a reference
* to a dentry in lower layer that was moved under us.
*/
- err = ovl_check_origin(upperdentry, roe->lowerstack,
- roe->numlower, &stack, &ctr);
+ err = ovl_check_origin(ofs, upperdentry, &stack, &ctr);
if (err)
goto out_put_upper;
}
@@ -674,6 +881,34 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
if (!this)
continue;
+ /*
+ * If no origin fh is stored in upper of a merge dir, store fh
+ * of lower dir and set upper parent "impure".
+ */
+ if (upperdentry && !ctr && !ofs->noxattr) {
+ err = ovl_fix_origin(dentry, this, upperdentry);
+ if (err) {
+ dput(this);
+ goto out_put;
+ }
+ }
+
+ /*
+ * When "verify_lower" feature is enabled, do not merge with a
+ * lower dir that does not match a stored origin xattr. In any
+ * case, only verified origin is used for index lookup.
+ */
+ if (upperdentry && !ctr && ovl_verify_lower(dentry->d_sb)) {
+ err = ovl_verify_origin(upperdentry, this, false);
+ if (err) {
+ dput(this);
+ break;
+ }
+
+ /* Bless lower dir as verified origin */
+ origin = this;
+ }
+
stack[ctr].dentry = this;
stack[ctr].layer = lower.layer;
ctr++;
@@ -693,25 +928,30 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
*/
err = -EPERM;
if (d.redirect && !ofs->config.redirect_follow) {
- pr_warn_ratelimited("overlay: refusing to follow redirect for (%pd2)\n", dentry);
+ pr_warn_ratelimited("overlayfs: refusing to follow redirect for (%pd2)\n",
+ dentry);
goto out_put;
}
if (d.redirect && d.redirect[0] == '/' && poe != roe) {
poe = roe;
-
/* Find the current layer on the root dentry */
- i = ovl_find_layer(ofs, &lower);
- if (WARN_ON(i == ofs->numlower))
- break;
+ i = lower.layer->idx - 1;
}
}
- /* Lookup index by lower inode and verify it matches upper inode */
- if (ctr && !d.is_dir && ovl_indexdir(dentry->d_sb)) {
- struct dentry *origin = stack[0].dentry;
+ /*
+ * Lookup index by lower inode and verify it matches upper inode.
+ * We only trust dir index if we verified that lower dir matches
+ * origin, otherwise dir index entries may be inconsistent and we
+ * ignore them. Always lookup index of non-dir and non-upper.
+ */
+ if (ctr && (!upperdentry || !d.is_dir))
+ origin = stack[0].dentry;
- index = ovl_lookup_index(dentry, upperdentry, origin);
+ if (origin && ovl_indexdir(dentry->d_sb) &&
+ (!d.is_dir || ovl_index_all(dentry->d_sb))) {
+ index = ovl_lookup_index(ofs, upperdentry, origin, true);
if (IS_ERR(index)) {
err = PTR_ERR(index);
index = NULL;
@@ -724,17 +964,22 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
if (!oe)
goto out_put;
- oe->opaque = upperopaque;
memcpy(oe->lowerstack, stack, sizeof(struct ovl_path) * ctr);
dentry->d_fsdata = oe;
+ if (upperopaque)
+ ovl_dentry_set_opaque(dentry);
+
if (upperdentry)
ovl_dentry_set_upper_alias(dentry);
else if (index)
upperdentry = dget(index);
if (upperdentry || ctr) {
- inode = ovl_get_inode(dentry, upperdentry, index);
+ if (ctr)
+ origin = stack[0].dentry;
+ inode = ovl_get_inode(dentry->d_sb, upperdentry, origin, index,
+ ctr);
err = PTR_ERR(inode);
if (IS_ERR(inode))
goto out_free_oe;
@@ -748,9 +993,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
dput(index);
kfree(stack);
kfree(d.redirect);
- d_add(dentry, inode);
-
- return NULL;
+ return d_splice_alias(inode, dentry);
out_free_oe:
dentry->d_fsdata = NULL;
@@ -771,9 +1014,9 @@ out:
bool ovl_lower_positive(struct dentry *dentry)
{
- struct ovl_entry *oe = dentry->d_fsdata;
struct ovl_entry *poe = dentry->d_parent->d_fsdata;
const struct qstr *name = &dentry->d_name;
+ const struct cred *old_cred;
unsigned int i;
bool positive = false;
bool done = false;
@@ -783,12 +1026,13 @@ bool ovl_lower_positive(struct dentry *dentry)
* whiteout.
*/
if (!dentry->d_inode)
- return oe->opaque;
+ return ovl_dentry_is_opaque(dentry);
/* Negative upper -> positive lower */
if (!ovl_dentry_upper(dentry))
return true;
+ old_cred = ovl_override_creds(dentry->d_sb);
/* Positive upper -> have to look up lower to see whether it exists */
for (i = 0; !done && !positive && i < poe->numlower; i++) {
struct dentry *this;
@@ -818,6 +1062,7 @@ bool ovl_lower_positive(struct dentry *dentry)
dput(this);
}
}
+ revert_creds(old_cred);
return positive;
}
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index b489099ccd49..0df25a9c94bd 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -27,8 +27,9 @@ enum ovl_path_type {
#define OVL_XATTR_ORIGIN OVL_XATTR_PREFIX "origin"
#define OVL_XATTR_IMPURE OVL_XATTR_PREFIX "impure"
#define OVL_XATTR_NLINK OVL_XATTR_PREFIX "nlink"
+#define OVL_XATTR_UPPER OVL_XATTR_PREFIX "upper"
-enum ovl_flag {
+enum ovl_inode_flag {
/* Pure upper dir that may contain non pure upper entries */
OVL_IMPURE,
/* Non-merge dir that may contain whiteout entries */
@@ -36,6 +37,11 @@ enum ovl_flag {
OVL_INDEX,
};
+enum ovl_entry_flag {
+ OVL_E_UPPER_ALIAS,
+ OVL_E_OPAQUE,
+};
+
/*
* The tuple (fh,uuid) is a universal unique identifier for a copy up origin,
* where:
@@ -62,6 +68,9 @@ enum ovl_flag {
#error Endianness not defined
#endif
+/* The type returned by overlay exportfs ops when encoding an ovl_fh handle */
+#define OVL_FILEID 0xfb
+
/* On-disk and in-memeory format for redirect by file handle */
struct ovl_fh {
u8 version; /* 0 */
@@ -194,6 +203,8 @@ const struct cred *ovl_override_creds(struct super_block *sb);
struct super_block *ovl_same_sb(struct super_block *sb);
bool ovl_can_decode_fh(struct super_block *sb);
struct dentry *ovl_indexdir(struct super_block *sb);
+bool ovl_index_all(struct super_block *sb);
+bool ovl_verify_lower(struct super_block *sb);
struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
bool ovl_dentry_remote(struct dentry *dentry);
bool ovl_dentry_weird(struct dentry *dentry);
@@ -210,6 +221,9 @@ struct inode *ovl_inode_lower(struct inode *inode);
struct inode *ovl_inode_real(struct inode *inode);
struct ovl_dir_cache *ovl_dir_cache(struct inode *inode);
void ovl_set_dir_cache(struct inode *inode, struct ovl_dir_cache *cache);
+void ovl_dentry_set_flag(unsigned long flag, struct dentry *dentry);
+void ovl_dentry_clear_flag(unsigned long flag, struct dentry *dentry);
+bool ovl_dentry_test_flag(unsigned long flag, struct dentry *dentry);
bool ovl_dentry_is_opaque(struct dentry *dentry);
bool ovl_dentry_is_whiteout(struct dentry *dentry);
void ovl_dentry_set_opaque(struct dentry *dentry);
@@ -238,6 +252,7 @@ void ovl_clear_flag(unsigned long flag, struct inode *inode);
bool ovl_test_flag(unsigned long flag, struct inode *inode);
bool ovl_inuse_trylock(struct dentry *dentry);
void ovl_inuse_unlock(struct dentry *dentry);
+bool ovl_need_index(struct dentry *dentry);
int ovl_nlink_start(struct dentry *dentry, bool *locked);
void ovl_nlink_end(struct dentry *dentry, bool locked);
int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);
@@ -249,15 +264,35 @@ static inline bool ovl_is_impuredir(struct dentry *dentry)
/* namei.c */
-int ovl_verify_origin(struct dentry *dentry, struct dentry *origin,
- bool is_upper, bool set);
-int ovl_verify_index(struct dentry *index, struct ovl_path *lower,
- unsigned int numlower);
+int ovl_check_fh_len(struct ovl_fh *fh, int fh_len);
+struct dentry *ovl_decode_fh(struct ovl_fh *fh, struct vfsmount *mnt);
+int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh,
+ struct dentry *upperdentry, struct ovl_path **stackp);
+int ovl_verify_set_fh(struct dentry *dentry, const char *name,
+ struct dentry *real, bool is_upper, bool set);
+struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index);
+int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index);
int ovl_get_index_name(struct dentry *origin, struct qstr *name);
+struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh);
+struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
+ struct dentry *origin, bool verify);
int ovl_path_next(int idx, struct dentry *dentry, struct path *path);
-struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags);
+struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
+ unsigned int flags);
bool ovl_lower_positive(struct dentry *dentry);
+static inline int ovl_verify_origin(struct dentry *upper,
+ struct dentry *origin, bool set)
+{
+ return ovl_verify_set_fh(upper, OVL_XATTR_ORIGIN, origin, false, set);
+}
+
+static inline int ovl_verify_upper(struct dentry *index,
+ struct dentry *upper, bool set)
+{
+ return ovl_verify_set_fh(index, OVL_XATTR_UPPER, upper, true, set);
+}
+
/* readdir.c */
extern const struct file_operations ovl_dir_operations;
int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list);
@@ -267,8 +302,7 @@ void ovl_dir_cache_free(struct inode *inode);
int ovl_check_d_type_supported(struct path *realpath);
void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
struct dentry *dentry, int level);
-int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt,
- struct ovl_path *lower, unsigned int numlower);
+int ovl_indexdir_cleanup(struct ovl_fs *ofs);
/* inode.c */
int ovl_set_nlink_upper(struct dentry *dentry);
@@ -291,8 +325,11 @@ int ovl_update_time(struct inode *inode, struct timespec *ts, int flags);
bool ovl_is_private_xattr(const char *name);
struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev);
-struct inode *ovl_get_inode(struct dentry *dentry, struct dentry *upperdentry,
- struct dentry *index);
+struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real,
+ bool is_upper);
+struct inode *ovl_get_inode(struct super_block *sb, struct dentry *upperdentry,
+ struct dentry *lowerdentry, struct dentry *index,
+ unsigned int numlower);
static inline void ovl_copyattr(struct inode *from, struct inode *to)
{
to->i_uid = from->i_uid;
@@ -306,6 +343,8 @@ static inline void ovl_copyattr(struct inode *from, struct inode *to)
/* dir.c */
extern const struct inode_operations ovl_dir_inode_operations;
struct dentry *ovl_lookup_temp(struct dentry *workdir);
+int ovl_cleanup_and_whiteout(struct dentry *workdir, struct inode *dir,
+ struct dentry *dentry);
struct cattr {
dev_t rdev;
umode_t mode;
@@ -321,4 +360,9 @@ int ovl_copy_up(struct dentry *dentry);
int ovl_copy_up_flags(struct dentry *dentry, int flags);
int ovl_copy_xattr(struct dentry *old, struct dentry *new);
int ovl_set_attr(struct dentry *upper, struct kstat *stat);
-struct ovl_fh *ovl_encode_fh(struct dentry *lower, bool is_upper);
+struct ovl_fh *ovl_encode_fh(struct dentry *real, bool is_upper);
+int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
+ struct dentry *upper);
+
+/* export.c */
+extern const struct export_operations ovl_export_operations;
diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
index 9d0bc03bf6e4..bfef6edcc111 100644
--- a/fs/overlayfs/ovl_entry.h
+++ b/fs/overlayfs/ovl_entry.h
@@ -17,11 +17,14 @@ struct ovl_config {
bool redirect_follow;
const char *redirect_mode;
bool index;
+ bool nfs_export;
};
struct ovl_layer {
struct vfsmount *mnt;
dev_t pseudo_dev;
+ /* Index of this layer in fs root (upper == 0) */
+ int idx;
};
struct ovl_path {
@@ -58,8 +61,7 @@ struct ovl_fs {
struct ovl_entry {
union {
struct {
- unsigned long has_upper;
- bool opaque;
+ unsigned long flags;
};
struct rcu_head rcu;
};
@@ -69,6 +71,11 @@ struct ovl_entry {
struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
+static inline struct ovl_entry *OVL_E(struct dentry *dentry)
+{
+ return (struct ovl_entry *) dentry->d_fsdata;
+}
+
struct ovl_inode {
struct ovl_dir_cache *cache;
const char *redirect;
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index 8c98578d27a1..c11f5c0906c3 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -593,8 +593,15 @@ static struct ovl_dir_cache *ovl_cache_get_impure(struct path *path)
return ERR_PTR(res);
}
if (list_empty(&cache->entries)) {
- /* Good oportunity to get rid of an unnecessary "impure" flag */
- ovl_do_removexattr(ovl_dentry_upper(dentry), OVL_XATTR_IMPURE);
+ /*
+ * A good opportunity to get rid of an unneeded "impure" flag.
+ * Removing the "impure" xattr is best effort.
+ */
+ if (!ovl_want_write(dentry)) {
+ ovl_do_removexattr(ovl_dentry_upper(dentry),
+ OVL_XATTR_IMPURE);
+ ovl_drop_write(dentry);
+ }
ovl_clear_flag(OVL_IMPURE, d_inode(dentry));
kfree(cache);
return NULL;
@@ -769,10 +776,14 @@ static int ovl_dir_fsync(struct file *file, loff_t start, loff_t end,
struct dentry *dentry = file->f_path.dentry;
struct file *realfile = od->realfile;
+ /* Nothing to sync for lower */
+ if (!OVL_TYPE_UPPER(ovl_path_type(dentry)))
+ return 0;
+
/*
* Need to check if we started out being a lower dir, but got copied up
*/
- if (!od->is_upper && OVL_TYPE_UPPER(ovl_path_type(dentry))) {
+ if (!od->is_upper) {
struct inode *inode = file_inode(file);
realfile = READ_ONCE(od->upperfile);
@@ -858,8 +869,11 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list)
int err;
struct ovl_cache_entry *p, *n;
struct rb_root root = RB_ROOT;
+ const struct cred *old_cred;
+ old_cred = ovl_override_creds(dentry->d_sb);
err = ovl_dir_read_merged(dentry, list, &root);
+ revert_creds(old_cred);
if (err)
return err;
@@ -1016,13 +1030,13 @@ void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt,
}
}
-int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt,
- struct ovl_path *lower, unsigned int numlower)
+int ovl_indexdir_cleanup(struct ovl_fs *ofs)
{
int err;
+ struct dentry *indexdir = ofs->indexdir;
struct dentry *index = NULL;
- struct inode *dir = dentry->d_inode;
- struct path path = { .mnt = mnt, .dentry = dentry };
+ struct inode *dir = indexdir->d_inode;
+ struct path path = { .mnt = ofs->upper_mnt, .dentry = indexdir };
LIST_HEAD(list);
struct rb_root root = RB_ROOT;
struct ovl_cache_entry *p;
@@ -1046,19 +1060,40 @@ int ovl_indexdir_cleanup(struct dentry *dentry, struct vfsmount *mnt,
if (p->len == 2 && p->name[1] == '.')
continue;
}
- index = lookup_one_len(p->name, dentry, p->len);
+ index = lookup_one_len(p->name, indexdir, p->len);
if (IS_ERR(index)) {
err = PTR_ERR(index);
index = NULL;
break;
}
- err = ovl_verify_index(index, lower, numlower);
- /* Cleanup stale and orphan index entries */
- if (err && (err == -ESTALE || err == -ENOENT))
+ err = ovl_verify_index(ofs, index);
+ if (!err) {
+ goto next;
+ } else if (err == -ESTALE) {
+ /* Cleanup stale index entries */
+ err = ovl_cleanup(dir, index);
+ } else if (err != -ENOENT) {
+ /*
+ * Abort mount to avoid corrupting the index if
+ * an incompatible index entry was found or on out
+ * of memory.
+ */
+ break;
+ } else if (ofs->config.nfs_export) {
+ /*
+ * Whiteout orphan index to block future open by
+ * handle after overlay nlink dropped to zero.
+ */
+ err = ovl_cleanup_and_whiteout(indexdir, dir, index);
+ } else {
+ /* Cleanup orphan index entries */
err = ovl_cleanup(dir, index);
+ }
+
if (err)
break;
+next:
dput(index);
index = NULL;
}
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 76440feb79f6..9ee37c76091d 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -45,6 +45,11 @@ module_param_named(index, ovl_index_def, bool, 0644);
MODULE_PARM_DESC(ovl_index_def,
"Default to on or off for the inodes index feature");
+static bool ovl_nfs_export_def = IS_ENABLED(CONFIG_OVERLAY_FS_NFS_EXPORT);
+module_param_named(nfs_export, ovl_nfs_export_def, bool, 0644);
+MODULE_PARM_DESC(ovl_nfs_export_def,
+ "Default to on or off for the NFS export feature");
+
static void ovl_entry_stack_free(struct ovl_entry *oe)
{
unsigned int i;
@@ -211,6 +216,7 @@ static void ovl_destroy_inode(struct inode *inode)
struct ovl_inode *oi = OVL_I(inode);
dput(oi->__upperdentry);
+ iput(oi->lower);
kfree(oi->redirect);
ovl_dir_cache_free(inode);
mutex_destroy(&oi->lock);
@@ -341,6 +347,9 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
seq_printf(m, ",redirect_dir=%s", ofs->config.redirect_mode);
if (ofs->config.index != ovl_index_def)
seq_printf(m, ",index=%s", ofs->config.index ? "on" : "off");
+ if (ofs->config.nfs_export != ovl_nfs_export_def)
+ seq_printf(m, ",nfs_export=%s", ofs->config.nfs_export ?
+ "on" : "off");
return 0;
}
@@ -373,6 +382,8 @@ enum {
OPT_REDIRECT_DIR,
OPT_INDEX_ON,
OPT_INDEX_OFF,
+ OPT_NFS_EXPORT_ON,
+ OPT_NFS_EXPORT_OFF,
OPT_ERR,
};
@@ -384,6 +395,8 @@ static const match_table_t ovl_tokens = {
{OPT_REDIRECT_DIR, "redirect_dir=%s"},
{OPT_INDEX_ON, "index=on"},
{OPT_INDEX_OFF, "index=off"},
+ {OPT_NFS_EXPORT_ON, "nfs_export=on"},
+ {OPT_NFS_EXPORT_OFF, "nfs_export=off"},
{OPT_ERR, NULL}
};
@@ -490,6 +503,14 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
config->index = false;
break;
+ case OPT_NFS_EXPORT_ON:
+ config->nfs_export = true;
+ break;
+
+ case OPT_NFS_EXPORT_OFF:
+ config->nfs_export = false;
+ break;
+
default:
pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p);
return -EINVAL;
@@ -520,10 +541,6 @@ static struct dentry *ovl_workdir_create(struct ovl_fs *ofs,
bool retried = false;
bool locked = false;
- err = mnt_want_write(mnt);
- if (err)
- goto out_err;
-
inode_lock_nested(dir, I_MUTEX_PARENT);
locked = true;
@@ -588,7 +605,6 @@ retry:
goto out_err;
}
out_unlock:
- mnt_drop_write(mnt);
if (locked)
inode_unlock(dir);
@@ -700,12 +716,16 @@ static int ovl_lower_dir(const char *name, struct path *path,
*remote = true;
/*
- * The inodes index feature needs to encode and decode file
- * handles, so it requires that all layers support them.
+ * The inodes index feature and NFS export need to encode and decode
+ * file handles, so they require that all layers support them.
*/
- if (ofs->config.index && !ovl_can_decode_fh(path->dentry->d_sb)) {
+ if ((ofs->config.nfs_export ||
+ (ofs->config.index && ofs->config.upperdir)) &&
+ !ovl_can_decode_fh(path->dentry->d_sb)) {
ofs->config.index = false;
- pr_warn("overlayfs: fs on '%s' does not support file handles, falling back to index=off.\n", name);
+ ofs->config.nfs_export = false;
+ pr_warn("overlayfs: fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n",
+ name);
}
return 0;
@@ -929,12 +949,17 @@ out:
static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
{
+ struct vfsmount *mnt = ofs->upper_mnt;
struct dentry *temp;
int err;
+ err = mnt_want_write(mnt);
+ if (err)
+ return err;
+
ofs->workdir = ovl_workdir_create(ofs, OVL_WORKDIR_NAME, false);
if (!ofs->workdir)
- return 0;
+ goto out;
/*
* Upper should support d_type, else whiteouts are visible. Given
@@ -944,7 +969,7 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
*/
err = ovl_check_d_type_supported(workpath);
if (err < 0)
- return err;
+ goto out;
/*
* We allowed this configuration and don't want to break users over
@@ -967,7 +992,9 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
err = ovl_do_setxattr(ofs->workdir, OVL_XATTR_OPAQUE, "0", 1, 0);
if (err) {
ofs->noxattr = true;
- pr_warn("overlayfs: upper fs does not support xattr.\n");
+ ofs->config.index = false;
+ pr_warn("overlayfs: upper fs does not support xattr, falling back to index=off.\n");
+ err = 0;
} else {
vfs_removexattr(ofs->workdir, OVL_XATTR_OPAQUE);
}
@@ -979,7 +1006,15 @@ static int ovl_make_workdir(struct ovl_fs *ofs, struct path *workpath)
pr_warn("overlayfs: upper fs does not support file handles, falling back to index=off.\n");
}
- return 0;
+ /* NFS export of r/w mount depends on index */
+ if (ofs->config.nfs_export && !ofs->config.index) {
+ pr_warn("overlayfs: NFS export requires \"index=on\", falling back to nfs_export=off.\n");
+ ofs->config.nfs_export = false;
+ }
+
+out:
+ mnt_drop_write(mnt);
+ return err;
}
static int ovl_get_workdir(struct ovl_fs *ofs, struct path *upperpath)
@@ -1026,11 +1061,16 @@ out:
static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe,
struct path *upperpath)
{
+ struct vfsmount *mnt = ofs->upper_mnt;
int err;
+ err = mnt_want_write(mnt);
+ if (err)
+ return err;
+
/* Verify lower root is upper root origin */
err = ovl_verify_origin(upperpath->dentry, oe->lowerstack[0].dentry,
- false, true);
+ true);
if (err) {
pr_err("overlayfs: failed to verify upper root origin\n");
goto out;
@@ -1038,23 +1078,33 @@ static int ovl_get_indexdir(struct ovl_fs *ofs, struct ovl_entry *oe,
ofs->indexdir = ovl_workdir_create(ofs, OVL_INDEXDIR_NAME, true);
if (ofs->indexdir) {
- /* Verify upper root is index dir origin */
- err = ovl_verify_origin(ofs->indexdir, upperpath->dentry,
- true, true);
+ /*
+ * Verify upper root is exclusively associated with index dir.
+ * Older kernels stored upper fh in "trusted.overlay.origin"
+ * xattr. If that xattr exists, verify that it is a match to
+ * upper dir file handle. In any case, verify or set xattr
+ * "trusted.overlay.upper" to indicate that index may have
+ * directory entries.
+ */
+ if (ovl_check_origin_xattr(ofs->indexdir)) {
+ err = ovl_verify_set_fh(ofs->indexdir, OVL_XATTR_ORIGIN,
+ upperpath->dentry, true, false);
+ if (err)
+ pr_err("overlayfs: failed to verify index dir 'origin' xattr\n");
+ }
+ err = ovl_verify_upper(ofs->indexdir, upperpath->dentry, true);
if (err)
- pr_err("overlayfs: failed to verify index dir origin\n");
+ pr_err("overlayfs: failed to verify index dir 'upper' xattr\n");
/* Cleanup bad/stale/orphan index entries */
if (!err)
- err = ovl_indexdir_cleanup(ofs->indexdir,
- ofs->upper_mnt,
- oe->lowerstack,
- oe->numlower);
+ err = ovl_indexdir_cleanup(ofs);
}
if (err || !ofs->indexdir)
pr_warn("overlayfs: try deleting index dir or mounting with '-o index=off' to disable inodes index.\n");
out:
+ mnt_drop_write(mnt);
return err;
}
@@ -1094,6 +1144,7 @@ static int ovl_get_lower_layers(struct ovl_fs *ofs, struct path *stack,
ofs->lower_layers[ofs->numlower].mnt = mnt;
ofs->lower_layers[ofs->numlower].pseudo_dev = dev;
+ ofs->lower_layers[ofs->numlower].idx = i + 1;
ofs->numlower++;
/* Check if all lower layers are on same sb */
@@ -1131,6 +1182,10 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
} else if (!ofs->config.upperdir && stacklen == 1) {
pr_err("overlayfs: at least 2 lowerdir are needed while upperdir nonexistent\n");
goto out_err;
+ } else if (!ofs->config.upperdir && ofs->config.nfs_export &&
+ ofs->config.redirect_follow) {
+ pr_warn("overlayfs: NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
+ ofs->config.nfs_export = false;
}
err = -ENOMEM;
@@ -1207,6 +1262,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
goto out_err;
ofs->config.index = ovl_index_def;
+ ofs->config.nfs_export = ovl_nfs_export_def;
err = ovl_parse_opt((char *) data, &ofs->config);
if (err)
goto out_err;
@@ -1257,13 +1313,26 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
if (err)
goto out_free_oe;
- if (!ofs->indexdir)
+ /* Force r/o mount with no index dir */
+ if (!ofs->indexdir) {
+ dput(ofs->workdir);
+ ofs->workdir = NULL;
sb->s_flags |= SB_RDONLY;
+ }
+
}
- /* Show index=off/on in /proc/mounts for any of the reasons above */
- if (!ofs->indexdir)
+ /* Show index=off in /proc/mounts for forced r/o mount */
+ if (!ofs->indexdir) {
ofs->config.index = false;
+ if (ofs->upper_mnt && ofs->config.nfs_export) {
+ pr_warn("overlayfs: NFS export requires an index dir, falling back to nfs_export=off.\n");
+ ofs->config.nfs_export = false;
+ }
+ }
+
+ if (ofs->config.nfs_export)
+ sb->s_export_op = &ovl_export_operations;
/* Never override disk quota limits or use reserved space */
cap_lower(cred->cap_effective, CAP_SYS_RESOURCE);
@@ -1279,15 +1348,15 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
if (!root_dentry)
goto out_free_oe;
+ root_dentry->d_fsdata = oe;
+
mntput(upperpath.mnt);
if (upperpath.dentry) {
- oe->has_upper = true;
+ ovl_dentry_set_upper_alias(root_dentry);
if (ovl_is_impuredir(upperpath.dentry))
ovl_set_flag(OVL_IMPURE, d_inode(root_dentry));
}
- root_dentry->d_fsdata = oe;
-
/* Root is always merge -> can have whiteouts */
ovl_set_flag(OVL_WHITEOUTS, d_inode(root_dentry));
ovl_inode_init(d_inode(root_dentry), upperpath.dentry,
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index d6bb1c9f5e7a..930784a26623 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -63,6 +63,22 @@ struct dentry *ovl_indexdir(struct super_block *sb)
return ofs->indexdir;
}
+/* Index all files on copy up. For now only enabled for NFS export */
+bool ovl_index_all(struct super_block *sb)
+{
+ struct ovl_fs *ofs = sb->s_fs_info;
+
+ return ofs->config.nfs_export && ofs->config.index;
+}
+
+/* Verify lower origin on lookup. For now only enabled for NFS export */
+bool ovl_verify_lower(struct super_block *sb)
+{
+ struct ovl_fs *ofs = sb->s_fs_info;
+
+ return ofs->config.nfs_export && ofs->config.index;
+}
+
struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
{
size_t size = offsetof(struct ovl_entry, lowerstack[numlower]);
@@ -194,10 +210,24 @@ void ovl_set_dir_cache(struct inode *inode, struct ovl_dir_cache *cache)
OVL_I(inode)->cache = cache;
}
+void ovl_dentry_set_flag(unsigned long flag, struct dentry *dentry)
+{
+ set_bit(flag, &OVL_E(dentry)->flags);
+}
+
+void ovl_dentry_clear_flag(unsigned long flag, struct dentry *dentry)
+{
+ clear_bit(flag, &OVL_E(dentry)->flags);
+}
+
+bool ovl_dentry_test_flag(unsigned long flag, struct dentry *dentry)
+{
+ return test_bit(flag, &OVL_E(dentry)->flags);
+}
+
bool ovl_dentry_is_opaque(struct dentry *dentry)
{
- struct ovl_entry *oe = dentry->d_fsdata;
- return oe->opaque;
+ return ovl_dentry_test_flag(OVL_E_OPAQUE, dentry);
}
bool ovl_dentry_is_whiteout(struct dentry *dentry)
@@ -207,28 +237,23 @@ bool ovl_dentry_is_whiteout(struct dentry *dentry)
void ovl_dentry_set_opaque(struct dentry *dentry)
{
- struct ovl_entry *oe = dentry->d_fsdata;
-
- oe->opaque = true;
+ ovl_dentry_set_flag(OVL_E_OPAQUE, dentry);
}
/*
- * For hard links it's possible for ovl_dentry_upper() to return positive, while
- * there's no actual upper alias for the inode. Copy up code needs to know
- * about the existence of the upper alias, so it can't use ovl_dentry_upper().
+ * For hard links and decoded file handles, it's possible for ovl_dentry_upper()
+ * to return positive, while there's no actual upper alias for the inode.
+ * Copy up code needs to know about the existence of the upper alias, so it
+ * can't use ovl_dentry_upper().
*/
bool ovl_dentry_has_upper_alias(struct dentry *dentry)
{
- struct ovl_entry *oe = dentry->d_fsdata;
-
- return oe->has_upper;
+ return ovl_dentry_test_flag(OVL_E_UPPER_ALIAS, dentry);
}
void ovl_dentry_set_upper_alias(struct dentry *dentry)
{
- struct ovl_entry *oe = dentry->d_fsdata;
-
- oe->has_upper = true;
+ ovl_dentry_set_flag(OVL_E_UPPER_ALIAS, dentry);
}
bool ovl_redirect_dir(struct super_block *sb)
@@ -257,7 +282,7 @@ void ovl_inode_init(struct inode *inode, struct dentry *upperdentry,
if (upperdentry)
OVL_I(inode)->__upperdentry = upperdentry;
if (lowerdentry)
- OVL_I(inode)->lower = d_inode(lowerdentry);
+ OVL_I(inode)->lower = igrab(d_inode(lowerdentry));
ovl_copyattr(d_inode(upperdentry ?: lowerdentry), inode);
}
@@ -273,7 +298,7 @@ void ovl_inode_update(struct inode *inode, struct dentry *upperdentry)
*/
smp_wmb();
OVL_I(inode)->__upperdentry = upperdentry;
- if (!S_ISDIR(upperinode->i_mode) && inode_unhashed(inode)) {
+ if (inode_unhashed(inode)) {
inode->i_private = upperinode;
__insert_inode_hash(inode, (unsigned long) upperinode);
}
@@ -447,10 +472,32 @@ void ovl_inuse_unlock(struct dentry *dentry)
}
}
+/*
+ * Does this overlay dentry need to be indexed on copy up?
+ */
+bool ovl_need_index(struct dentry *dentry)
+{
+ struct dentry *lower = ovl_dentry_lower(dentry);
+
+ if (!lower || !ovl_indexdir(dentry->d_sb))
+ return false;
+
+ /* Index all files for NFS export and consistency verification */
+ if (ovl_index_all(dentry->d_sb))
+ return true;
+
+ /* Index only lower hardlinks on copy up */
+ if (!d_is_dir(lower) && d_inode(lower)->i_nlink > 1)
+ return true;
+
+ return false;
+}
+
/* Caller must hold OVL_I(inode)->lock */
static void ovl_cleanup_index(struct dentry *dentry)
{
- struct inode *dir = ovl_indexdir(dentry->d_sb)->d_inode;
+ struct dentry *indexdir = ovl_indexdir(dentry->d_sb);
+ struct inode *dir = indexdir->d_inode;
struct dentry *lowerdentry = ovl_dentry_lower(dentry);
struct dentry *upperdentry = ovl_dentry_upper(dentry);
struct dentry *index = NULL;
@@ -463,7 +510,7 @@ static void ovl_cleanup_index(struct dentry *dentry)
goto fail;
inode = d_inode(upperdentry);
- if (inode->i_nlink != 1) {
+ if (!S_ISDIR(inode->i_mode) && inode->i_nlink != 1) {
pr_warn_ratelimited("overlayfs: cleanup linked index (%pd2, ino=%lu, nlink=%u)\n",
upperdentry, inode->i_ino, inode->i_nlink);
/*
@@ -481,13 +528,17 @@ static void ovl_cleanup_index(struct dentry *dentry)
}
inode_lock_nested(dir, I_MUTEX_PARENT);
- /* TODO: whiteout instead of cleanup to block future open by handle */
- index = lookup_one_len(name.name, ovl_indexdir(dentry->d_sb), name.len);
+ index = lookup_one_len(name.name, indexdir, name.len);
err = PTR_ERR(index);
- if (!IS_ERR(index))
- err = ovl_cleanup(dir, index);
- else
+ if (IS_ERR(index)) {
index = NULL;
+ } else if (ovl_index_all(dentry->d_sb)) {
+ /* Whiteout orphan index to block future open by handle */
+ err = ovl_cleanup_and_whiteout(indexdir, dir, index);
+ } else {
+ /* Cleanup orphan index entries */
+ err = ovl_cleanup(dir, index);
+ }
inode_unlock(dir);
if (err)
@@ -512,16 +563,16 @@ int ovl_nlink_start(struct dentry *dentry, bool *locked)
const struct cred *old_cred;
int err;
- if (!d_inode(dentry) || d_is_dir(dentry))
+ if (!d_inode(dentry))
return 0;
/*
* With inodes index is enabled, we store the union overlay nlink
- * in an xattr on the index inode. When whiting out lower hardlinks
+ * in an xattr on the index inode. When whiting out an indexed lower,
* we need to decrement the overlay persistent nlink, but before the
* first copy up, we have no upper index inode to store the xattr.
*
- * As a workaround, before whiteout/rename over of a lower hardlink,
+ * As a workaround, before whiteout/rename over an indexed lower,
* copy up to create the upper index. Creating the upper index will
* initialize the overlay nlink, so it could be dropped if unlink
* or rename succeeds.
@@ -529,8 +580,7 @@ int ovl_nlink_start(struct dentry *dentry, bool *locked)
* TODO: implement metadata only index copy up when called with
* ovl_copy_up_flags(dentry, O_PATH).
*/
- if (ovl_indexdir(dentry->d_sb) && !ovl_dentry_has_upper_alias(dentry) &&
- d_inode(ovl_dentry_lower(dentry))->i_nlink > 1) {
+ if (ovl_need_index(dentry) && !ovl_dentry_has_upper_alias(dentry)) {
err = ovl_copy_up(dentry);
if (err)
return err;
@@ -540,7 +590,7 @@ int ovl_nlink_start(struct dentry *dentry, bool *locked)
if (err)
return err;
- if (!ovl_test_flag(OVL_INDEX, d_inode(dentry)))
+ if (d_is_dir(dentry) || !ovl_test_flag(OVL_INDEX, d_inode(dentry)))
goto out;
old_cred = ovl_override_creds(dentry->d_sb);
diff --git a/fs/pipe.c b/fs/pipe.c
index a449ca0ec0c6..0913aed7fd0d 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -35,11 +35,6 @@
*/
unsigned int pipe_max_size = 1048576;
-/*
- * Minimum pipe size, as required by POSIX
- */
-unsigned int pipe_min_size = PAGE_SIZE;
-
/* Maximum allocatable pages per user. Hard limit is unset by default, soft
* matches default values.
*/
@@ -610,12 +605,21 @@ static unsigned long account_pipe_buffers(struct user_struct *user,
static bool too_many_pipe_buffers_soft(unsigned long user_bufs)
{
- return pipe_user_pages_soft && user_bufs >= pipe_user_pages_soft;
+ unsigned long soft_limit = READ_ONCE(pipe_user_pages_soft);
+
+ return soft_limit && user_bufs > soft_limit;
}
static bool too_many_pipe_buffers_hard(unsigned long user_bufs)
{
- return pipe_user_pages_hard && user_bufs >= pipe_user_pages_hard;
+ unsigned long hard_limit = READ_ONCE(pipe_user_pages_hard);
+
+ return hard_limit && user_bufs > hard_limit;
+}
+
+static bool is_unprivileged_user(void)
+{
+ return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
}
struct pipe_inode_info *alloc_pipe_info(void)
@@ -624,22 +628,23 @@ struct pipe_inode_info *alloc_pipe_info(void)
unsigned long pipe_bufs = PIPE_DEF_BUFFERS;
struct user_struct *user = get_current_user();
unsigned long user_bufs;
+ unsigned int max_size = READ_ONCE(pipe_max_size);
pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT);
if (pipe == NULL)
goto out_free_uid;
- if (pipe_bufs * PAGE_SIZE > pipe_max_size && !capable(CAP_SYS_RESOURCE))
- pipe_bufs = pipe_max_size >> PAGE_SHIFT;
+ if (pipe_bufs * PAGE_SIZE > max_size && !capable(CAP_SYS_RESOURCE))
+ pipe_bufs = max_size >> PAGE_SHIFT;
user_bufs = account_pipe_buffers(user, 0, pipe_bufs);
- if (too_many_pipe_buffers_soft(user_bufs)) {
+ if (too_many_pipe_buffers_soft(user_bufs) && is_unprivileged_user()) {
user_bufs = account_pipe_buffers(user, pipe_bufs, 1);
pipe_bufs = 1;
}
- if (too_many_pipe_buffers_hard(user_bufs))
+ if (too_many_pipe_buffers_hard(user_bufs) && is_unprivileged_user())
goto out_revert_acct;
pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer),
@@ -1020,18 +1025,16 @@ const struct file_operations pipefifo_fops = {
* Currently we rely on the pipe array holding a power-of-2 number
* of pages. Returns 0 on error.
*/
-unsigned int round_pipe_size(unsigned int size)
+unsigned int round_pipe_size(unsigned long size)
{
- unsigned long nr_pages;
-
- if (size < pipe_min_size)
- size = pipe_min_size;
-
- nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
- if (nr_pages == 0)
+ if (size > (1U << 31))
return 0;
- return roundup_pow_of_two(nr_pages) << PAGE_SHIFT;
+ /* Minimum pipe size, as required by POSIX */
+ if (size < PAGE_SIZE)
+ return PAGE_SIZE;
+
+ return roundup_pow_of_two(size);
}
/*
@@ -1046,8 +1049,6 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
long ret = 0;
size = round_pipe_size(arg);
- if (size == 0)
- return -EINVAL;
nr_pages = size >> PAGE_SHIFT;
if (!nr_pages)
@@ -1069,7 +1070,7 @@ static long pipe_set_size(struct pipe_inode_info *pipe, unsigned long arg)
if (nr_pages > pipe->buffers &&
(too_many_pipe_buffers_hard(user_bufs) ||
too_many_pipe_buffers_soft(user_bufs)) &&
- !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
+ is_unprivileged_user()) {
ret = -EPERM;
goto out_revert_acct;
}
@@ -1125,16 +1126,6 @@ out_revert_acct:
}
/*
- * This should work even if CONFIG_PROC_FS isn't set, as proc_dopipe_max_size
- * will return an error.
- */
-int pipe_proc_fn(struct ctl_table *table, int write, void __user *buf,
- size_t *lenp, loff_t *ppos)
-{
- return proc_dopipe_max_size(table, write, buf, lenp, ppos);
-}
-
-/*
* After the inode slimming patch, i_pipe/i_bdev/i_cdev share the same
* location, so checking ->i_pipe is not enough to verify that this is a
* pipe.
diff --git a/fs/proc/array.c b/fs/proc/array.c
index d67a72dcb92c..598803576e4c 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -736,16 +736,10 @@ static int children_seq_open(struct inode *inode, struct file *file)
return ret;
}
-int children_seq_release(struct inode *inode, struct file *file)
-{
- seq_release(inode, file);
- return 0;
-}
-
const struct file_operations proc_tid_children_operations = {
.open = children_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = children_seq_release,
+ .release = seq_release,
};
#endif /* CONFIG_PROC_CHILDREN */
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 60316b52d659..9298324325ed 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -75,6 +75,7 @@
#include <linux/ptrace.h>
#include <linux/tracehook.h>
#include <linux/printk.h>
+#include <linux/cache.h>
#include <linux/cgroup.h>
#include <linux/cpuset.h>
#include <linux/audit.h>
@@ -100,6 +101,8 @@
#include "internal.h"
#include "fd.h"
+#include "../../lib/kstrtox.h"
+
/* NOTE:
* Implementing inode permission operations in /proc is almost
* certainly an error. Permission checks need to happen during
@@ -110,8 +113,8 @@
* in /proc for a task before it execs a suid executable.
*/
-static u8 nlink_tid;
-static u8 nlink_tgid;
+static u8 nlink_tid __ro_after_init;
+static u8 nlink_tgid __ro_after_init;
struct pid_entry {
const char *name;
@@ -1370,7 +1373,7 @@ static ssize_t proc_fail_nth_write(struct file *file, const char __user *buf,
task = get_proc_task(file_inode(file));
if (!task)
return -ESRCH;
- WRITE_ONCE(task->fail_nth, n);
+ task->fail_nth = n;
put_task_struct(task);
return count;
@@ -1386,8 +1389,7 @@ static ssize_t proc_fail_nth_read(struct file *file, char __user *buf,
task = get_proc_task(file_inode(file));
if (!task)
return -ESRCH;
- len = snprintf(numbuf, sizeof(numbuf), "%u\n",
- READ_ONCE(task->fail_nth));
+ len = snprintf(numbuf, sizeof(numbuf), "%u\n", task->fail_nth);
len = simple_read_from_buffer(buf, count, ppos, numbuf, len);
put_task_struct(task);
@@ -1907,8 +1909,33 @@ end_instantiate:
static int dname_to_vma_addr(struct dentry *dentry,
unsigned long *start, unsigned long *end)
{
- if (sscanf(dentry->d_name.name, "%lx-%lx", start, end) != 2)
+ const char *str = dentry->d_name.name;
+ unsigned long long sval, eval;
+ unsigned int len;
+
+ len = _parse_integer(str, 16, &sval);
+ if (len & KSTRTOX_OVERFLOW)
+ return -EINVAL;
+ if (sval != (unsigned long)sval)
return -EINVAL;
+ str += len;
+
+ if (*str != '-')
+ return -EINVAL;
+ str++;
+
+ len = _parse_integer(str, 16, &eval);
+ if (len & KSTRTOX_OVERFLOW)
+ return -EINVAL;
+ if (eval != (unsigned long)eval)
+ return -EINVAL;
+ str += len;
+
+ if (*str != '\0')
+ return -EINVAL;
+
+ *start = sval;
+ *end = eval;
return 0;
}
@@ -2000,9 +2027,9 @@ out:
}
struct map_files_info {
+ unsigned long start;
+ unsigned long end;
fmode_t mode;
- unsigned int len;
- unsigned char name[4*sizeof(long)+2]; /* max: %lx-%lx\0 */
};
/*
@@ -2172,10 +2199,9 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
if (++pos <= ctx->pos)
continue;
+ info.start = vma->vm_start;
+ info.end = vma->vm_end;
info.mode = vma->vm_file->f_mode;
- info.len = snprintf(info.name,
- sizeof(info.name), "%lx-%lx",
- vma->vm_start, vma->vm_end);
if (flex_array_put(fa, i++, &info, GFP_KERNEL))
BUG();
}
@@ -2183,9 +2209,13 @@ proc_map_files_readdir(struct file *file, struct dir_context *ctx)
up_read(&mm->mmap_sem);
for (i = 0; i < nr_files; i++) {
+ char buf[4 * sizeof(long) + 2]; /* max: %lx-%lx\0 */
+ unsigned int len;
+
p = flex_array_get(fa, i);
+ len = snprintf(buf, sizeof(buf), "%lx-%lx", p->start, p->end);
if (!proc_fill_cache(file, ctx,
- p->name, p->len,
+ buf, len,
proc_map_files_instantiate,
task,
(void *)(unsigned long)p->mode))
@@ -3018,11 +3048,11 @@ static const struct inode_operations proc_tgid_base_inode_operations = {
static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
{
struct dentry *dentry, *leader, *dir;
- char buf[PROC_NUMBUF];
+ char buf[10 + 1];
struct qstr name;
name.name = buf;
- name.len = snprintf(buf, sizeof(buf), "%d", pid);
+ name.len = snprintf(buf, sizeof(buf), "%u", pid);
/* no ->d_hash() rejects on procfs */
dentry = d_hash_and_lookup(mnt->mnt_root, &name);
if (dentry) {
@@ -3034,7 +3064,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
return;
name.name = buf;
- name.len = snprintf(buf, sizeof(buf), "%d", tgid);
+ name.len = snprintf(buf, sizeof(buf), "%u", tgid);
leader = d_hash_and_lookup(mnt->mnt_root, &name);
if (!leader)
goto out;
@@ -3046,7 +3076,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
goto out_put_leader;
name.name = buf;
- name.len = snprintf(buf, sizeof(buf), "%d", pid);
+ name.len = snprintf(buf, sizeof(buf), "%u", pid);
dentry = d_hash_and_lookup(dir, &name);
if (dentry) {
d_invalidate(dentry);
@@ -3225,14 +3255,14 @@ int proc_pid_readdir(struct file *file, struct dir_context *ctx)
for (iter = next_tgid(ns, iter);
iter.task;
iter.tgid += 1, iter = next_tgid(ns, iter)) {
- char name[PROC_NUMBUF];
+ char name[10 + 1];
int len;
cond_resched();
if (!has_pid_permissions(ns, iter.task, HIDEPID_INVISIBLE))
continue;
- len = snprintf(name, sizeof(name), "%d", iter.tgid);
+ len = snprintf(name, sizeof(name), "%u", iter.tgid);
ctx->pos = iter.tgid + TGID_OFFSET;
if (!proc_fill_cache(file, ctx, name, len,
proc_pid_instantiate, iter.task, NULL)) {
@@ -3560,10 +3590,10 @@ static int proc_task_readdir(struct file *file, struct dir_context *ctx)
for (task = first_tid(proc_pid(inode), tid, ctx->pos - 2, ns);
task;
task = next_tid(task), ctx->pos++) {
- char name[PROC_NUMBUF];
+ char name[10 + 1];
int len;
tid = task_pid_nr_ns(task, ns);
- len = snprintf(name, sizeof(name), "%d", tid);
+ len = snprintf(name, sizeof(name), "%u", tid);
if (!proc_fill_cache(file, ctx, name, len,
proc_task_instantiate, task, NULL)) {
/* returning this tgid failed, save it as the first
diff --git a/fs/proc/consoles.c b/fs/proc/consoles.c
index 290ba85cb900..a8ac48aebd59 100644
--- a/fs/proc/consoles.c
+++ b/fs/proc/consoles.c
@@ -55,8 +55,7 @@ static int show_console_dev(struct seq_file *m, void *v)
if (dev)
seq_printf(m, " %4d:%d", MAJOR(dev), MINOR(dev));
- seq_printf(m, "\n");
-
+ seq_putc(m, '\n');
return 0;
}
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
index 96fc70225e54..6b80cd1e419a 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -236,7 +236,7 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx,
for (fd = ctx->pos - 2;
fd < files_fdtable(files)->max_fds;
fd++, ctx->pos++) {
- char name[PROC_NUMBUF];
+ char name[10 + 1];
int len;
if (!fcheck_files(files, fd))
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 793a67574668..5d709fa8f3a2 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -28,7 +28,7 @@
static DEFINE_RWLOCK(proc_subdir_lock);
-static int proc_match(unsigned int len, const char *name, struct proc_dir_entry *de)
+static int proc_match(const char *name, struct proc_dir_entry *de, unsigned int len)
{
if (len < de->namelen)
return -1;
@@ -60,7 +60,7 @@ static struct proc_dir_entry *pde_subdir_find(struct proc_dir_entry *dir,
struct proc_dir_entry *de = rb_entry(node,
struct proc_dir_entry,
subdir_node);
- int result = proc_match(len, name, de);
+ int result = proc_match(name, de, len);
if (result < 0)
node = node->rb_left;
@@ -84,7 +84,7 @@ static bool pde_subdir_insert(struct proc_dir_entry *dir,
struct proc_dir_entry *this = rb_entry(*new,
struct proc_dir_entry,
subdir_node);
- int result = proc_match(de->namelen, de->name, this);
+ int result = proc_match(de->name, this, de->namelen);
parent = *new;
if (result < 0)
@@ -211,8 +211,8 @@ void proc_free_inum(unsigned int inum)
* Don't create negative dentries here, return -ENOENT by hand
* instead.
*/
-struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
- struct dentry *dentry)
+struct dentry *proc_lookup_de(struct inode *dir, struct dentry *dentry,
+ struct proc_dir_entry *de)
{
struct inode *inode;
@@ -235,7 +235,7 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir,
struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
unsigned int flags)
{
- return proc_lookup_de(PDE(dir), dir, dentry);
+ return proc_lookup_de(dir, dentry, PDE(dir));
}
/*
@@ -247,8 +247,8 @@ struct dentry *proc_lookup(struct inode *dir, struct dentry *dentry,
* value of the readdir() call, as long as it's non-negative
* for success..
*/
-int proc_readdir_de(struct proc_dir_entry *de, struct file *file,
- struct dir_context *ctx)
+int proc_readdir_de(struct file *file, struct dir_context *ctx,
+ struct proc_dir_entry *de)
{
int i;
@@ -292,7 +292,7 @@ int proc_readdir(struct file *file, struct dir_context *ctx)
{
struct inode *inode = file_inode(file);
- return proc_readdir_de(PDE(inode), file, ctx);
+ return proc_readdir_de(file, ctx, PDE(inode));
}
/*
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 8dacaabb9f37..6e8724958116 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -5,6 +5,7 @@
* Copyright (C) 1991, 1992 Linus Torvalds
*/
+#include <linux/cache.h>
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/kernel.h>
@@ -52,7 +53,7 @@ static void proc_evict_inode(struct inode *inode)
}
}
-static struct kmem_cache * proc_inode_cachep;
+static struct kmem_cache *proc_inode_cachep __ro_after_init;
static struct inode *proc_alloc_inode(struct super_block *sb)
{
@@ -128,12 +129,12 @@ enum {BIAS = -1U<<31};
static inline int use_pde(struct proc_dir_entry *pde)
{
- return atomic_inc_unless_negative(&pde->in_use);
+ return likely(atomic_inc_unless_negative(&pde->in_use));
}
static void unuse_pde(struct proc_dir_entry *pde)
{
- if (atomic_dec_return(&pde->in_use) == BIAS)
+ if (unlikely(atomic_dec_return(&pde->in_use) == BIAS))
complete(pde->pde_unload_completion);
}
@@ -166,7 +167,7 @@ static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
spin_lock(&pde->pde_unload_lock);
/* After ->release. */
list_del(&pdeo->lh);
- if (pdeo->c)
+ if (unlikely(pdeo->c))
complete(pdeo->c);
kfree(pdeo);
}
@@ -420,7 +421,7 @@ static const char *proc_get_link(struct dentry *dentry,
struct delayed_call *done)
{
struct proc_dir_entry *pde = PDE(inode);
- if (unlikely(!use_pde(pde)))
+ if (!use_pde(pde))
return ERR_PTR(-EINVAL);
set_delayed_call(done, proc_put_link, pde);
return pde->data;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 4a67188c8d74..d697c8ab0a14 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -31,24 +31,28 @@ struct mempolicy;
* subdir_node is used to build the rb tree "subdir" of the parent.
*/
struct proc_dir_entry {
+ /*
+ * number of callers into module in progress;
+ * negative -> it's going away RSN
+ */
+ atomic_t in_use;
+ atomic_t count; /* use count */
+ struct list_head pde_openers; /* who did ->open, but not ->release */
+ /* protects ->pde_openers and all struct pde_opener instances */
+ spinlock_t pde_unload_lock;
+ struct completion *pde_unload_completion;
+ const struct inode_operations *proc_iops;
+ const struct file_operations *proc_fops;
+ void *data;
unsigned int low_ino;
- umode_t mode;
nlink_t nlink;
kuid_t uid;
kgid_t gid;
loff_t size;
- const struct inode_operations *proc_iops;
- const struct file_operations *proc_fops;
struct proc_dir_entry *parent;
struct rb_root_cached subdir;
struct rb_node subdir_node;
- void *data;
- atomic_t count; /* use count */
- atomic_t in_use; /* number of callers into module in progress; */
- /* negative -> it's going away RSN */
- struct completion *pde_unload_completion;
- struct list_head pde_openers; /* who did ->open, but not ->release */
- spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
+ umode_t mode;
u8 namelen;
char name[];
} __randomize_layout;
@@ -149,10 +153,9 @@ extern bool proc_fill_cache(struct file *, struct dir_context *, const char *, i
* generic.c
*/
extern struct dentry *proc_lookup(struct inode *, struct dentry *, unsigned int);
-extern struct dentry *proc_lookup_de(struct proc_dir_entry *, struct inode *,
- struct dentry *);
+struct dentry *proc_lookup_de(struct inode *, struct dentry *, struct proc_dir_entry *);
extern int proc_readdir(struct file *, struct dir_context *);
-extern int proc_readdir_de(struct proc_dir_entry *, struct file *, struct dir_context *);
+int proc_readdir_de(struct file *, struct dir_context *, struct proc_dir_entry *);
static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde)
{
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 4bc85cb8be6a..e8a93bc8285d 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -512,23 +512,15 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
return -EFAULT;
} else {
if (kern_addr_valid(start)) {
- unsigned long n;
-
/*
* Using bounce buffer to bypass the
* hardened user copy kernel text checks.
*/
- memcpy(buf, (char *) start, tsz);
- n = copy_to_user(buffer, buf, tsz);
- /*
- * We cannot distinguish between fault on source
- * and fault on destination. When this happens
- * we clear too and hope it will trigger the
- * EFAULT again.
- */
- if (n) {
- if (clear_user(buffer + tsz - n,
- n))
+ if (probe_kernel_read(buf, (void *) start, tsz)) {
+ if (clear_user(buffer, tsz))
+ return -EFAULT;
+ } else {
+ if (copy_to_user(buffer, buf, tsz))
return -EFAULT;
}
} else {
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index a2bf369c923d..68c06ae7888c 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -135,7 +135,7 @@ static struct dentry *proc_tgid_net_lookup(struct inode *dir,
de = ERR_PTR(-ENOENT);
net = get_proc_task_net(dir);
if (net != NULL) {
- de = proc_lookup_de(net->proc_net, dir, dentry);
+ de = proc_lookup_de(dir, dentry, net->proc_net);
put_net(net);
}
return de;
@@ -172,7 +172,7 @@ static int proc_tgid_net_readdir(struct file *file, struct dir_context *ctx)
ret = -EINVAL;
net = get_proc_task_net(file_inode(file));
if (net != NULL) {
- ret = proc_readdir_de(net->proc_net, file, ctx);
+ ret = proc_readdir_de(file, ctx, net->proc_net);
put_net(net);
}
return ret;
diff --git a/fs/proc/self.c b/fs/proc/self.c
index 31326bb23b8b..4d7d061696b3 100644
--- a/fs/proc/self.c
+++ b/fs/proc/self.c
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
+#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/pid_namespace.h>
@@ -17,11 +18,11 @@ static const char *proc_self_get_link(struct dentry *dentry,
if (!tgid)
return ERR_PTR(-ENOENT);
- /* 11 for max length of signed int in decimal + NULL term */
- name = kmalloc(12, dentry ? GFP_KERNEL : GFP_ATOMIC);
+ /* max length of unsigned int in decimal + NULL term */
+ name = kmalloc(10 + 1, dentry ? GFP_KERNEL : GFP_ATOMIC);
if (unlikely(!name))
return dentry ? ERR_PTR(-ENOMEM) : ERR_PTR(-ECHILD);
- sprintf(name, "%d", tgid);
+ sprintf(name, "%u", tgid);
set_delayed_call(done, kfree_link, name);
return name;
}
@@ -30,7 +31,7 @@ static const struct inode_operations proc_self_inode_operations = {
.get_link = proc_self_get_link,
};
-static unsigned self_inum;
+static unsigned self_inum __ro_after_init;
int proc_setup_self(struct super_block *s)
{
diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c
index b813e3b529f2..9d2efaca499f 100644
--- a/fs/proc/thread_self.c
+++ b/fs/proc/thread_self.c
@@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
+#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/pid_namespace.h>
@@ -18,11 +19,10 @@ static const char *proc_thread_self_get_link(struct dentry *dentry,
if (!pid)
return ERR_PTR(-ENOENT);
- name = kmalloc(PROC_NUMBUF + 6 + PROC_NUMBUF,
- dentry ? GFP_KERNEL : GFP_ATOMIC);
+ name = kmalloc(10 + 6 + 10 + 1, dentry ? GFP_KERNEL : GFP_ATOMIC);
if (unlikely(!name))
return dentry ? ERR_PTR(-ENOMEM) : ERR_PTR(-ECHILD);
- sprintf(name, "%d/task/%d", tgid, pid);
+ sprintf(name, "%u/task/%u", tgid, pid);
set_delayed_call(done, kfree_link, name);
return name;
}
@@ -31,7 +31,7 @@ static const struct inode_operations proc_thread_self_inode_operations = {
.get_link = proc_thread_self_get_link,
};
-static unsigned thread_self_inum;
+static unsigned thread_self_inum __ro_after_init;
int proc_setup_thread_self(struct super_block *s)
{
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 885d445afa0d..a45f0af22a60 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -1178,18 +1178,16 @@ fs_initcall(vmcore_init);
/* Cleanup function for vmcore module. */
void vmcore_cleanup(void)
{
- struct list_head *pos, *next;
-
if (proc_vmcore) {
proc_remove(proc_vmcore);
proc_vmcore = NULL;
}
/* clear the vmcore list. */
- list_for_each_safe(pos, next, &vmcore_list) {
+ while (!list_empty(&vmcore_list)) {
struct vmcore *m;
- m = list_entry(pos, struct vmcore, list);
+ m = list_first_entry(&vmcore_list, struct vmcore, list);
list_del(&m->list);
kfree(m);
}
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c
index 14626b34d13e..0927a4b2ecaf 100644
--- a/fs/udf/udftime.c
+++ b/fs/udf/udftime.c
@@ -62,6 +62,11 @@ udf_disk_stamp_to_time(struct timespec *dest, struct timestamp src)
dest->tv_sec -= offset * 60;
dest->tv_nsec = 1000 * (src.centiseconds * 10000 +
src.hundredsOfMicroseconds * 100 + src.microseconds);
+ /*
+ * Sanitize nanosecond field since reportedly some filesystems are
+ * recorded with bogus sub-second values.
+ */
+ dest->tv_nsec %= NSEC_PER_SEC;
return dest;
}
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 50dfce000864..b721d0bda5e5 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -429,7 +429,7 @@ ufs_readdir(struct file *file, struct dir_context *ctx)
unsigned long n = pos >> PAGE_SHIFT;
unsigned long npages = dir_pages(inode);
unsigned chunk_mask = ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
- bool need_revalidate = inode_cmp_iversion(inode, file->f_version);
+ bool need_revalidate = !inode_eq_iversion(inode, file->f_version);
unsigned flags = UFS_SB(sb)->s_flags;
UFSD("BEGIN\n");
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 46af6aa60a8e..a55f7a45fa78 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -118,8 +118,8 @@ xfs_mount_validate_sb(
bool check_inprogress,
bool check_version)
{
- u32 agcount = 0;
- u32 rem;
+ uint32_t agcount = 0;
+ uint32_t rem;
if (sbp->sb_magicnum != XFS_SB_MAGIC) {
xfs_warn(mp, "bad magic number");
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index f3e0001f9992..7aba628dc527 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1666,9 +1666,12 @@ xfs_fs_fill_super(
"DAX unsupported by block device. Turning off DAX.");
mp->m_flags &= ~XFS_MOUNT_DAX;
}
- if (xfs_sb_version_hasreflink(&mp->m_sb))
+ if (xfs_sb_version_hasreflink(&mp->m_sb)) {
xfs_alert(mp,
"DAX and reflink cannot be used together!");
+ error = -EINVAL;
+ goto out_filestream_unmount;
+ }
}
if (mp->m_flags & XFS_MOUNT_DISCARD) {
@@ -1681,15 +1684,18 @@ xfs_fs_fill_super(
}
}
- if (xfs_sb_version_hasrmapbt(&mp->m_sb)) {
- if (mp->m_sb.sb_rblocks) {
- xfs_alert(mp,
- "EXPERIMENTAL reverse mapping btree not compatible with realtime device!");
- error = -EINVAL;
- goto out_filestream_unmount;
- }
+ if (xfs_sb_version_hasreflink(&mp->m_sb) && mp->m_sb.sb_rblocks) {
+ xfs_alert(mp,
+ "reflink not compatible with realtime device!");
+ error = -EINVAL;
+ goto out_filestream_unmount;
+ }
+
+ if (xfs_sb_version_hasrmapbt(&mp->m_sb) && mp->m_sb.sb_rblocks) {
xfs_alert(mp,
- "EXPERIMENTAL reverse mapping btree feature enabled. Use at your own risk!");
+ "reverse mapping btree not compatible with realtime device!");
+ error = -EINVAL;
+ goto out_filestream_unmount;
}
error = xfs_mountfs(mp);
diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h
index fcc5dfc70aa0..8cee8e8050e3 100644
--- a/fs/xfs/xfs_super.h
+++ b/fs/xfs/xfs_super.h
@@ -44,6 +44,12 @@ extern void xfs_qm_exit(void);
# define XFS_REALTIME_STRING
#endif
+#ifdef CONFIG_XFS_ONLINE_SCRUB
+# define XFS_SCRUB_STRING "scrub, "
+#else
+# define XFS_SCRUB_STRING
+#endif
+
#ifdef DEBUG
# define XFS_DBG_STRING "debug"
#else
@@ -54,6 +60,7 @@ extern void xfs_qm_exit(void);
#define XFS_BUILD_OPTIONS XFS_ACL_STRING \
XFS_SECURITY_STRING \
XFS_REALTIME_STRING \
+ XFS_SCRUB_STRING \
XFS_DBG_STRING /* DBG must be last */
struct xfs_inode;
diff --git a/include/asm-generic/audit_dir_write.h b/include/asm-generic/audit_dir_write.h
index da09fb986459..dd5a9dd7a102 100644
--- a/include/asm-generic/audit_dir_write.h
+++ b/include/asm-generic/audit_dir_write.h
@@ -27,7 +27,9 @@ __NR_mknod,
__NR_mkdirat,
__NR_mknodat,
__NR_unlinkat,
+#ifdef __NR_renameat
__NR_renameat,
+#endif
__NR_linkat,
__NR_symlinkat,
#endif
diff --git a/include/asm-generic/bitops/find.h b/include/asm-generic/bitops/find.h
index 1ba611e16fa0..8a1ee10014de 100644
--- a/include/asm-generic/bitops/find.h
+++ b/include/asm-generic/bitops/find.h
@@ -16,6 +16,22 @@ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
size, unsigned long offset);
#endif
+#ifndef find_next_and_bit
+/**
+ * find_next_and_bit - find the next set bit in both memory regions
+ * @addr1: The first address to base the search on
+ * @addr2: The second address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The bitmap size in bits
+ *
+ * Returns the bit number for the next set bit
+ * If no bits are set, returns @size.
+ */
+extern unsigned long find_next_and_bit(const unsigned long *addr1,
+ const unsigned long *addr2, unsigned long size,
+ unsigned long offset);
+#endif
+
#ifndef find_next_zero_bit
/**
* find_next_zero_bit - find the next cleared bit in a memory region
@@ -55,8 +71,12 @@ extern unsigned long find_first_zero_bit(const unsigned long *addr,
unsigned long size);
#else /* CONFIG_GENERIC_FIND_FIRST_BIT */
+#ifndef find_first_bit
#define find_first_bit(addr, size) find_next_bit((addr), (size), 0)
+#endif
+#ifndef find_first_zero_bit
#define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
+#endif
#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
diff --git a/include/asm-generic/pci_iomap.h b/include/asm-generic/pci_iomap.h
index b1e17fcee2d0..854f96ad5ccb 100644
--- a/include/asm-generic/pci_iomap.h
+++ b/include/asm-generic/pci_iomap.h
@@ -1,12 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/* Generic I/O port emulation, based on MN10300 code
*
* 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_GENERIC_PCI_IOMAP_H
#define __ASM_GENERIC_PCI_IOMAP_H
diff --git a/include/asm-generic/qrwlock_types.h b/include/asm-generic/qrwlock_types.h
index 137ecdd16daa..c36f1d5a2572 100644
--- a/include/asm-generic/qrwlock_types.h
+++ b/include/asm-generic/qrwlock_types.h
@@ -3,6 +3,7 @@
#define __ASM_GENERIC_QRWLOCK_TYPES_H
#include <linux/types.h>
+#include <asm/byteorder.h>
#include <asm/spinlock_types.h>
/*
diff --git a/include/dt-bindings/clock/jz4770-cgu.h b/include/dt-bindings/clock/jz4770-cgu.h
new file mode 100644
index 000000000000..d68a7695a1f8
--- /dev/null
+++ b/include/dt-bindings/clock/jz4770-cgu.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides clock numbers for the ingenic,jz4770-cgu DT binding.
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4770_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4770_CGU_H__
+
+#define JZ4770_CLK_EXT 0
+#define JZ4770_CLK_OSC32K 1
+#define JZ4770_CLK_PLL0 2
+#define JZ4770_CLK_PLL1 3
+#define JZ4770_CLK_CCLK 4
+#define JZ4770_CLK_H0CLK 5
+#define JZ4770_CLK_H1CLK 6
+#define JZ4770_CLK_H2CLK 7
+#define JZ4770_CLK_C1CLK 8
+#define JZ4770_CLK_PCLK 9
+#define JZ4770_CLK_MMC0_MUX 10
+#define JZ4770_CLK_MMC0 11
+#define JZ4770_CLK_MMC1_MUX 12
+#define JZ4770_CLK_MMC1 13
+#define JZ4770_CLK_MMC2_MUX 14
+#define JZ4770_CLK_MMC2 15
+#define JZ4770_CLK_CIM 16
+#define JZ4770_CLK_UHC 17
+#define JZ4770_CLK_GPU 18
+#define JZ4770_CLK_BCH 19
+#define JZ4770_CLK_LPCLK_MUX 20
+#define JZ4770_CLK_GPS 21
+#define JZ4770_CLK_SSI_MUX 22
+#define JZ4770_CLK_PCM_MUX 23
+#define JZ4770_CLK_I2S 24
+#define JZ4770_CLK_OTG 25
+#define JZ4770_CLK_SSI0 26
+#define JZ4770_CLK_SSI1 27
+#define JZ4770_CLK_SSI2 28
+#define JZ4770_CLK_PCM0 29
+#define JZ4770_CLK_PCM1 30
+#define JZ4770_CLK_DMA 31
+#define JZ4770_CLK_I2C0 32
+#define JZ4770_CLK_I2C1 33
+#define JZ4770_CLK_I2C2 34
+#define JZ4770_CLK_UART0 35
+#define JZ4770_CLK_UART1 36
+#define JZ4770_CLK_UART2 37
+#define JZ4770_CLK_UART3 38
+#define JZ4770_CLK_IPU 39
+#define JZ4770_CLK_ADC 40
+#define JZ4770_CLK_AIC 41
+#define JZ4770_CLK_AUX 42
+#define JZ4770_CLK_VPU 43
+#define JZ4770_CLK_UHC_PHY 44
+#define JZ4770_CLK_OTG_PHY 45
+#define JZ4770_CLK_EXT512 46
+#define JZ4770_CLK_RTC 47
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4770_CGU_H__ */
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 3489253e38fc..5f11fbdc27f8 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -64,9 +64,14 @@
* bitmap_find_free_region(bitmap, bits, order) Find and allocate bit region
* bitmap_release_region(bitmap, pos, order) Free specified bit region
* bitmap_allocate_region(bitmap, pos, order) Allocate specified bit region
- * bitmap_from_u32array(dst, nbits, buf, nwords) *dst = *buf (nwords 32b words)
- * bitmap_to_u32array(buf, nwords, src, nbits) *buf = *dst (nwords 32b words)
+ * bitmap_from_arr32(dst, buf, nbits) Copy nbits from u32[] buf to dst
+ * bitmap_to_arr32(buf, src, nbits) Copy nbits from buf to u32[] dst
*
+ * Note, bitmap_zero() and bitmap_fill() operate over the region of
+ * unsigned longs, that is, bits behind bitmap till the unsigned long
+ * boundary will be zeroed or filled as well. Consider to use
+ * bitmap_clear() or bitmap_set() to make explicit zeroing or filling
+ * respectively.
*/
/**
@@ -83,8 +88,12 @@
* test_and_change_bit(bit, addr) Change bit and return old value
* find_first_zero_bit(addr, nbits) Position first zero bit in *addr
* find_first_bit(addr, nbits) Position first set bit in *addr
- * find_next_zero_bit(addr, nbits, bit) Position next zero bit in *addr >= bit
+ * find_next_zero_bit(addr, nbits, bit)
+ * Position next zero bit in *addr >= bit
* find_next_bit(addr, nbits, bit) Position next set bit in *addr >= bit
+ * find_next_and_bit(addr1, addr2, nbits, bit)
+ * Same as find_next_bit, but in
+ * (*addr1 & *addr2)
*
*/
@@ -174,14 +183,7 @@ extern void bitmap_fold(unsigned long *dst, const unsigned long *orig,
extern int bitmap_find_free_region(unsigned long *bitmap, unsigned int bits, int order);
extern void bitmap_release_region(unsigned long *bitmap, unsigned int pos, int order);
extern int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order);
-extern unsigned int bitmap_from_u32array(unsigned long *bitmap,
- unsigned int nbits,
- const u32 *buf,
- unsigned int nwords);
-extern unsigned int bitmap_to_u32array(u32 *buf,
- unsigned int nwords,
- const unsigned long *bitmap,
- unsigned int nbits);
+
#ifdef __BIG_ENDIAN
extern void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits);
#else
@@ -209,12 +211,12 @@ static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
static inline void bitmap_fill(unsigned long *dst, unsigned int nbits)
{
- unsigned int nlongs = BITS_TO_LONGS(nbits);
- if (!small_const_nbits(nbits)) {
- unsigned int len = (nlongs - 1) * sizeof(unsigned long);
- memset(dst, 0xff, len);
+ if (small_const_nbits(nbits))
+ *dst = ~0UL;
+ else {
+ unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
+ memset(dst, 0xff, len);
}
- dst[nlongs - 1] = BITMAP_LAST_WORD_MASK(nbits);
}
static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
@@ -228,6 +230,35 @@ static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
}
}
+/*
+ * Copy bitmap and clear tail bits in last word.
+ */
+static inline void bitmap_copy_clear_tail(unsigned long *dst,
+ const unsigned long *src, unsigned int nbits)
+{
+ bitmap_copy(dst, src, nbits);
+ if (nbits % BITS_PER_LONG)
+ dst[nbits / BITS_PER_LONG] &= BITMAP_LAST_WORD_MASK(nbits);
+}
+
+/*
+ * On 32-bit systems bitmaps are represented as u32 arrays internally, and
+ * therefore conversion is not needed when copying data from/to arrays of u32.
+ */
+#if BITS_PER_LONG == 64
+extern void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf,
+ unsigned int nbits);
+extern void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap,
+ unsigned int nbits);
+#else
+#define bitmap_from_arr32(bitmap, buf, nbits) \
+ bitmap_copy_clear_tail((unsigned long *) (bitmap), \
+ (const unsigned long *) (buf), (nbits))
+#define bitmap_to_arr32(buf, bitmap, nbits) \
+ bitmap_copy_clear_tail((unsigned long *) (buf), \
+ (const unsigned long *) (bitmap), (nbits))
+#endif
+
static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
const unsigned long *src2, unsigned int nbits)
{
diff --git a/include/linux/build_bug.h b/include/linux/build_bug.h
index 3efed0d742a0..43d1fd50d433 100644
--- a/include/linux/build_bug.h
+++ b/include/linux/build_bug.h
@@ -8,7 +8,6 @@
#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
#define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
#define BUILD_BUG_ON_ZERO(e) (0)
-#define BUILD_BUG_ON_NULL(e) ((void *)0)
#define BUILD_BUG_ON_INVALID(e) (0)
#define BUILD_BUG_ON_MSG(cond, msg) (0)
#define BUILD_BUG_ON(condition) (0)
@@ -28,7 +27,6 @@
* aren't permitted).
*/
#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
-#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:(-!!(e)); }))
/*
* BUILD_BUG_ON_INVALID() permits the compiler to check the validity of the
diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h
index 3b609edffa8f..d02a4df3f473 100644
--- a/include/linux/compiler-clang.h
+++ b/include/linux/compiler-clang.h
@@ -19,3 +19,11 @@
#define randomized_struct_fields_start struct {
#define randomized_struct_fields_end };
+
+/* all clang versions usable with the kernel support KASAN ABI version 5 */
+#define KASAN_ABI_VERSION 5
+
+/* emulate gcc's __SANITIZE_ADDRESS__ flag */
+#if __has_feature(address_sanitizer)
+#define __SANITIZE_ADDRESS__
+#endif
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 75b565194437..d4a2a7dcd72d 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -640,7 +640,7 @@ static inline int cpulist_parse(const char *buf, struct cpumask *dstp)
/**
* cpumask_size - size to allocate for a 'struct cpumask' in bytes
*/
-static inline size_t cpumask_size(void)
+static inline unsigned int cpumask_size(void)
{
return BITS_TO_LONGS(nr_cpumask_bits) * sizeof(long);
}
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 1b8e41597ef5..934633a05d20 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -112,7 +112,7 @@ static inline int cpuset_do_slab_mem_spread(void)
return task_spread_slab(current);
}
-extern int current_cpuset_is_being_rebound(void);
+extern bool current_cpuset_is_being_rebound(void);
extern void rebuild_sched_domains(void);
@@ -247,9 +247,9 @@ static inline int cpuset_do_slab_mem_spread(void)
return 0;
}
-static inline int current_cpuset_is_being_rebound(void)
+static inline bool current_cpuset_is_being_rebound(void)
{
- return 0;
+ return false;
}
static inline void rebuild_sched_domains(void)
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
index a992e6ca2f1c..f7ac2aa93269 100644
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -2,13 +2,13 @@
#ifndef LINUX_CRASH_DUMP_H
#define LINUX_CRASH_DUMP_H
-#ifdef CONFIG_CRASH_DUMP
#include <linux/kexec.h>
#include <linux/proc_fs.h>
#include <linux/elf.h>
#include <asm/pgtable.h> /* for pgprot_t */
+#ifdef CONFIG_CRASH_DUMP
#define ELFCORE_ADDR_MAX (-1ULL)
#define ELFCORE_ADDR_ERR (-2ULL)
@@ -52,13 +52,13 @@ void vmcore_cleanup(void);
* has passed the elf core header address on command line.
*
* This is not just a test if CONFIG_CRASH_DUMP is enabled or not. It will
- * return 1 if CONFIG_CRASH_DUMP=y and if kernel is booting after a panic of
- * previous kernel.
+ * return true if CONFIG_CRASH_DUMP=y and if kernel is booting after a panic
+ * of previous kernel.
*/
-static inline int is_kdump_kernel(void)
+static inline bool is_kdump_kernel(void)
{
- return (elfcorehdr_addr != ELFCORE_ADDR_MAX) ? 1 : 0;
+ return elfcorehdr_addr != ELFCORE_ADDR_MAX;
}
/* is_vmcore_usable() checks if the kernel is booting after a panic and
@@ -89,7 +89,7 @@ extern int register_oldmem_pfn_is_ram(int (*fn)(unsigned long pfn));
extern void unregister_oldmem_pfn_is_ram(void);
#else /* !CONFIG_CRASH_DUMP */
-static inline int is_kdump_kernel(void) { return 0; }
+static inline bool is_kdump_kernel(void) { return 0; }
#endif /* CONFIG_CRASH_DUMP */
extern unsigned long saved_max_pfn;
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 65cd8ab60b7a..82a99d366aec 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -227,6 +227,7 @@ extern seqlock_t rename_lock;
*/
extern void d_instantiate(struct dentry *, struct inode *);
extern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
+extern struct dentry * d_instantiate_anon(struct dentry *, struct inode *);
extern int d_instantiate_no_diralias(struct dentry *, struct inode *);
extern void __d_drop(struct dentry *dentry);
extern void d_drop(struct dentry *dentry);
@@ -235,6 +236,7 @@ extern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op
/* allocate/de-allocate */
extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
+extern struct dentry * d_alloc_anon(struct super_block *);
extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *);
extern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *,
wait_queue_head_t *);
diff --git a/include/linux/fb.h b/include/linux/fb.h
index d1e5bed39140..f577d3c89618 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -569,7 +569,10 @@ static inline struct apertures_struct *alloc_apertures(unsigned int max_num) {
#define fb_memcpy_fromfb sbus_memcpy_fromio
#define fb_memcpy_tofb sbus_memcpy_toio
-#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) || defined(__arm__)
+#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || \
+ defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || \
+ defined(__avr32__) || defined(__bfin__) || defined(__arm__) || \
+ defined(__aarch64__)
#define fb_readb __raw_readb
#define fb_readw __raw_readw
diff --git a/include/linux/genl_magic_func.h b/include/linux/genl_magic_func.h
index 604967609e55..83f81ac53282 100644
--- a/include/linux/genl_magic_func.h
+++ b/include/linux/genl_magic_func.h
@@ -2,6 +2,7 @@
#ifndef GENL_MAGIC_FUNC_H
#define GENL_MAGIC_FUNC_H
+#include <linux/build_bug.h>
#include <linux/genl_magic_struct.h>
/*
@@ -132,17 +133,6 @@ static void dprint_array(const char *dir, int nla_type,
* use one static buffer for parsing of nested attributes */
static struct nlattr *nested_attr_tb[128];
-#ifndef BUILD_BUG_ON
-/* Force a compilation error if condition is true */
-#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition))
-/* Force a compilation error if condition is true, but also produce a
- result (of value 0 and type size_t), so the expression can be used
- e.g. in a structure initializer (or where-ever else comma expressions
- aren't permitted). */
-#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
-#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
-#endif
-
#undef GENL_struct
#define GENL_struct(tag_name, tag_number, s_name, s_fields) \
/* *_from_attrs functions are static, but potentially unused */ \
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 93b4183cf53d..da0ebaec25f0 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -265,7 +265,7 @@ extern struct resource * __devm_request_region(struct device *dev,
extern void __devm_release_region(struct device *dev, struct resource *parent,
resource_size_t start, resource_size_t n);
extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size);
-extern int iomem_is_exclusive(u64 addr);
+extern bool iomem_is_exclusive(u64 addr);
extern int
walk_system_ram_range(unsigned long start_pfn, unsigned long nr_pages,
diff --git a/include/linux/iversion.h b/include/linux/iversion.h
index 3d2fd06495ec..be50ef7cedab 100644
--- a/include/linux/iversion.h
+++ b/include/linux/iversion.h
@@ -45,7 +45,7 @@
*
* With this implementation, the value should always appear to observers to
* increase over time if the file has changed. It's recommended to use
- * inode_cmp_iversion() helper to compare values.
+ * inode_eq_iversion() helper to compare values.
*
* Note that some filesystems (e.g. NFS and AFS) just use the field to store
* a server-provided value (for the most part). For that reason, those
@@ -305,33 +305,33 @@ inode_query_iversion(struct inode *inode)
}
/**
- * inode_cmp_iversion_raw - check whether the raw i_version counter has changed
+ * inode_eq_iversion_raw - check whether the raw i_version counter has changed
* @inode: inode to check
* @old: old value to check against its i_version
*
- * Compare the current raw i_version counter with a previous one. Returns false
- * if they are the same or true if they are different.
+ * Compare the current raw i_version counter with a previous one. Returns true
+ * if they are the same or false if they are different.
*/
static inline bool
-inode_cmp_iversion_raw(const struct inode *inode, u64 old)
+inode_eq_iversion_raw(const struct inode *inode, u64 old)
{
- return inode_peek_iversion_raw(inode) != old;
+ return inode_peek_iversion_raw(inode) == old;
}
/**
- * inode_cmp_iversion - check whether the i_version counter has changed
+ * inode_eq_iversion - check whether the i_version counter has changed
* @inode: inode to check
* @old: old value to check against its i_version
*
- * Compare an i_version counter with a previous one. Returns false if they are
- * the same, and true if they are different.
+ * Compare an i_version counter with a previous one. Returns true if they are
+ * the same, and false if they are different.
*
* Note that we don't need to set the QUERIED flag in this case, as the value
* in the inode is not being recorded for later use.
*/
static inline bool
-inode_cmp_iversion(const struct inode *inode, u64 old)
+inode_eq_iversion(const struct inode *inode, u64 old)
{
- return inode_peek_iversion(inode) != old;
+ return inode_peek_iversion(inode) == old;
}
#endif
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index e0340ca08d98..b6a29c126cc4 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -393,7 +393,7 @@ extern bool ____wrong_branch_error(void);
branch = !arch_static_branch_jump(&(x)->key, true); \
else \
branch = ____wrong_branch_error(); \
- branch; \
+ likely(branch); \
})
#define static_branch_unlikely(x) \
@@ -405,7 +405,7 @@ extern bool ____wrong_branch_error(void);
branch = arch_static_branch(&(x)->key, false); \
else \
branch = ____wrong_branch_error(); \
- branch; \
+ unlikely(branch); \
})
#else /* !HAVE_JUMP_LABEL */
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index d79d1e7486bd..657a83b943f0 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -167,7 +167,7 @@ static inline int kallsyms_show_value(void)
static inline void print_ip_sym(unsigned long ip)
{
- printk("[<%p>] %pS\n", (void *) ip, (void *) ip);
+ printk("[<%px>] %pS\n", (void *) ip, (void *) ip);
}
#endif /*_LINUX_KALLSYMS_H*/
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index e3eb834c9a35..adc13474a53b 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -11,8 +11,6 @@ struct task_struct;
#ifdef CONFIG_KASAN
-#define KASAN_SHADOW_SCALE_SHIFT 3
-
#include <asm/kasan.h>
#include <asm/pgtable.h>
@@ -56,14 +54,14 @@ void kasan_poison_object_data(struct kmem_cache *cache, void *object);
void kasan_init_slab_obj(struct kmem_cache *cache, const void *object);
void kasan_kmalloc_large(const void *ptr, size_t size, gfp_t flags);
-void kasan_kfree_large(const void *ptr);
-void kasan_poison_kfree(void *ptr);
+void kasan_kfree_large(void *ptr, unsigned long ip);
+void kasan_poison_kfree(void *ptr, unsigned long ip);
void kasan_kmalloc(struct kmem_cache *s, const void *object, size_t size,
gfp_t flags);
void kasan_krealloc(const void *object, size_t new_size, gfp_t flags);
void kasan_slab_alloc(struct kmem_cache *s, void *object, gfp_t flags);
-bool kasan_slab_free(struct kmem_cache *s, void *object);
+bool kasan_slab_free(struct kmem_cache *s, void *object, unsigned long ip);
struct kasan_cache {
int alloc_meta_offset;
@@ -108,8 +106,8 @@ static inline void kasan_init_slab_obj(struct kmem_cache *cache,
const void *object) {}
static inline void kasan_kmalloc_large(void *ptr, size_t size, gfp_t flags) {}
-static inline void kasan_kfree_large(const void *ptr) {}
-static inline void kasan_poison_kfree(void *ptr) {}
+static inline void kasan_kfree_large(void *ptr, unsigned long ip) {}
+static inline void kasan_poison_kfree(void *ptr, unsigned long ip) {}
static inline void kasan_kmalloc(struct kmem_cache *s, const void *object,
size_t size, gfp_t flags) {}
static inline void kasan_krealloc(const void *object, size_t new_size,
@@ -117,7 +115,8 @@ static inline void kasan_krealloc(const void *object, size_t new_size,
static inline void kasan_slab_alloc(struct kmem_cache *s, void *object,
gfp_t flags) {}
-static inline bool kasan_slab_free(struct kmem_cache *s, void *object)
+static inline bool kasan_slab_free(struct kmem_cache *s, void *object,
+ unsigned long ip)
{
return false;
}
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
index 7b45959ebd92..e251533a5939 100644
--- a/include/linux/kfifo.h
+++ b/include/linux/kfifo.h
@@ -113,7 +113,8 @@ struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void);
* array is a part of the structure and the fifo type where the array is
* outside of the fifo structure.
*/
-#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo))
+#define __is_kfifo_ptr(fifo) \
+ (sizeof(*fifo) == sizeof(STRUCT_KFIFO_PTR(typeof(*(fifo)->type))))
/**
* DECLARE_KFIFO_PTR - macro to declare a fifo pointer object
diff --git a/include/linux/led-class-flash.h b/include/linux/led-class-flash.h
index e97966d1fb8d..700efaa9e115 100644
--- a/include/linux/led-class-flash.h
+++ b/include/linux/led-class-flash.h
@@ -121,6 +121,8 @@ extern void led_classdev_flash_unregister(struct led_classdev_flash *fled_cdev);
static inline int led_set_flash_strobe(struct led_classdev_flash *fled_cdev,
bool state)
{
+ if (!fled_cdev)
+ return -EINVAL;
return fled_cdev->ops->strobe_set(fled_cdev, state);
}
@@ -136,6 +138,8 @@ static inline int led_set_flash_strobe(struct led_classdev_flash *fled_cdev,
static inline int led_get_flash_strobe(struct led_classdev_flash *fled_cdev,
bool *state)
{
+ if (!fled_cdev)
+ return -EINVAL;
if (fled_cdev->ops->strobe_get)
return fled_cdev->ops->strobe_get(fled_cdev, state);
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index f8109ddb5ef1..ff855ed965fb 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -47,6 +47,17 @@ enum {
/* region flag indicating to direct-map persistent memory by default */
ND_REGION_PAGEMAP = 0,
+ /*
+ * Platform ensures entire CPU store data path is flushed to pmem on
+ * system power loss.
+ */
+ ND_REGION_PERSIST_CACHE = 1,
+ /*
+ * Platform provides mechanisms to automatically flush outstanding
+ * write data from memory controler to pmem on system power loss.
+ * (ADR)
+ */
+ ND_REGION_PERSIST_MEMCTRL = 2,
/* mark newly adjusted resources as requiring a label update */
DPA_RESOURCE_ADJUSTED = 1 << 0,
diff --git a/include/linux/lockref.h b/include/linux/lockref.h
index ef3c9342e119..2eac32095113 100644
--- a/include/linux/lockref.h
+++ b/include/linux/lockref.h
@@ -44,7 +44,7 @@ extern void lockref_mark_dead(struct lockref *);
extern int lockref_get_not_dead(struct lockref *);
/* Must be called under spinlock for reliable results */
-static inline int __lockref_is_dead(const struct lockref *l)
+static inline bool __lockref_is_dead(const struct lockref *l)
{
return ((int)l->count < 0);
}
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 7ed0f7782d16..8be5077efb5f 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -332,8 +332,8 @@ void memblock_enforce_memory_limit(phys_addr_t memory_limit);
void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
void memblock_mem_limit_remove_map(phys_addr_t limit);
bool memblock_is_memory(phys_addr_t addr);
-int memblock_is_map_memory(phys_addr_t addr);
-int memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
+bool memblock_is_map_memory(phys_addr_t addr);
+bool memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
bool memblock_is_reserved(phys_addr_t addr);
bool memblock_is_region_reserved(phys_addr_t base, phys_addr_t size);
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 58e110aee7ab..aba5f86eb038 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -13,6 +13,7 @@ struct pglist_data;
struct mem_section;
struct memory_block;
struct resource;
+struct vmem_altmap;
#ifdef CONFIG_MEMORY_HOTPLUG
/*
@@ -125,24 +126,26 @@ static inline bool movable_node_is_enabled(void)
#ifdef CONFIG_MEMORY_HOTREMOVE
extern bool is_pageblock_removable_nolock(struct page *page);
-extern int arch_remove_memory(u64 start, u64 size);
+extern int arch_remove_memory(u64 start, u64 size,
+ struct vmem_altmap *altmap);
extern int __remove_pages(struct zone *zone, unsigned long start_pfn,
- unsigned long nr_pages);
+ unsigned long nr_pages, struct vmem_altmap *altmap);
#endif /* CONFIG_MEMORY_HOTREMOVE */
/* reasonably generic interface to expand the physical pages */
-extern int __add_pages(int nid, unsigned long start_pfn,
- unsigned long nr_pages, bool want_memblock);
+extern int __add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
+ struct vmem_altmap *altmap, bool want_memblock);
#ifndef CONFIG_ARCH_HAS_ADD_PAGES
static inline int add_pages(int nid, unsigned long start_pfn,
- unsigned long nr_pages, bool want_memblock)
+ unsigned long nr_pages, struct vmem_altmap *altmap,
+ bool want_memblock)
{
- return __add_pages(nid, start_pfn, nr_pages, want_memblock);
+ return __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock);
}
#else /* ARCH_HAS_ADD_PAGES */
-int add_pages(int nid, unsigned long start_pfn,
- unsigned long nr_pages, bool want_memblock);
+int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
+ struct vmem_altmap *altmap, bool want_memblock);
#endif /* ARCH_HAS_ADD_PAGES */
#ifdef CONFIG_NUMA
@@ -318,15 +321,17 @@ extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
void *arg, int (*func)(struct memory_block *, void *));
extern int add_memory(int nid, u64 start, u64 size);
extern int add_memory_resource(int nid, struct resource *resource, bool online);
-extern int arch_add_memory(int nid, u64 start, u64 size, bool want_memblock);
+extern int arch_add_memory(int nid, u64 start, u64 size,
+ struct vmem_altmap *altmap, bool want_memblock);
extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
- unsigned long nr_pages);
+ unsigned long nr_pages, struct vmem_altmap *altmap);
extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
extern bool is_memblock_offlined(struct memory_block *mem);
extern void remove_memory(int nid, u64 start, u64 size);
-extern int sparse_add_one_section(struct pglist_data *pgdat, unsigned long start_pfn);
+extern int sparse_add_one_section(struct pglist_data *pgdat,
+ unsigned long start_pfn, struct vmem_altmap *altmap);
extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms,
- unsigned long map_offset);
+ unsigned long map_offset, struct vmem_altmap *altmap);
extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
unsigned long pnum);
extern bool allow_online_pfn_range(int nid, unsigned long pfn, unsigned long nr_pages,
diff --git a/include/linux/memremap.h b/include/linux/memremap.h
index 10d23c367048..7b4899c06f49 100644
--- a/include/linux/memremap.h
+++ b/include/linux/memremap.h
@@ -26,18 +26,6 @@ struct vmem_altmap {
unsigned long alloc;
};
-unsigned long vmem_altmap_offset(struct vmem_altmap *altmap);
-void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns);
-
-#ifdef CONFIG_ZONE_DEVICE
-struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start);
-#else
-static inline struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start)
-{
- return NULL;
-}
-#endif
-
/*
* Specialize ZONE_DEVICE memory into multiple types each having differents
* usage.
@@ -125,8 +113,9 @@ typedef void (*dev_page_free_t)(struct page *page, void *data);
struct dev_pagemap {
dev_page_fault_t page_fault;
dev_page_free_t page_free;
- struct vmem_altmap *altmap;
- const struct resource *res;
+ struct vmem_altmap altmap;
+ bool altmap_valid;
+ struct resource res;
struct percpu_ref *ref;
struct device *dev;
void *data;
@@ -134,15 +123,17 @@ struct dev_pagemap {
};
#ifdef CONFIG_ZONE_DEVICE
-void *devm_memremap_pages(struct device *dev, struct resource *res,
- struct percpu_ref *ref, struct vmem_altmap *altmap);
-struct dev_pagemap *find_dev_pagemap(resource_size_t phys);
+void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap);
+struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
+ struct dev_pagemap *pgmap);
+
+unsigned long vmem_altmap_offset(struct vmem_altmap *altmap);
+void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns);
static inline bool is_zone_device_page(const struct page *page);
#else
static inline void *devm_memremap_pages(struct device *dev,
- struct resource *res, struct percpu_ref *ref,
- struct vmem_altmap *altmap)
+ struct dev_pagemap *pgmap)
{
/*
* Fail attempts to call devm_memremap_pages() without
@@ -153,11 +144,22 @@ static inline void *devm_memremap_pages(struct device *dev,
return ERR_PTR(-ENXIO);
}
-static inline struct dev_pagemap *find_dev_pagemap(resource_size_t phys)
+static inline struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
+ struct dev_pagemap *pgmap)
{
return NULL;
}
-#endif
+
+static inline unsigned long vmem_altmap_offset(struct vmem_altmap *altmap)
+{
+ return 0;
+}
+
+static inline void vmem_altmap_free(struct vmem_altmap *altmap,
+ unsigned long nr_pfns)
+{
+}
+#endif /* CONFIG_ZONE_DEVICE */
#if defined(CONFIG_DEVICE_PRIVATE) || defined(CONFIG_DEVICE_PUBLIC)
static inline bool is_device_private_page(const struct page *page)
@@ -173,39 +175,6 @@ static inline bool is_device_public_page(const struct page *page)
}
#endif /* CONFIG_DEVICE_PRIVATE || CONFIG_DEVICE_PUBLIC */
-/**
- * get_dev_pagemap() - take a new live reference on the dev_pagemap for @pfn
- * @pfn: page frame number to lookup page_map
- * @pgmap: optional known pgmap that already has a reference
- *
- * @pgmap allows the overhead of a lookup to be bypassed when @pfn lands in the
- * same mapping.
- */
-static inline struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
- struct dev_pagemap *pgmap)
-{
- const struct resource *res = pgmap ? pgmap->res : NULL;
- resource_size_t phys = PFN_PHYS(pfn);
-
- /*
- * In the cached case we're already holding a live reference so
- * we can simply do a blind increment
- */
- if (res && phys >= res->start && phys <= res->end) {
- percpu_ref_get(pgmap->ref);
- return pgmap;
- }
-
- /* fall back to slow path lookup */
- rcu_read_lock();
- pgmap = find_dev_pagemap(phys);
- if (pgmap && !percpu_ref_tryget_live(pgmap->ref))
- pgmap = NULL;
- rcu_read_unlock();
-
- return pgmap;
-}
-
static inline void put_dev_pagemap(struct dev_pagemap *pgmap)
{
if (pgmap)
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index fb7e8b205eb9..6ed79a8a8318 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -1277,7 +1277,7 @@ mlx5_get_vector_affinity(struct mlx5_core_dev *dev, int vector)
int eqn;
int err;
- err = mlx5_vector2eqn(dev, vector, &eqn, &irq);
+ err = mlx5_vector2eqn(dev, MLX5_EQ_VEC_COMP_BASE + vector, &eqn, &irq);
if (err)
return NULL;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 173d2484f6e3..ad06d42adb1a 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2075,8 +2075,8 @@ static inline void zero_resv_unavail(void) {}
#endif
extern void set_dma_reserve(unsigned long new_dma_reserve);
-extern void memmap_init_zone(unsigned long, int, unsigned long,
- unsigned long, enum memmap_context);
+extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long,
+ enum memmap_context, struct vmem_altmap *);
extern void setup_per_zone_wmarks(void);
extern int __meminit init_per_zone_wmark_min(void);
extern void mem_init(void);
@@ -2544,7 +2544,8 @@ void sparse_mem_maps_populate_node(struct page **map_map,
unsigned long map_count,
int nodeid);
-struct page *sparse_mem_map_populate(unsigned long pnum, int nid);
+struct page *sparse_mem_map_populate(unsigned long pnum, int nid,
+ struct vmem_altmap *altmap);
pgd_t *vmemmap_pgd_populate(unsigned long addr, int node);
p4d_t *vmemmap_p4d_populate(pgd_t *pgd, unsigned long addr, int node);
pud_t *vmemmap_pud_populate(p4d_t *p4d, unsigned long addr, int node);
@@ -2552,20 +2553,17 @@ pmd_t *vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node);
pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node);
void *vmemmap_alloc_block(unsigned long size, int node);
struct vmem_altmap;
-void *__vmemmap_alloc_block_buf(unsigned long size, int node,
- struct vmem_altmap *altmap);
-static inline void *vmemmap_alloc_block_buf(unsigned long size, int node)
-{
- return __vmemmap_alloc_block_buf(size, node, NULL);
-}
-
+void *vmemmap_alloc_block_buf(unsigned long size, int node);
+void *altmap_alloc_block_buf(unsigned long size, struct vmem_altmap *altmap);
void vmemmap_verify(pte_t *, int, unsigned long, unsigned long);
int vmemmap_populate_basepages(unsigned long start, unsigned long end,
int node);
-int vmemmap_populate(unsigned long start, unsigned long end, int node);
+int vmemmap_populate(unsigned long start, unsigned long end, int node,
+ struct vmem_altmap *altmap);
void vmemmap_populate_print_last(void);
#ifdef CONFIG_MEMORY_HOTPLUG
-void vmemmap_free(unsigned long start, unsigned long end);
+void vmemmap_free(unsigned long start, unsigned long end,
+ struct vmem_altmap *altmap);
#endif
void register_page_bootmem_memmap(unsigned long section_nr, struct page *map,
unsigned long nr_pages);
diff --git a/include/linux/module.h b/include/linux/module.h
index 8dc7065d904d..d44df9b2c131 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -491,7 +491,7 @@ extern struct mutex module_mutex;
/* FIXME: It'd be nice to isolate modules during init, too, so they
aren't used before they (may) fail. But presently too much code
(IDE & SCSI) require entry into the module during init.*/
-static inline int module_is_live(struct module *mod)
+static inline bool module_is_live(struct module *mod)
{
return mod->state != MODULE_STATE_GOING;
}
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 153274f78402..f25c13423bd4 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -138,9 +138,9 @@ extern void __mutex_init(struct mutex *lock, const char *name,
* mutex_is_locked - is the mutex locked
* @lock: the mutex to be queried
*
- * Returns 1 if the mutex is locked, 0 if unlocked.
+ * Returns true if the mutex is locked, false if unlocked.
*/
-static inline int mutex_is_locked(struct mutex *lock)
+static inline bool mutex_is_locked(struct mutex *lock)
{
/*
* XXX think about spin_is_locked
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 4c77f39ebd65..5eef6c8e2741 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -3228,6 +3228,12 @@ static inline int netif_set_real_num_rx_queues(struct net_device *dev,
}
#endif
+static inline struct netdev_rx_queue *
+__netif_get_rx_queue(struct net_device *dev, unsigned int rxq)
+{
+ return dev->_rx + rxq;
+}
+
#ifdef CONFIG_SYSFS
static inline unsigned int get_netdev_rx_queue_index(
struct netdev_rx_queue *queue)
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h
index bf588a05d0d0..88865e0ebf4d 100644
--- a/include/linux/of_pci.h
+++ b/include/linux/of_pci.h
@@ -9,8 +9,7 @@ struct pci_dev;
struct of_phandle_args;
struct device_node;
-#ifdef CONFIG_OF_PCI
-int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq);
+#if IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_PCI)
struct device_node *of_pci_find_child_device(struct device_node *parent,
unsigned int devfn);
int of_pci_get_devfn(struct device_node *np);
@@ -23,11 +22,6 @@ int of_pci_map_rid(struct device_node *np, u32 rid,
const char *map_name, const char *map_mask_name,
struct device_node **target, u32 *id_out);
#else
-static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
-{
- return 0;
-}
-
static inline struct device_node *of_pci_find_child_device(struct device_node *parent,
unsigned int devfn)
{
diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h
index 3cc06b059017..df28af5cef21 100644
--- a/include/linux/pci-aspm.h
+++ b/include/linux/pci-aspm.h
@@ -24,43 +24,12 @@
#define PCIE_LINK_STATE_CLKPM 4
#ifdef CONFIG_PCIEASPM
-void pcie_aspm_init_link_state(struct pci_dev *pdev);
-void pcie_aspm_exit_link_state(struct pci_dev *pdev);
-void pcie_aspm_pm_state_change(struct pci_dev *pdev);
-void pcie_aspm_powersave_config_link(struct pci_dev *pdev);
void pci_disable_link_state(struct pci_dev *pdev, int state);
void pci_disable_link_state_locked(struct pci_dev *pdev, int state);
void pcie_no_aspm(void);
#else
-static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
-{
-}
-static inline void pcie_aspm_exit_link_state(struct pci_dev *pdev)
-{
-}
-static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev)
-{
-}
-static inline void pcie_aspm_powersave_config_link(struct pci_dev *pdev)
-{
-}
-static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
-{
-}
-static inline void pcie_no_aspm(void)
-{
-}
+static inline void pci_disable_link_state(struct pci_dev *pdev, int state) { }
+static inline void pcie_no_aspm(void) { }
#endif
-#ifdef CONFIG_PCIEASPM_DEBUG /* this depends on CONFIG_PCIEASPM */
-void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev);
-void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev);
-#else
-static inline void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev)
-{
-}
-static inline void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev)
-{
-}
-#endif
#endif /* LINUX_ASPM_H */
diff --git a/include/linux/pci-dma-compat.h b/include/linux/pci-dma-compat.h
index d1f9fdade1e0..0dd1a3f7b309 100644
--- a/include/linux/pci-dma-compat.h
+++ b/include/linux/pci-dma-compat.h
@@ -17,91 +17,90 @@ static inline void *
pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle)
{
- return dma_alloc_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, dma_handle, GFP_ATOMIC);
+ return dma_alloc_coherent(&hwdev->dev, size, dma_handle, GFP_ATOMIC);
}
static inline void *
pci_zalloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle)
{
- return dma_zalloc_coherent(hwdev == NULL ? NULL : &hwdev->dev,
- size, dma_handle, GFP_ATOMIC);
+ return dma_zalloc_coherent(&hwdev->dev, size, dma_handle, GFP_ATOMIC);
}
static inline void
pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
- dma_free_coherent(hwdev == NULL ? NULL : &hwdev->dev, size, vaddr, dma_handle);
+ dma_free_coherent(&hwdev->dev, size, vaddr, dma_handle);
}
static inline dma_addr_t
pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
{
- return dma_map_single(hwdev == NULL ? NULL : &hwdev->dev, ptr, size, (enum dma_data_direction)direction);
+ return dma_map_single(&hwdev->dev, ptr, size, (enum dma_data_direction)direction);
}
static inline void
pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr,
size_t size, int direction)
{
- dma_unmap_single(hwdev == NULL ? NULL : &hwdev->dev, dma_addr, size, (enum dma_data_direction)direction);
+ dma_unmap_single(&hwdev->dev, dma_addr, size, (enum dma_data_direction)direction);
}
static inline dma_addr_t
pci_map_page(struct pci_dev *hwdev, struct page *page,
unsigned long offset, size_t size, int direction)
{
- return dma_map_page(hwdev == NULL ? NULL : &hwdev->dev, page, offset, size, (enum dma_data_direction)direction);
+ return dma_map_page(&hwdev->dev, page, offset, size, (enum dma_data_direction)direction);
}
static inline void
pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
size_t size, int direction)
{
- dma_unmap_page(hwdev == NULL ? NULL : &hwdev->dev, dma_address, size, (enum dma_data_direction)direction);
+ dma_unmap_page(&hwdev->dev, dma_address, size, (enum dma_data_direction)direction);
}
static inline int
pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction)
{
- return dma_map_sg(hwdev == NULL ? NULL : &hwdev->dev, sg, nents, (enum dma_data_direction)direction);
+ return dma_map_sg(&hwdev->dev, sg, nents, (enum dma_data_direction)direction);
}
static inline void
pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg,
int nents, int direction)
{
- dma_unmap_sg(hwdev == NULL ? NULL : &hwdev->dev, sg, nents, (enum dma_data_direction)direction);
+ dma_unmap_sg(&hwdev->dev, sg, nents, (enum dma_data_direction)direction);
}
static inline void
pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t dma_handle,
size_t size, int direction)
{
- dma_sync_single_for_cpu(hwdev == NULL ? NULL : &hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
+ dma_sync_single_for_cpu(&hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
}
static inline void
pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t dma_handle,
size_t size, int direction)
{
- dma_sync_single_for_device(hwdev == NULL ? NULL : &hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
+ dma_sync_single_for_device(&hwdev->dev, dma_handle, size, (enum dma_data_direction)direction);
}
static inline void
pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg,
int nelems, int direction)
{
- dma_sync_sg_for_cpu(hwdev == NULL ? NULL : &hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
+ dma_sync_sg_for_cpu(&hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
}
static inline void
pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg,
int nelems, int direction)
{
- dma_sync_sg_for_device(hwdev == NULL ? NULL : &hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
+ dma_sync_sg_for_device(&hwdev->dev, sg, nelems, (enum dma_data_direction)direction);
}
static inline int
diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h
index 809c2f1873ac..baadad1aabbc 100644
--- a/include/linux/pci-ecam.h
+++ b/include/linux/pci-ecam.h
@@ -1,17 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright 2016 Broadcom
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2, as
- * published by the Free Software Foundation (the "GPL").
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License version 2 (GPLv2) for more details.
- *
- * You should have received a copy of the GNU General Public License
- * version 2 (GPLv2) along with this source code.
*/
#ifndef DRIVERS_PCI_ECAM_H
#define DRIVERS_PCI_ECAM_H
diff --git a/include/linux/pci-ep-cfs.h b/include/linux/pci-ep-cfs.h
index 263b89ea5705..f42b0fd4b4bc 100644
--- a/include/linux/pci-ep-cfs.h
+++ b/include/linux/pci-ep-cfs.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/**
* PCI Endpoint ConfigFS header file
*
* Copyright (C) 2017 Texas Instruments
* Author: Kishon Vijay Abraham I <kishon@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.
*/
#ifndef __LINUX_PCI_EP_CFS_H
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index f7a04e1af112..a1a5e5df0f66 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
* PCI Endpoint *Controller* (EPC) header file
*
* Copyright (C) 2017 Texas Instruments
* Author: Kishon Vijay Abraham I <kishon@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.
*/
#ifndef __LINUX_PCI_EPC_H
@@ -39,17 +36,20 @@ enum pci_epc_irq_type {
* @owner: the module owner containing the ops
*/
struct pci_epc_ops {
- int (*write_header)(struct pci_epc *pci_epc,
+ int (*write_header)(struct pci_epc *epc, u8 func_no,
struct pci_epf_header *hdr);
- int (*set_bar)(struct pci_epc *epc, enum pci_barno bar,
+ int (*set_bar)(struct pci_epc *epc, u8 func_no,
+ enum pci_barno bar,
dma_addr_t bar_phys, size_t size, int flags);
- void (*clear_bar)(struct pci_epc *epc, enum pci_barno bar);
- int (*map_addr)(struct pci_epc *epc, phys_addr_t addr,
- u64 pci_addr, size_t size);
- void (*unmap_addr)(struct pci_epc *epc, phys_addr_t addr);
- int (*set_msi)(struct pci_epc *epc, u8 interrupts);
- int (*get_msi)(struct pci_epc *epc);
- int (*raise_irq)(struct pci_epc *pci_epc,
+ void (*clear_bar)(struct pci_epc *epc, u8 func_no,
+ enum pci_barno bar);
+ int (*map_addr)(struct pci_epc *epc, u8 func_no,
+ phys_addr_t addr, u64 pci_addr, size_t size);
+ void (*unmap_addr)(struct pci_epc *epc, u8 func_no,
+ phys_addr_t addr);
+ int (*set_msi)(struct pci_epc *epc, u8 func_no, u8 interrupts);
+ int (*get_msi)(struct pci_epc *epc, u8 func_no);
+ int (*raise_irq)(struct pci_epc *epc, u8 func_no,
enum pci_epc_irq_type type, u8 interrupt_num);
int (*start)(struct pci_epc *epc);
void (*stop)(struct pci_epc *epc);
@@ -124,17 +124,21 @@ void pci_epc_destroy(struct pci_epc *epc);
int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf);
void pci_epc_linkup(struct pci_epc *epc);
void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf);
-int pci_epc_write_header(struct pci_epc *epc, struct pci_epf_header *hdr);
-int pci_epc_set_bar(struct pci_epc *epc, enum pci_barno bar,
+int pci_epc_write_header(struct pci_epc *epc, u8 func_no,
+ struct pci_epf_header *hdr);
+int pci_epc_set_bar(struct pci_epc *epc, u8 func_no,
+ enum pci_barno bar,
dma_addr_t bar_phys, size_t size, int flags);
-void pci_epc_clear_bar(struct pci_epc *epc, int bar);
-int pci_epc_map_addr(struct pci_epc *epc, phys_addr_t phys_addr,
+void pci_epc_clear_bar(struct pci_epc *epc, u8 func_no, int bar);
+int pci_epc_map_addr(struct pci_epc *epc, u8 func_no,
+ phys_addr_t phys_addr,
u64 pci_addr, size_t size);
-void pci_epc_unmap_addr(struct pci_epc *epc, phys_addr_t phys_addr);
-int pci_epc_set_msi(struct pci_epc *epc, u8 interrupts);
-int pci_epc_get_msi(struct pci_epc *epc);
-int pci_epc_raise_irq(struct pci_epc *epc, enum pci_epc_irq_type type,
- u8 interrupt_num);
+void pci_epc_unmap_addr(struct pci_epc *epc, u8 func_no,
+ phys_addr_t phys_addr);
+int pci_epc_set_msi(struct pci_epc *epc, u8 func_no, u8 interrupts);
+int pci_epc_get_msi(struct pci_epc *epc, u8 func_no);
+int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no,
+ enum pci_epc_irq_type type, u8 interrupt_num);
int pci_epc_start(struct pci_epc *epc);
void pci_epc_stop(struct pci_epc *epc);
struct pci_epc *pci_epc_get(const char *epc_name);
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
index 60d551a9a1ba..e897bf076701 100644
--- a/include/linux/pci-epf.h
+++ b/include/linux/pci-epf.h
@@ -1,12 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/**
* PCI Endpoint *Function* (EPF) header file
*
* Copyright (C) 2017 Texas Instruments
* Author: Kishon Vijay Abraham I <kishon@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.
*/
#ifndef __LINUX_PCI_EPF_H
diff --git a/include/linux/pci.h b/include/linux/pci.h
index ad35aac87971..024a1beda008 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -48,17 +48,17 @@
* In the interest of not exposing interfaces to user-space unnecessarily,
* the following kernel-only defines are being added here.
*/
-#define PCI_DEVID(bus, devfn) ((((u16)(bus)) << 8) | (devfn))
+#define PCI_DEVID(bus, devfn) ((((u16)(bus)) << 8) | (devfn))
/* return bus from PCI devid = ((u16)bus_number) << 8) | devfn */
#define PCI_BUS_NUM(x) (((x) >> 8) & 0xff)
/* pci_slot represents a physical slot */
struct pci_slot {
- struct pci_bus *bus; /* The bus this slot is on */
- struct list_head list; /* node in list of slots on this bus */
- struct hotplug_slot *hotplug; /* Hotplug info (migrate over time) */
- unsigned char number; /* PCI_SLOT(pci_dev->devfn) */
- struct kobject kobj;
+ struct pci_bus *bus; /* Bus this slot is on */
+ struct list_head list; /* Node in list of slots */
+ struct hotplug_slot *hotplug; /* Hotplug info (move here) */
+ unsigned char number; /* PCI_SLOT(pci_dev->devfn) */
+ struct kobject kobj;
};
static inline const char *pci_slot_name(const struct pci_slot *slot)
@@ -72,9 +72,7 @@ enum pci_mmap_state {
pci_mmap_mem
};
-/*
- * For PCI devices, the region numbers are assigned this way:
- */
+/* For PCI devices, the region numbers are assigned this way: */
enum {
/* #0-5: standard PCI resources */
PCI_STD_RESOURCES,
@@ -83,23 +81,23 @@ enum {
/* #6: expansion ROM resource */
PCI_ROM_RESOURCE,
- /* device specific resources */
+ /* Device-specific resources */
#ifdef CONFIG_PCI_IOV
PCI_IOV_RESOURCES,
PCI_IOV_RESOURCE_END = PCI_IOV_RESOURCES + PCI_SRIOV_NUM_BARS - 1,
#endif
- /* resources assigned to buses behind the bridge */
+ /* Resources assigned to buses behind the bridge */
#define PCI_BRIDGE_RESOURCE_NUM 4
PCI_BRIDGE_RESOURCES,
PCI_BRIDGE_RESOURCE_END = PCI_BRIDGE_RESOURCES +
PCI_BRIDGE_RESOURCE_NUM - 1,
- /* total resources associated with a PCI device */
+ /* Total resources associated with a PCI device */
PCI_NUM_RESOURCES,
- /* preserve this for compatibility */
+ /* Preserve this for compatibility */
DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES,
};
@@ -152,9 +150,10 @@ static inline const char *pci_power_name(pci_power_t state)
#define PCI_PM_D3COLD_WAIT 100
#define PCI_PM_BUS_WAIT 50
-/** The pci_channel state describes connectivity between the CPU and
- * the pci device. If some PCI bus between here and the pci device
- * has crashed or locked up, this info is reflected here.
+/**
+ * The pci_channel state describes connectivity between the CPU and
+ * the PCI device. If some PCI bus between here and the PCI device
+ * has crashed or locked up, this info is reflected here.
*/
typedef unsigned int __bitwise pci_channel_state_t;
@@ -184,9 +183,7 @@ enum pcie_reset_state {
typedef unsigned short __bitwise pci_dev_flags_t;
enum pci_dev_flags {
- /* INTX_DISABLE in PCI_COMMAND register disables MSI
- * generation too.
- */
+ /* INTX_DISABLE in PCI_COMMAND register disables MSI too */
PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) (1 << 0),
/* Device configuration is irrevocably lost if disabled into D3 */
PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) (1 << 1),
@@ -202,7 +199,7 @@ enum pci_dev_flags {
PCI_DEV_FLAGS_NO_PM_RESET = (__force pci_dev_flags_t) (1 << 7),
/* Get VPD from function 0 VPD */
PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 << 8),
- /* a non-root bridge where translation occurs, stop alias search here */
+ /* A non-root bridge where translation occurs, stop alias search here */
PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT = (__force pci_dev_flags_t) (1 << 9),
/* Do not use FLR even if device advertises PCI_AF_CAP */
PCI_DEV_FLAGS_NO_FLR_RESET = (__force pci_dev_flags_t) (1 << 10),
@@ -222,17 +219,17 @@ enum pci_bus_flags {
PCI_BUS_FLAGS_NO_AERSID = (__force pci_bus_flags_t) 4,
};
-/* These values come from the PCI Express Spec */
+/* Values from Link Status register, PCIe r3.1, sec 7.8.8 */
enum pcie_link_width {
PCIE_LNK_WIDTH_RESRV = 0x00,
PCIE_LNK_X1 = 0x01,
PCIE_LNK_X2 = 0x02,
PCIE_LNK_X4 = 0x04,
PCIE_LNK_X8 = 0x08,
- PCIE_LNK_X12 = 0x0C,
+ PCIE_LNK_X12 = 0x0c,
PCIE_LNK_X16 = 0x10,
PCIE_LNK_X32 = 0x20,
- PCIE_LNK_WIDTH_UNKNOWN = 0xFF,
+ PCIE_LNK_WIDTH_UNKNOWN = 0xff,
};
/* Based on the PCI Hotplug Spec, but some values are made up by us */
@@ -263,15 +260,15 @@ enum pci_bus_speed {
};
struct pci_cap_saved_data {
- u16 cap_nr;
- bool cap_extended;
- unsigned int size;
- u32 data[0];
+ u16 cap_nr;
+ bool cap_extended;
+ unsigned int size;
+ u32 data[0];
};
struct pci_cap_saved_state {
- struct hlist_node next;
- struct pci_cap_saved_data cap;
+ struct hlist_node next;
+ struct pci_cap_saved_data cap;
};
struct irq_affinity;
@@ -280,19 +277,17 @@ struct pci_vpd;
struct pci_sriov;
struct pci_ats;
-/*
- * The pci_dev structure is used to describe PCI devices.
- */
+/* The pci_dev structure describes PCI devices */
struct pci_dev {
- struct list_head bus_list; /* node in per-bus list */
- struct pci_bus *bus; /* bus this device is on */
- struct pci_bus *subordinate; /* bus this device bridges to */
+ struct list_head bus_list; /* Node in per-bus list */
+ struct pci_bus *bus; /* Bus this device is on */
+ struct pci_bus *subordinate; /* Bus this device bridges to */
- void *sysdata; /* hook for sys-specific extension */
- struct proc_dir_entry *procent; /* device entry in /proc/bus/pci */
+ void *sysdata; /* Hook for sys-specific extension */
+ struct proc_dir_entry *procent; /* Device entry in /proc/bus/pci */
struct pci_slot *slot; /* Physical slot this device is in */
- unsigned int devfn; /* encoded device & function index */
+ unsigned int devfn; /* Encoded device & function index */
unsigned short vendor;
unsigned short device;
unsigned short subsystem_vendor;
@@ -307,12 +302,12 @@ struct pci_dev {
u8 msi_cap; /* MSI capability offset */
u8 msix_cap; /* MSI-X capability offset */
u8 pcie_mpss:3; /* PCIe Max Payload Size Supported */
- u8 rom_base_reg; /* which config register controls the ROM */
- u8 pin; /* which interrupt pin this device uses */
- u16 pcie_flags_reg; /* cached PCIe Capabilities Register */
- unsigned long *dma_alias_mask;/* mask of enabled devfn aliases */
+ u8 rom_base_reg; /* Config register controlling ROM */
+ u8 pin; /* Interrupt pin this device uses */
+ u16 pcie_flags_reg; /* Cached PCIe Capabilities Register */
+ unsigned long *dma_alias_mask;/* Mask of enabled devfn aliases */
- struct pci_driver *driver; /* which driver has allocated this device */
+ struct pci_driver *driver; /* Driver bound to this device */
u64 dma_mask; /* Mask of the bits of bus address this
device implements. Normally this is
0xffffffff. You only need to change
@@ -321,9 +316,9 @@ struct pci_dev {
struct device_dma_parameters dma_parms;
- pci_power_t current_state; /* Current operating state. In ACPI-speak,
- this is D0-D3, D0 being fully functional,
- and D3 being off. */
+ pci_power_t current_state; /* Current operating state. In ACPI,
+ this is D0-D3, D0 being fully
+ functional, and D3 being off. */
u8 pm_cap; /* PM capability offset */
unsigned int pme_support:5; /* Bitmask of states from which PME#
can be generated */
@@ -334,10 +329,10 @@ struct pci_dev {
unsigned int no_d3cold:1; /* D3cold is forbidden */
unsigned int bridge_d3:1; /* Allow D3 for bridge */
unsigned int d3cold_allowed:1; /* D3cold is allowed by user */
- unsigned int mmio_always_on:1; /* disallow turning off io/mem
- decoding during bar sizing */
+ unsigned int mmio_always_on:1; /* Disallow turning off io/mem
+ decoding during BAR sizing */
unsigned int wakeup_prepared:1;
- unsigned int runtime_d3cold:1; /* whether go through runtime
+ unsigned int runtime_d3cold:1; /* Whether go through runtime
D3cold, not set for devices
powered on/off by the
corresponding bridge */
@@ -350,12 +345,14 @@ struct pci_dev {
#ifdef CONFIG_PCIEASPM
struct pcie_link_state *link_state; /* ASPM link state */
+ unsigned int ltr_path:1; /* Latency Tolerance Reporting
+ supported from root to here */
#endif
- pci_channel_state_t error_state; /* current connectivity state */
- struct device dev; /* Generic device interface */
+ pci_channel_state_t error_state; /* Current connectivity state */
+ struct device dev; /* Generic device interface */
- int cfg_size; /* Size of configuration space */
+ int cfg_size; /* Size of config space */
/*
* Instead of touching interrupt line and base address registers
@@ -364,47 +361,47 @@ struct pci_dev {
unsigned int irq;
struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
- bool match_driver; /* Skip attaching driver */
- /* These fields are used by common fixups */
- unsigned int transparent:1; /* Subtractive decode PCI bridge */
- unsigned int multifunction:1;/* Part of multi-function device */
- /* keep track of device state */
+ bool match_driver; /* Skip attaching driver */
+
+ unsigned int transparent:1; /* Subtractive decode bridge */
+ unsigned int multifunction:1; /* Multi-function device */
+
unsigned int is_added:1;
- unsigned int is_busmaster:1; /* device is busmaster */
- unsigned int no_msi:1; /* device may not use msi */
- unsigned int no_64bit_msi:1; /* device may only use 32-bit MSIs */
- unsigned int block_cfg_access:1; /* config space access is blocked */
- unsigned int broken_parity_status:1; /* Device generates false positive parity */
- unsigned int irq_reroute_variant:2; /* device needs IRQ rerouting variant */
+ unsigned int is_busmaster:1; /* Is busmaster */
+ unsigned int no_msi:1; /* May not use MSI */
+ unsigned int no_64bit_msi:1; /* May only use 32-bit MSIs */
+ unsigned int block_cfg_access:1; /* Config space access blocked */
+ unsigned int broken_parity_status:1; /* Generates false positive parity */
+ unsigned int irq_reroute_variant:2; /* Needs IRQ rerouting variant */
unsigned int msi_enabled:1;
unsigned int msix_enabled:1;
- unsigned int ari_enabled:1; /* ARI forwarding */
- unsigned int ats_enabled:1; /* Address Translation Service */
+ unsigned int ari_enabled:1; /* ARI forwarding */
+ unsigned int ats_enabled:1; /* Address Translation Svc */
unsigned int pasid_enabled:1; /* Process Address Space ID */
unsigned int pri_enabled:1; /* Page Request Interface */
unsigned int is_managed:1;
- unsigned int needs_freset:1; /* Dev requires fundamental reset */
+ unsigned int needs_freset:1; /* Requires fundamental reset */
unsigned int state_saved:1;
unsigned int is_physfn:1;
unsigned int is_virtfn:1;
unsigned int reset_fn:1;
- unsigned int is_hotplug_bridge:1;
- unsigned int is_thunderbolt:1; /* Thunderbolt controller */
- unsigned int __aer_firmware_first_valid:1;
+ unsigned int is_hotplug_bridge:1;
+ unsigned int is_thunderbolt:1; /* Thunderbolt controller */
+ unsigned int __aer_firmware_first_valid:1;
unsigned int __aer_firmware_first:1;
- unsigned int broken_intx_masking:1; /* INTx masking can't be used */
- unsigned int io_window_1k:1; /* Intel P2P bridge 1K I/O windows */
+ unsigned int broken_intx_masking:1; /* INTx masking can't be used */
+ unsigned int io_window_1k:1; /* Intel bridge 1K I/O windows */
unsigned int irq_managed:1;
unsigned int has_secondary_link:1;
- unsigned int non_compliant_bars:1; /* broken BARs; ignore them */
- unsigned int is_probed:1; /* device probing in progress */
+ unsigned int non_compliant_bars:1; /* Broken BARs; ignore them */
+ unsigned int is_probed:1; /* Device probing in progress */
pci_dev_flags_t dev_flags;
atomic_t enable_cnt; /* pci_enable_device has been called */
- u32 saved_config_space[16]; /* config space saved at suspend time */
+ u32 saved_config_space[16]; /* Config space saved at suspend time */
struct hlist_head saved_cap_space;
- struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
- int rom_attr_enabled; /* has display of the rom attribute been enabled? */
+ struct bin_attribute *rom_attr; /* Attribute descriptor for sysfs ROM entry */
+ int rom_attr_enabled; /* Display of ROM attribute enabled? */
struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
@@ -419,12 +416,12 @@ struct pci_dev {
struct pci_vpd *vpd;
#ifdef CONFIG_PCI_ATS
union {
- struct pci_sriov *sriov; /* SR-IOV capability related */
- struct pci_dev *physfn; /* the PF this VF is associated with */
+ struct pci_sriov *sriov; /* PF: SR-IOV info */
+ struct pci_dev *physfn; /* VF: related PF */
};
u16 ats_cap; /* ATS Capability offset */
u8 ats_stu; /* ATS Smallest Translation Unit */
- atomic_t ats_ref_cnt; /* number of VFs with ATS enabled */
+ atomic_t ats_ref_cnt; /* Number of VFs with ATS enabled */
#endif
#ifdef CONFIG_PCI_PRI
u32 pri_reqs_alloc; /* Number of PRI requests allocated */
@@ -432,11 +429,11 @@ struct pci_dev {
#ifdef CONFIG_PCI_PASID
u16 pasid_features;
#endif
- phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */
- size_t romlen; /* Length of ROM if it's not from the BAR */
- char *driver_override; /* Driver name to force a match */
+ phys_addr_t rom; /* Physical address if not from BAR */
+ size_t romlen; /* Length if not from BAR */
+ char *driver_override; /* Driver name to force a match */
- unsigned long priv_flags; /* Private flags for the pci driver */
+ unsigned long priv_flags; /* Private flags for the PCI driver */
};
static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
@@ -459,26 +456,26 @@ static inline int pci_channel_offline(struct pci_dev *pdev)
}
struct pci_host_bridge {
- struct device dev;
- struct pci_bus *bus; /* root bus */
- struct pci_ops *ops;
- void *sysdata;
- int busnr;
+ struct device dev;
+ struct pci_bus *bus; /* Root bus */
+ struct pci_ops *ops;
+ void *sysdata;
+ int busnr;
struct list_head windows; /* resource_entry */
- u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* platform IRQ swizzler */
+ u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
int (*map_irq)(const struct pci_dev *, u8, u8);
void (*release_fn)(struct pci_host_bridge *);
- void *release_data;
+ void *release_data;
struct msi_controller *msi;
- unsigned int ignore_reset_delay:1; /* for entire hierarchy */
- unsigned int no_ext_tags:1; /* no Extended Tags */
+ unsigned int ignore_reset_delay:1; /* For entire hierarchy */
+ unsigned int no_ext_tags:1; /* No Extended Tags */
/* Resource alignment requirements */
resource_size_t (*align_resource)(struct pci_dev *dev,
const struct resource *res,
resource_size_t start,
resource_size_t size,
resource_size_t align);
- unsigned long private[0] ____cacheline_aligned;
+ unsigned long private[0] ____cacheline_aligned;
};
#define to_pci_host_bridge(n) container_of(n, struct pci_host_bridge, dev)
@@ -500,8 +497,8 @@ void pci_free_host_bridge(struct pci_host_bridge *bridge);
struct pci_host_bridge *pci_find_host_bridge(struct pci_bus *bus);
void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
- void (*release_fn)(struct pci_host_bridge *),
- void *release_data);
+ void (*release_fn)(struct pci_host_bridge *),
+ void *release_data);
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge);
@@ -521,32 +518,32 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge);
#define PCI_SUBTRACTIVE_DECODE 0x1
struct pci_bus_resource {
- struct list_head list;
- struct resource *res;
- unsigned int flags;
+ struct list_head list;
+ struct resource *res;
+ unsigned int flags;
};
#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */
struct pci_bus {
- struct list_head node; /* node in list of buses */
- struct pci_bus *parent; /* parent bus this bridge is on */
- struct list_head children; /* list of child buses */
- struct list_head devices; /* list of devices on this bus */
- struct pci_dev *self; /* bridge device as seen by parent */
- struct list_head slots; /* list of slots on this bus;
+ struct list_head node; /* Node in list of buses */
+ struct pci_bus *parent; /* Parent bus this bridge is on */
+ struct list_head children; /* List of child buses */
+ struct list_head devices; /* List of devices on this bus */
+ struct pci_dev *self; /* Bridge device as seen by parent */
+ struct list_head slots; /* List of slots on this bus;
protected by pci_slot_mutex */
struct resource *resource[PCI_BRIDGE_RESOURCE_NUM];
- struct list_head resources; /* address space routed to this bus */
- struct resource busn_res; /* bus numbers routed to this bus */
+ struct list_head resources; /* Address space routed to this bus */
+ struct resource busn_res; /* Bus numbers routed to this bus */
- struct pci_ops *ops; /* configuration access functions */
+ struct pci_ops *ops; /* Configuration access functions */
struct msi_controller *msi; /* MSI controller */
- void *sysdata; /* hook for sys-specific extension */
- struct proc_dir_entry *procdir; /* directory entry in /proc/bus/pci */
+ void *sysdata; /* Hook for sys-specific extension */
+ struct proc_dir_entry *procdir; /* Directory entry in /proc/bus/pci */
- unsigned char number; /* bus number */
- unsigned char primary; /* number of primary bridge */
+ unsigned char number; /* Bus number */
+ unsigned char primary; /* Number of primary bridge */
unsigned char max_bus_speed; /* enum pci_bus_speed */
unsigned char cur_bus_speed; /* enum pci_bus_speed */
#ifdef CONFIG_PCI_DOMAINS_GENERIC
@@ -555,12 +552,12 @@ struct pci_bus {
char name[48];
- unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */
- pci_bus_flags_t bus_flags; /* inherited by child buses */
+ unsigned short bridge_ctl; /* Manage NO_ISA/FBB/et al behaviors */
+ pci_bus_flags_t bus_flags; /* Inherited by child buses */
struct device *bridge;
struct device dev;
- struct bin_attribute *legacy_io; /* legacy I/O for this bus */
- struct bin_attribute *legacy_mem; /* legacy mem */
+ struct bin_attribute *legacy_io; /* Legacy I/O for this bus */
+ struct bin_attribute *legacy_mem; /* Legacy mem */
unsigned int is_added:1;
};
@@ -617,9 +614,7 @@ static inline bool pci_dev_msi_enabled(struct pci_dev *pci_dev)
static inline bool pci_dev_msi_enabled(struct pci_dev *pci_dev) { return false; }
#endif
-/*
- * Error values that may be returned by PCI functions.
- */
+/* Error values that may be returned by PCI functions */
#define PCIBIOS_SUCCESSFUL 0x00
#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81
#define PCIBIOS_BAD_VENDOR_ID 0x83
@@ -628,9 +623,7 @@ static inline bool pci_dev_msi_enabled(struct pci_dev *pci_dev) { return false;
#define PCIBIOS_SET_FAILED 0x88
#define PCIBIOS_BUFFER_TOO_SMALL 0x89
-/*
- * Translate above to generic errno for passing back through non-PCI code.
- */
+/* Translate above to generic errno for passing back through non-PCI code */
static inline int pcibios_err_to_errno(int err)
{
if (err <= PCIBIOS_SUCCESSFUL)
@@ -680,13 +673,13 @@ typedef u32 pci_bus_addr_t;
#endif
struct pci_bus_region {
- pci_bus_addr_t start;
- pci_bus_addr_t end;
+ pci_bus_addr_t start;
+ pci_bus_addr_t end;
};
struct pci_dynids {
- spinlock_t lock; /* protects list, index */
- struct list_head list; /* for IDs added at runtime */
+ spinlock_t lock; /* Protects list, index */
+ struct list_head list; /* For IDs added at runtime */
};
@@ -700,13 +693,13 @@ struct pci_dynids {
typedef unsigned int __bitwise pci_ers_result_t;
enum pci_ers_result {
- /* no result/none/not supported in device driver */
+ /* No result/none/not supported in device driver */
PCI_ERS_RESULT_NONE = (__force pci_ers_result_t) 1,
/* Device driver can recover without slot reset */
PCI_ERS_RESULT_CAN_RECOVER = (__force pci_ers_result_t) 2,
- /* Device driver wants slot to be reset. */
+ /* Device driver wants slot to be reset */
PCI_ERS_RESULT_NEED_RESET = (__force pci_ers_result_t) 3,
/* Device has completely failed, is unrecoverable */
@@ -742,27 +735,27 @@ struct pci_error_handlers {
struct module;
struct pci_driver {
- struct list_head node;
- const char *name;
- const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */
- int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
- void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
- int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */
- int (*suspend_late) (struct pci_dev *dev, pm_message_t state);
- int (*resume_early) (struct pci_dev *dev);
- int (*resume) (struct pci_dev *dev); /* Device woken up */
+ struct list_head node;
+ const char *name;
+ const struct pci_device_id *id_table; /* Must be non-NULL for probe to be called */
+ int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
+ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
+ int (*suspend)(struct pci_dev *dev, pm_message_t state); /* Device suspended */
+ int (*suspend_late)(struct pci_dev *dev, pm_message_t state);
+ int (*resume_early)(struct pci_dev *dev);
+ int (*resume) (struct pci_dev *dev); /* Device woken up */
void (*shutdown) (struct pci_dev *dev);
- int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */
+ int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* On PF */
const struct pci_error_handlers *err_handler;
const struct attribute_group **groups;
struct device_driver driver;
- struct pci_dynids dynids;
+ struct pci_dynids dynids;
};
#define to_pci_driver(drv) container_of(drv, struct pci_driver, driver)
/**
- * PCI_DEVICE - macro used to describe a specific pci device
+ * PCI_DEVICE - macro used to describe a specific PCI device
* @vend: the 16 bit PCI Vendor ID
* @dev: the 16 bit PCI Device ID
*
@@ -775,7 +768,7 @@ struct pci_driver {
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
/**
- * PCI_DEVICE_SUB - macro used to describe a specific pci device with subsystem
+ * PCI_DEVICE_SUB - macro used to describe a specific PCI device with subsystem
* @vend: the 16 bit PCI Vendor ID
* @dev: the 16 bit PCI Device ID
* @subvend: the 16 bit PCI Subvendor ID
@@ -789,7 +782,7 @@ struct pci_driver {
.subvendor = (subvend), .subdevice = (subdev)
/**
- * PCI_DEVICE_CLASS - macro used to describe a specific pci device class
+ * PCI_DEVICE_CLASS - macro used to describe a specific PCI device class
* @dev_class: the class, subclass, prog-if triple for this device
* @dev_class_mask: the class mask for this device
*
@@ -803,7 +796,7 @@ struct pci_driver {
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
/**
- * PCI_VDEVICE - macro used to describe a specific pci device in short form
+ * PCI_VDEVICE - macro used to describe a specific PCI device in short form
* @vend: the vendor name
* @dev: the 16 bit PCI Device ID
*
@@ -812,22 +805,21 @@ struct pci_driver {
* to PCI_ANY_ID. The macro allows the next field to follow as the device
* private data.
*/
-
#define PCI_VDEVICE(vend, dev) \
.vendor = PCI_VENDOR_ID_##vend, .device = (dev), \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0
enum {
- PCI_REASSIGN_ALL_RSRC = 0x00000001, /* ignore firmware setup */
- PCI_REASSIGN_ALL_BUS = 0x00000002, /* reassign all bus numbers */
- PCI_PROBE_ONLY = 0x00000004, /* use existing setup */
- PCI_CAN_SKIP_ISA_ALIGN = 0x00000008, /* don't do ISA alignment */
- PCI_ENABLE_PROC_DOMAINS = 0x00000010, /* enable domains in /proc */
+ PCI_REASSIGN_ALL_RSRC = 0x00000001, /* Ignore firmware setup */
+ PCI_REASSIGN_ALL_BUS = 0x00000002, /* Reassign all bus numbers */
+ PCI_PROBE_ONLY = 0x00000004, /* Use existing setup */
+ PCI_CAN_SKIP_ISA_ALIGN = 0x00000008, /* Don't do ISA alignment */
+ PCI_ENABLE_PROC_DOMAINS = 0x00000010, /* Enable domains in /proc */
PCI_COMPAT_DOMAIN_0 = 0x00000020, /* ... except domain 0 */
- PCI_SCAN_ALL_PCIE_DEVS = 0x00000040, /* scan all, not just dev 0 */
+ PCI_SCAN_ALL_PCIE_DEVS = 0x00000040, /* Scan all, not just dev 0 */
};
-/* these external functions are only available when PCI support is enabled */
+/* These external functions are only available when PCI support is enabled */
#ifdef CONFIG_PCI
extern unsigned int pci_flags;
@@ -840,11 +832,11 @@ static inline int pci_has_flag(int flag) { return pci_flags & flag; }
void pcie_bus_configure_settings(struct pci_bus *bus);
enum pcie_bus_config_types {
- PCIE_BUS_TUNE_OFF, /* don't touch MPS at all */
- PCIE_BUS_DEFAULT, /* ensure MPS matches upstream bridge */
- PCIE_BUS_SAFE, /* use largest MPS boot-time devices support */
- PCIE_BUS_PERFORMANCE, /* use MPS and MRRS for best performance */
- PCIE_BUS_PEER2PEER, /* set MPS = 128 for all devices */
+ PCIE_BUS_TUNE_OFF, /* Don't touch MPS at all */
+ PCIE_BUS_DEFAULT, /* Ensure MPS matches upstream bridge */
+ PCIE_BUS_SAFE, /* Use largest MPS boot-time devices support */
+ PCIE_BUS_PERFORMANCE, /* Use MPS and MRRS for best performance */
+ PCIE_BUS_PEER2PEER, /* Set MPS = 128 for all devices */
};
extern enum pcie_bus_config_types pcie_bus_config;
@@ -853,7 +845,7 @@ extern struct bus_type pci_bus_type;
/* Do NOT directly access these two variables, unless you are arch-specific PCI
* code, or PCI core code. */
-extern struct list_head pci_root_buses; /* list of all known PCI buses */
+extern struct list_head pci_root_buses; /* List of all known PCI buses */
/* Some device drivers need know if PCI is initiated */
int no_pci_devices(void);
@@ -887,12 +879,13 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
struct pci_ops *ops, void *sysdata,
struct list_head *resources);
+int pci_host_probe(struct pci_host_bridge *bridge);
int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
void pci_bus_release_busn_res(struct pci_bus *b);
struct pci_bus *pci_scan_root_bus(struct device *parent, int bus,
- struct pci_ops *ops, void *sysdata,
- struct list_head *resources);
+ struct pci_ops *ops, void *sysdata,
+ struct list_head *resources);
int pci_scan_root_bus_bridge(struct pci_host_bridge *bridge);
struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev,
int busnr);
@@ -949,10 +942,10 @@ int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap);
struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
- struct pci_dev *from);
+ struct pci_dev *from);
struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
- unsigned int ss_vendor, unsigned int ss_device,
- struct pci_dev *from);
+ unsigned int ss_vendor, unsigned int ss_device,
+ struct pci_dev *from);
struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn);
struct pci_dev *pci_get_domain_bus_and_slot(int domain, unsigned int bus,
unsigned int devfn);
@@ -1028,7 +1021,7 @@ static inline int pcie_capability_clear_dword(struct pci_dev *dev, int pos,
return pcie_capability_clear_and_set_dword(dev, pos, clear, 0);
}
-/* user-space driven config access */
+/* User-space driven config access */
int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val);
int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val);
int pci_user_read_config_dword(struct pci_dev *dev, int where, u32 *val);
@@ -1171,7 +1164,7 @@ unsigned int pci_rescan_bus(struct pci_bus *bus);
void pci_lock_rescan_remove(void);
void pci_unlock_rescan_remove(void);
-/* Vital product data routines */
+/* Vital Product Data routines */
ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);
ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void *buf);
int pci_set_vpd_size(struct pci_dev *dev, size_t len);
@@ -1256,9 +1249,7 @@ static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar)
int __must_check __pci_register_driver(struct pci_driver *, struct module *,
const char *mod_name);
-/*
- * pci_register_driver must be a macro so that KBUILD_MODNAME can be expanded
- */
+/* pci_register_driver() must be a macro so KBUILD_MODNAME can be expanded */
#define pci_register_driver(driver) \
__pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)
@@ -1273,8 +1264,7 @@ void pci_unregister_driver(struct pci_driver *dev);
* use this macro once, and calling it replaces module_init() and module_exit()
*/
#define module_pci_driver(__pci_driver) \
- module_driver(__pci_driver, pci_register_driver, \
- pci_unregister_driver)
+ module_driver(__pci_driver, pci_register_driver, pci_unregister_driver)
/**
* builtin_pci_driver() - Helper macro for registering a PCI driver
@@ -1313,10 +1303,10 @@ resource_size_t pcibios_iov_resource_alignment(struct pci_dev *dev, int resno);
int pci_set_vga_state(struct pci_dev *pdev, bool decode,
unsigned int command_bits, u32 flags);
-#define PCI_IRQ_LEGACY (1 << 0) /* allow legacy interrupts */
-#define PCI_IRQ_MSI (1 << 1) /* allow MSI interrupts */
-#define PCI_IRQ_MSIX (1 << 2) /* allow MSI-X interrupts */
-#define PCI_IRQ_AFFINITY (1 << 3) /* auto-assign affinity */
+#define PCI_IRQ_LEGACY (1 << 0) /* Allow legacy interrupts */
+#define PCI_IRQ_MSI (1 << 1) /* Allow MSI interrupts */
+#define PCI_IRQ_MSIX (1 << 2) /* Allow MSI-X interrupts */
+#define PCI_IRQ_AFFINITY (1 << 3) /* Auto-assign affinity */
#define PCI_IRQ_ALL_TYPES \
(PCI_IRQ_LEGACY | PCI_IRQ_MSI | PCI_IRQ_MSIX)
@@ -1335,8 +1325,8 @@ int pci_set_vga_state(struct pci_dev *pdev, bool decode,
#define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr)
struct msix_entry {
- u32 vector; /* kernel uses to write allocated vector */
- u16 entry; /* driver uses to specify entry, OS writes */
+ u32 vector; /* Kernel uses to write allocated vector */
+ u16 entry; /* Driver uses to specify entry, OS writes */
};
#ifdef CONFIG_PCI_MSI
@@ -1376,10 +1366,10 @@ static inline int pci_msi_enabled(void) { return 0; }
static inline int pci_enable_msi(struct pci_dev *dev)
{ return -ENOSYS; }
static inline int pci_enable_msix_range(struct pci_dev *dev,
- struct msix_entry *entries, int minvec, int maxvec)
+ struct msix_entry *entries, int minvec, int maxvec)
{ return -ENOSYS; }
static inline int pci_enable_msix_exact(struct pci_dev *dev,
- struct msix_entry *entries, int nvec)
+ struct msix_entry *entries, int nvec)
{ return -ENOSYS; }
static inline int
@@ -1544,9 +1534,9 @@ static inline int acpi_pci_bus_find_domain_nr(struct pci_bus *bus)
int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent);
#endif
-/* some architectures require additional setup to direct VGA traffic */
+/* Some architectures require additional setup to direct VGA traffic */
typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,
- unsigned int command_bits, u32 flags);
+ unsigned int command_bits, u32 flags);
void pci_register_set_vga_state(arch_set_vga_state_t func);
static inline int
@@ -1585,10 +1575,9 @@ static inline void pci_clear_flags(int flags) { }
static inline int pci_has_flag(int flag) { return 0; }
/*
- * If the system does not have PCI, clearly these return errors. Define
- * these as simple inline functions to avoid hair in drivers.
+ * If the system does not have PCI, clearly these return errors. Define
+ * these as simple inline functions to avoid hair in drivers.
*/
-
#define _PCI_NOP(o, s, t) \
static inline int pci_##o##_config_##s(struct pci_dev *dev, \
int where, t val) \
@@ -1687,6 +1676,13 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
#define dev_is_pf(d) (false)
static inline bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags)
{ return false; }
+static inline int pci_irqd_intx_xlate(struct irq_domain *d,
+ struct device_node *node,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{ return -EINVAL; }
#endif /* CONFIG_PCI */
/* Include architecture-dependent settings and functions */
@@ -1727,8 +1723,10 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma);
#define pci_root_bus_fwnode(bus) NULL
#endif
-/* these helpers provide future and backwards compatibility
- * for accessing popular PCI BAR info */
+/*
+ * These helpers provide future and backwards compatibility
+ * for accessing popular PCI BAR info
+ */
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
#define pci_resource_end(dev, bar) ((dev)->resource[(bar)].end)
#define pci_resource_flags(dev, bar) ((dev)->resource[(bar)].flags)
@@ -1740,7 +1738,8 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma);
(pci_resource_end((dev), (bar)) - \
pci_resource_start((dev), (bar)) + 1))
-/* Similar to the helpers above, these manipulate per-pci_dev
+/*
+ * Similar to the helpers above, these manipulate per-pci_dev
* driver-specific data. They are really just a wrapper around
* the generic device structure functions of these calls.
*/
@@ -1754,16 +1753,14 @@ static inline void pci_set_drvdata(struct pci_dev *pdev, void *data)
dev_set_drvdata(&pdev->dev, data);
}
-/* If you want to know what to call your pci_dev, ask this function.
- * Again, it's a wrapper around the generic device.
- */
static inline const char *pci_name(const struct pci_dev *pdev)
{
return dev_name(&pdev->dev);
}
-/* Some archs don't want to expose struct resource to userland as-is
+/*
+ * Some archs don't want to expose struct resource to userland as-is
* in sysfs and /proc
*/
#ifdef HAVE_ARCH_PCI_RESOURCE_TO_USER
@@ -1782,16 +1779,16 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar,
/*
- * The world is not perfect and supplies us with broken PCI devices.
- * For at least a part of these bugs we need a work-around, so both
- * generic (drivers/pci/quirks.c) and per-architecture code can define
- * fixup hooks to be called for particular buggy devices.
+ * The world is not perfect and supplies us with broken PCI devices.
+ * For at least a part of these bugs we need a work-around, so both
+ * generic (drivers/pci/quirks.c) and per-architecture code can define
+ * fixup hooks to be called for particular buggy devices.
*/
struct pci_fixup {
- u16 vendor; /* You can use PCI_ANY_ID here of course */
- u16 device; /* You can use PCI_ANY_ID here of course */
- u32 class; /* You can use PCI_ANY_ID here too */
+ u16 vendor; /* Or PCI_ANY_ID */
+ u16 device; /* Or PCI_ANY_ID */
+ u32 class; /* Or PCI_ANY_ID */
unsigned int class_shift; /* should be 0, 8, 16 */
void (*hook)(struct pci_dev *dev);
};
@@ -1833,23 +1830,19 @@ enum pci_fixup_pass {
#define DECLARE_PCI_FIXUP_CLASS_RESUME(vendor, device, class, \
class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \
- resume##hook, vendor, device, class, \
- class_shift, hook)
+ resume##hook, vendor, device, class, class_shift, hook)
#define DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(vendor, device, class, \
class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \
- resume_early##hook, vendor, device, \
- class, class_shift, hook)
+ resume_early##hook, vendor, device, class, class_shift, hook)
#define DECLARE_PCI_FIXUP_CLASS_SUSPEND(vendor, device, class, \
class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \
- suspend##hook, vendor, device, class, \
- class_shift, hook)
+ suspend##hook, vendor, device, class, class_shift, hook)
#define DECLARE_PCI_FIXUP_CLASS_SUSPEND_LATE(vendor, device, class, \
class_shift, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend_late, \
- suspend_late##hook, vendor, device, \
- class, class_shift, hook)
+ suspend_late##hook, vendor, device, class, class_shift, hook)
#define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \
@@ -1865,20 +1858,16 @@ enum pci_fixup_pass {
hook, vendor, device, PCI_ANY_ID, 0, hook)
#define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \
- resume##hook, vendor, device, \
- PCI_ANY_ID, 0, hook)
+ resume##hook, vendor, device, PCI_ANY_ID, 0, hook)
#define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \
- resume_early##hook, vendor, device, \
- PCI_ANY_ID, 0, hook)
+ resume_early##hook, vendor, device, PCI_ANY_ID, 0, hook)
#define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \
- suspend##hook, vendor, device, \
- PCI_ANY_ID, 0, hook)
+ suspend##hook, vendor, device, PCI_ANY_ID, 0, hook)
#define DECLARE_PCI_FIXUP_SUSPEND_LATE(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend_late, \
- suspend_late##hook, vendor, device, \
- PCI_ANY_ID, 0, hook)
+ suspend_late##hook, vendor, device, PCI_ANY_ID, 0, hook)
#ifdef CONFIG_PCI_QUIRKS
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
@@ -2064,6 +2053,7 @@ void pci_request_acs(void);
bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
bool pci_acs_path_enabled(struct pci_dev *start,
struct pci_dev *end, u16 acs_flags);
+int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask);
#define PCI_VPD_LRDT 0x80 /* Large Resource Data Type */
#define PCI_VPD_LRDT_ID(x) ((x) | PCI_VPD_LRDT)
@@ -2115,7 +2105,7 @@ static inline u16 pci_vpd_lrdt_size(const u8 *lrdt)
*/
static inline u16 pci_vpd_lrdt_tag(const u8 *lrdt)
{
- return (u16)(lrdt[0] & PCI_VPD_LRDT_TIN_MASK);
+ return (u16)(lrdt[0] & PCI_VPD_LRDT_TIN_MASK);
}
/**
@@ -2185,6 +2175,9 @@ void pci_release_of_node(struct pci_dev *dev);
void pci_set_bus_of_node(struct pci_bus *bus);
void pci_release_bus_of_node(struct pci_bus *bus);
struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus);
+int pci_parse_request_of_pci_ranges(struct device *dev,
+ struct list_head *resources,
+ struct resource **bus_range);
/* Arch may override this (weak) */
struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus);
@@ -2200,7 +2193,7 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
return bus ? bus->dev.of_node : NULL;
}
-#else /* CONFIG_OF */
+#else /* CONFIG_OF */
static inline void pci_set_of_node(struct pci_dev *dev) { }
static inline void pci_release_of_node(struct pci_dev *dev) { }
static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
@@ -2209,6 +2202,12 @@ static inline struct device_node *
pci_device_to_OF_node(const struct pci_dev *pdev) { return NULL; }
static inline struct irq_domain *
pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
+static inline int pci_parse_request_of_pci_ranges(struct device *dev,
+ struct list_head *resources,
+ struct resource **bus_range)
+{
+ return -EINVAL;
+}
#endif /* CONFIG_OF */
#ifdef CONFIG_ACPI
@@ -2234,7 +2233,7 @@ int pci_for_each_dma_alias(struct pci_dev *pdev,
int (*fn)(struct pci_dev *pdev,
u16 alias, void *data), void *data);
-/* helper functions for operation of device flag */
+/* Helper functions for operation of device flag */
static inline void pci_set_dev_assigned(struct pci_dev *pdev)
{
pdev->dev_flags |= PCI_DEV_FLAGS_ASSIGNED;
@@ -2317,7 +2316,19 @@ static inline void pci_uevent_ers(struct pci_dev *pdev,
}
}
-/* provide the legacy pci_dma_* API */
+/* Provide the legacy pci_dma_* API */
#include <linux/pci-dma-compat.h>
+#define pci_printk(level, pdev, fmt, arg...) \
+ dev_printk(level, &(pdev)->dev, fmt, ##arg)
+
+#define pci_emerg(pdev, fmt, arg...) dev_emerg(&(pdev)->dev, fmt, ##arg)
+#define pci_alert(pdev, fmt, arg...) dev_alert(&(pdev)->dev, fmt, ##arg)
+#define pci_crit(pdev, fmt, arg...) dev_crit(&(pdev)->dev, fmt, ##arg)
+#define pci_err(pdev, fmt, arg...) dev_err(&(pdev)->dev, fmt, ##arg)
+#define pci_warn(pdev, fmt, arg...) dev_warn(&(pdev)->dev, fmt, ##arg)
+#define pci_notice(pdev, fmt, arg...) dev_notice(&(pdev)->dev, fmt, ##arg)
+#define pci_info(pdev, fmt, arg...) dev_info(&(pdev)->dev, fmt, ##arg)
+#define pci_dbg(pdev, fmt, arg...) dev_dbg(&(pdev)->dev, fmt, ##arg)
+
#endif /* LINUX_PCI_H */
diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h
index 2e855afa0212..26213024e81b 100644
--- a/include/linux/pci_hotplug.h
+++ b/include/linux/pci_hotplug.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
/*
* PCI HotPlug Core Functions
*
@@ -7,21 +8,6 @@
*
* 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, GOOD TITLE or
- * NON INFRINGEMENT. See the GNU 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.
- *
* Send feedback to <kristen.c.accardi@intel.com>
*
*/
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index ab20dc5db423..eb13e84e1fef 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2381,6 +2381,8 @@
#define PCI_VENDOR_ID_LENOVO 0x17aa
+#define PCI_VENDOR_ID_CDNS 0x17cd
+
#define PCI_VENDOR_ID_ARECA 0x17d3
#define PCI_DEVICE_ID_ARECA_1110 0x1110
#define PCI_DEVICE_ID_ARECA_1120 0x1120
diff --git a/include/linux/pfn_t.h b/include/linux/pfn_t.h
index 43b1d7648e82..a03c2642a87c 100644
--- a/include/linux/pfn_t.h
+++ b/include/linux/pfn_t.h
@@ -15,8 +15,10 @@
#define PFN_SG_LAST (1ULL << (BITS_PER_LONG_LONG - 2))
#define PFN_DEV (1ULL << (BITS_PER_LONG_LONG - 3))
#define PFN_MAP (1ULL << (BITS_PER_LONG_LONG - 4))
+#define PFN_SPECIAL (1ULL << (BITS_PER_LONG_LONG - 5))
#define PFN_FLAGS_TRACE \
+ { PFN_SPECIAL, "SPECIAL" }, \
{ PFN_SG_CHAIN, "SG_CHAIN" }, \
{ PFN_SG_LAST, "SG_LAST" }, \
{ PFN_DEV, "DEV" }, \
@@ -120,4 +122,15 @@ pud_t pud_mkdevmap(pud_t pud);
#endif
#endif /* __HAVE_ARCH_PTE_DEVMAP */
+#ifdef __HAVE_ARCH_PTE_SPECIAL
+static inline bool pfn_t_special(pfn_t pfn)
+{
+ return (pfn.val & PFN_SPECIAL) == PFN_SPECIAL;
+}
+#else
+static inline bool pfn_t_special(pfn_t pfn)
+{
+ return false;
+}
+#endif /* __HAVE_ARCH_PTE_SPECIAL */
#endif /* _LINUX_PFN_T_H_ */
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 2dc5e9870fcd..5a3bb3b7c9ad 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -167,10 +167,9 @@ void pipe_lock(struct pipe_inode_info *);
void pipe_unlock(struct pipe_inode_info *);
void pipe_double_lock(struct pipe_inode_info *, struct pipe_inode_info *);
-extern unsigned int pipe_max_size, pipe_min_size;
+extern unsigned int pipe_max_size;
extern unsigned long pipe_user_pages_hard;
extern unsigned long pipe_user_pages_soft;
-int pipe_proc_fn(struct ctl_table *, int, void __user *, size_t *, loff_t *);
/* Drop the inode semaphore and wait for a pipe event, atomically */
void pipe_wait(struct pipe_inode_info *pipe);
@@ -191,6 +190,6 @@ long pipe_fcntl(struct file *, unsigned int, unsigned long arg);
struct pipe_inode_info *get_pipe_info(struct file *file);
int create_pipe_files(struct file **, int);
-unsigned int round_pipe_size(unsigned int size);
+unsigned int round_pipe_size(unsigned long size);
#endif
diff --git a/include/linux/platform_data/mlxcpld-hotplug.h b/include/linux/platform_data/mlxcpld-hotplug.h
deleted file mode 100644
index e4cfcffaa6f4..000000000000
--- a/include/linux/platform_data/mlxcpld-hotplug.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * include/linux/platform_data/mlxcpld-hotplug.h
- * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
- * Copyright (c) 2016 Vadim Pasternak <vadimp@mellanox.com>
- *
- * 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 names of the copyright holders 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") version 2 as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H
-#define __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H
-
-/**
- * struct mlxcpld_hotplug_device - I2C device data:
- * @adapter: I2C device adapter;
- * @client: I2C device client;
- * @brdinfo: device board information;
- * @bus: I2C bus, where device is attached;
- *
- * Structure represents I2C hotplug device static data (board topology) and
- * dynamic data (related kernel objects handles).
- */
-struct mlxcpld_hotplug_device {
- struct i2c_adapter *adapter;
- struct i2c_client *client;
- struct i2c_board_info brdinfo;
- u16 bus;
-};
-
-/**
- * struct mlxcpld_hotplug_platform_data - device platform data:
- * @top_aggr_offset: offset of top aggregation interrupt register;
- * @top_aggr_mask: top aggregation interrupt common mask;
- * @top_aggr_psu_mask: top aggregation interrupt PSU mask;
- * @psu_reg_offset: offset of PSU interrupt register;
- * @psu_mask: PSU interrupt mask;
- * @psu_count: number of equipped replaceable PSUs;
- * @psu: pointer to PSU devices data array;
- * @top_aggr_pwr_mask: top aggregation interrupt power mask;
- * @pwr_reg_offset: offset of power interrupt register
- * @pwr_mask: power interrupt mask;
- * @pwr_count: number of power sources;
- * @pwr: pointer to power devices data array;
- * @top_aggr_fan_mask: top aggregation interrupt FAN mask;
- * @fan_reg_offset: offset of FAN interrupt register;
- * @fan_mask: FAN interrupt mask;
- * @fan_count: number of equipped replaceable FANs;
- * @fan: pointer to FAN devices data array;
- *
- * Structure represents board platform data, related to system hotplug events,
- * like FAN, PSU, power cable insertion and removing. This data provides the
- * number of hot-pluggable devices and hardware description for event handling.
- */
-struct mlxcpld_hotplug_platform_data {
- u16 top_aggr_offset;
- u8 top_aggr_mask;
- u8 top_aggr_psu_mask;
- u16 psu_reg_offset;
- u8 psu_mask;
- u8 psu_count;
- struct mlxcpld_hotplug_device *psu;
- u8 top_aggr_pwr_mask;
- u16 pwr_reg_offset;
- u8 pwr_mask;
- u8 pwr_count;
- struct mlxcpld_hotplug_device *pwr;
- u8 top_aggr_fan_mask;
- u16 fan_reg_offset;
- u8 fan_mask;
- u8 fan_count;
- struct mlxcpld_hotplug_device *fan;
-};
-
-#endif /* __LINUX_PLATFORM_DATA_MLXCPLD_HOTPLUG_H */
diff --git a/include/linux/platform_data/mlxreg.h b/include/linux/platform_data/mlxreg.h
new file mode 100644
index 000000000000..fcdc707eab99
--- /dev/null
+++ b/include/linux/platform_data/mlxreg.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2017 Vadim Pasternak <vadimp@mellanox.com>
+ *
+ * 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 names of the copyright holders 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") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_MLXREG_H
+#define __LINUX_PLATFORM_DATA_MLXREG_H
+
+#define MLXREG_CORE_LABEL_MAX_SIZE 32
+
+/**
+ * struct mlxreg_hotplug_device - I2C device data:
+ *
+ * @adapter: I2C device adapter;
+ * @client: I2C device client;
+ * @brdinfo: device board information;
+ * @nr: I2C device adapter number, to which device is to be attached;
+ *
+ * Structure represents I2C hotplug device static data (board topology) and
+ * dynamic data (related kernel objects handles).
+ */
+struct mlxreg_hotplug_device {
+ struct i2c_adapter *adapter;
+ struct i2c_client *client;
+ struct i2c_board_info *brdinfo;
+ int nr;
+};
+
+/**
+ * struct mlxreg_core_data - attributes control data:
+ *
+ * @label: attribute label;
+ * @label: attribute register offset;
+ * @reg: attribute register;
+ * @mask: attribute access mask;
+ * @mode: access mode;
+ * @bit: attribute effective bit;
+ * @np - pointer to node platform associated with attribute;
+ * @hpdev - hotplug device data;
+ * @health_cntr: dynamic device health indication counter;
+ * @attached: true if device has been attached after good health indication;
+ */
+struct mlxreg_core_data {
+ char label[MLXREG_CORE_LABEL_MAX_SIZE];
+ u32 reg;
+ u32 mask;
+ u32 bit;
+ umode_t mode;
+ struct device_node *np;
+ struct mlxreg_hotplug_device hpdev;
+ u8 health_cntr;
+ bool attached;
+};
+
+/**
+ * struct mlxreg_core_item - same type components controlled by the driver:
+ *
+ * @data: component data;
+ * @aggr_mask: group aggregation mask;
+ * @reg: group interrupt status register;
+ * @mask: group interrupt mask;
+ * @cache: last status value for elements fro the same group;
+ * @count: number of available elements in the group;
+ * @ind: element's index inside the group;
+ * @inversed: if 0: 0 for signal status is OK, if 1 - 1 is OK;
+ * @health: true if device has health indication, false in other case;
+ */
+struct mlxreg_core_item {
+ struct mlxreg_core_data *data;
+ u32 aggr_mask;
+ u32 reg;
+ u32 mask;
+ u32 cache;
+ u8 count;
+ u8 ind;
+ u8 inversed;
+ u8 health;
+};
+
+/**
+ * struct mlxreg_core_platform_data - platform data:
+ *
+ * @led_data: led private data;
+ * @regmap: register map of parent device;
+ * @counter: number of led instances;
+ */
+struct mlxreg_core_platform_data {
+ struct mlxreg_core_data *data;
+ void *regmap;
+ int counter;
+};
+
+/**
+ * struct mlxreg_core_hotplug_platform_data - hotplug platform data:
+ *
+ * @items: same type components with the hotplug capability;
+ * @irq: platform interrupt number;
+ * @regmap: register map of parent device;
+ * @counter: number of the components with the hotplug capability;
+ * @cell: location of top aggregation interrupt register;
+ * @mask: top aggregation interrupt common mask;
+ * @cell_low: location of low aggregation interrupt register;
+ * @mask_low: low aggregation interrupt common mask;
+ */
+struct mlxreg_core_hotplug_platform_data {
+ struct mlxreg_core_item *items;
+ int irq;
+ void *regmap;
+ int counter;
+ u32 cell;
+ u32 mask;
+ u32 cell_low;
+ u32 mask_low;
+};
+
+#endif /* __LINUX_PLATFORM_DATA_MLXREG_H */
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index 44e630eb3d94..728d421fffe9 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -324,6 +324,7 @@ struct rproc_mem_entry {
};
struct rproc;
+struct firmware;
/**
* struct rproc_ops - platform-specific device handlers
@@ -331,12 +332,24 @@ struct rproc;
* @stop: power off the device
* @kick: kick a virtqueue (virtqueue id given as a parameter)
* @da_to_va: optional platform hook to perform address translations
+ * @load_rsc_table: load resource table from firmware image
+ * @find_loaded_rsc_table: find the loaded resouce table
+ * @load: load firmeware to memory, where the remote processor
+ * expects to find it
+ * @sanity_check: sanity check the fw image
+ * @get_boot_addr: get boot address to entry point specified in firmware
*/
struct rproc_ops {
int (*start)(struct rproc *rproc);
int (*stop)(struct rproc *rproc);
void (*kick)(struct rproc *rproc, int vqid);
void * (*da_to_va)(struct rproc *rproc, u64 da, int len);
+ int (*load_rsc_table)(struct rproc *rproc, const struct firmware *fw);
+ struct resource_table *(*find_loaded_rsc_table)(
+ struct rproc *rproc, const struct firmware *fw);
+ int (*load)(struct rproc *rproc, const struct firmware *fw);
+ int (*sanity_check)(struct rproc *rproc, const struct firmware *fw);
+ u32 (*get_boot_addr)(struct rproc *rproc, const struct firmware *fw);
};
/**
@@ -390,7 +403,6 @@ enum rproc_crash_type {
* @priv: private data which belongs to the platform-specific rproc module
* @ops: platform-specific start/stop rproc handlers
* @dev: virtual device for refcounting and common remoteproc behavior
- * @fw_ops: firmware-specific handlers
* @power: refcount of users who need this rproc powered up
* @state: state of the device
* @lock: lock which protects concurrent manipulations of the rproc
@@ -406,11 +418,11 @@ enum rproc_crash_type {
* @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.
* @table_ptr: pointer to the resource table in effect
* @cached_table: copy of the resource table
+ * @table_sz: size of @cached_table
* @has_iommu: flag to indicate if remote processor is behind an MMU
*/
struct rproc {
@@ -419,9 +431,8 @@ struct rproc {
const char *name;
char *firmware;
void *priv;
- const struct rproc_ops *ops;
+ struct rproc_ops *ops;
struct device dev;
- const struct rproc_fw_ops *fw_ops;
atomic_t power;
unsigned int state;
struct mutex lock;
@@ -437,11 +448,11 @@ struct rproc {
int index;
struct work_struct crash_handler;
unsigned int crash_cnt;
- struct completion crash_comp;
bool recovery_disabled;
int max_notifyid;
struct resource_table *table_ptr;
struct resource_table *cached_table;
+ size_t table_sz;
bool has_iommu;
bool auto_boot;
};
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 166144c04ef6..b161ef8a902e 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -555,6 +555,14 @@ struct task_struct {
unsigned long wakee_flip_decay_ts;
struct task_struct *last_wakee;
+ /*
+ * recent_used_cpu is initially set as the last CPU used by a task
+ * that wakes affine another task. Waker/wakee relationships can
+ * push tasks around a CPU where each wakeup moves to the next one.
+ * Tracking a recently used CPU allows a quick search for a recently
+ * used CPU that may be idle.
+ */
+ int recent_used_cpu;
int wake_cpu;
#endif
int on_rq;
@@ -1489,6 +1497,11 @@ static inline struct thread_info *task_thread_info(struct task_struct *task)
extern struct task_struct *find_task_by_vpid(pid_t nr);
extern struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns);
+/*
+ * find a task by its virtual pid and get the task struct
+ */
+extern struct task_struct *find_get_task_by_vpid(pid_t nr);
+
extern int wake_up_state(struct task_struct *tsk, unsigned int state);
extern int wake_up_process(struct task_struct *tsk);
extern void wake_up_new_task(struct task_struct *tsk);
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index bd422561a75e..1149533aa2fa 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -7,6 +7,7 @@
#include <linux/sched.h>
#include <linux/mm_types.h>
#include <linux/gfp.h>
+#include <linux/sync_core.h>
/*
* Routines for handling mm_structs
@@ -194,18 +195,48 @@ static inline void memalloc_noreclaim_restore(unsigned int flags)
#ifdef CONFIG_MEMBARRIER
enum {
- MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY = (1U << 0),
- MEMBARRIER_STATE_SWITCH_MM = (1U << 1),
+ MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY = (1U << 0),
+ MEMBARRIER_STATE_PRIVATE_EXPEDITED = (1U << 1),
+ MEMBARRIER_STATE_GLOBAL_EXPEDITED_READY = (1U << 2),
+ MEMBARRIER_STATE_GLOBAL_EXPEDITED = (1U << 3),
+ MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY = (1U << 4),
+ MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE = (1U << 5),
};
+enum {
+ MEMBARRIER_FLAG_SYNC_CORE = (1U << 0),
+};
+
+#ifdef CONFIG_ARCH_HAS_MEMBARRIER_CALLBACKS
+#include <asm/membarrier.h>
+#endif
+
+static inline void membarrier_mm_sync_core_before_usermode(struct mm_struct *mm)
+{
+ if (likely(!(atomic_read(&mm->membarrier_state) &
+ MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE)))
+ return;
+ sync_core_before_usermode();
+}
+
static inline void membarrier_execve(struct task_struct *t)
{
atomic_set(&t->mm->membarrier_state, 0);
}
#else
+#ifdef CONFIG_ARCH_HAS_MEMBARRIER_CALLBACKS
+static inline void membarrier_arch_switch_mm(struct mm_struct *prev,
+ struct mm_struct *next,
+ struct task_struct *tsk)
+{
+}
+#endif
static inline void membarrier_execve(struct task_struct *t)
{
}
+static inline void membarrier_mm_sync_core_before_usermode(struct mm_struct *mm)
+{
+}
#endif
#endif /* _LINUX_SCHED_MM_H */
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 09c6e28746f9..ab437dd2e3b9 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -140,6 +140,20 @@ void *__seq_open_private(struct file *, const struct seq_operations *, int);
int seq_open_private(struct file *, const struct seq_operations *, int);
int seq_release_private(struct inode *, struct file *);
+#define DEFINE_SHOW_ATTRIBUTE(__name) \
+static int __name ## _open(struct inode *inode, struct file *file) \
+{ \
+ return single_open(file, __name ## _show, inode->i_private); \
+} \
+ \
+static const struct file_operations __name ## _fops = { \
+ .owner = THIS_MODULE, \
+ .open = __name ## _open, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+}
+
static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
{
#ifdef CONFIG_USER_NS
diff --git a/include/linux/switchtec.h b/include/linux/switchtec.h
index 6d325a7a0c19..ec93e93371fa 100644
--- a/include/linux/switchtec.h
+++ b/include/linux/switchtec.h
@@ -100,6 +100,9 @@ struct sw_event_regs {
u32 gpio_interrupt_hdr;
u32 gpio_interrupt_data;
u32 reserved16[4];
+ u32 gfms_event_hdr;
+ u32 gfms_event_data;
+ u32 reserved17[4];
} __packed;
enum {
diff --git a/include/linux/sync_core.h b/include/linux/sync_core.h
new file mode 100644
index 000000000000..013da4b8b327
--- /dev/null
+++ b/include/linux/sync_core.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_SYNC_CORE_H
+#define _LINUX_SYNC_CORE_H
+
+#ifdef CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
+#include <asm/sync_core.h>
+#else
+/*
+ * This is a dummy sync_core_before_usermode() implementation that can be used
+ * on all architectures which return to user-space through core serializing
+ * instructions.
+ * If your architecture returns to user-space through non-core-serializing
+ * instructions, you need to write your own functions.
+ */
+static inline void sync_core_before_usermode(void)
+{
+}
+#endif
+
+#endif /* _LINUX_SYNC_CORE_H */
+
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 992bc9948232..b769ecfcc3bd 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -51,9 +51,6 @@ extern int proc_dointvec_minmax(struct ctl_table *, int,
extern int proc_douintvec_minmax(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos);
-extern int proc_dopipe_max_size(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp,
- loff_t *ppos);
extern int proc_dointvec_jiffies(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int,
diff --git a/include/linux/uuid.h b/include/linux/uuid.h
index 33b0bdbb613c..d9c4a6cce3c2 100644
--- a/include/linux/uuid.h
+++ b/include/linux/uuid.h
@@ -17,6 +17,7 @@
#define _LINUX_UUID_H_
#include <uapi/linux/uuid.h>
+#include <linux/string.h>
#define UUID_SIZE 16
diff --git a/include/media/cec.h b/include/media/cec.h
index 16341210d3ba..7cdf71d7125a 100644
--- a/include/media/cec.h
+++ b/include/media/cec.h
@@ -122,6 +122,7 @@ struct cec_adap_ops {
/* Low-level callbacks */
int (*adap_enable)(struct cec_adapter *adap, bool enable);
int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
+ int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable);
int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
u32 signal_free_time, struct cec_msg *msg);
@@ -191,11 +192,6 @@ struct cec_adapter {
u32 tx_timeouts;
-#ifdef CONFIG_MEDIA_CEC_RC
- bool rc_repeating;
- int rc_last_scancode;
- u64 rc_last_keypress;
-#endif
#ifdef CONFIG_CEC_NOTIFIER
struct cec_notifier *notifier;
#endif
@@ -229,6 +225,18 @@ static inline bool cec_is_sink(const struct cec_adapter *adap)
return adap->phys_addr == 0;
}
+/**
+ * cec_is_registered() - is the CEC adapter registered?
+ *
+ * @adap: the CEC adapter, may be NULL.
+ *
+ * Return: true if the adapter is registered, false otherwise.
+ */
+static inline bool cec_is_registered(const struct cec_adapter *adap)
+{
+ return adap && adap->devnode.registered;
+}
+
#define cec_phys_addr_exp(pa) \
((pa) >> 12), ((pa) >> 8) & 0xf, ((pa) >> 4) & 0xf, (pa) & 0xf
diff --git a/drivers/media/dvb-core/demux.h b/include/media/demux.h
index c4df6cee48e6..c4df6cee48e6 100644
--- a/drivers/media/dvb-core/demux.h
+++ b/include/media/demux.h
diff --git a/drivers/media/dvb-core/dmxdev.h b/include/media/dmxdev.h
index 5e795f5f0f41..2f5cb2c7b6a7 100644
--- a/drivers/media/dvb-core/dmxdev.h
+++ b/include/media/dmxdev.h
@@ -32,9 +32,10 @@
#include <linux/dvb/dmx.h>
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_ringbuffer.h"
+#include <media/dvbdev.h>
+#include <media/demux.h>
+#include <media/dvb_ringbuffer.h>
+#include <media/dvb_vb2.h>
/**
* enum dmxdev_type - type of demux filter type.
@@ -89,23 +90,29 @@ struct dmxdev_feed {
/**
* struct dmxdev_filter - digital TV dmxdev filter
*
- * @filter: a dmxdev filter. Currently used only for section filter:
- * if the filter is Section, it contains a
- * &struct dmx_section_filter @sec pointer.
- * @feed: a dmxdev feed. Depending on the feed type, it can be:
- * for TS feed: a &struct list_head @ts list of TS and PES
- * feeds;
- * for section feed: a &struct dmx_section_feed @sec pointer.
- * @params: dmxdev filter parameters. Depending on the feed type, it
- * can be:
- * for section filter: a &struct dmx_sct_filter_params @sec
- * embedded struct;
- * for a TS filter: a &struct dmx_pes_filter_params @pes
- * embedded struct.
+ * @filter: a union describing a dmxdev filter.
+ * Currently used only for section filters.
+ * @filter.sec: a &struct dmx_section_filter pointer.
+ * For section filter only.
+ * @feed: a union describing a dmxdev feed.
+ * Depending on the filter type, it can be either
+ * @feed.ts or @feed.sec.
+ * @feed.ts: a &struct list_head list.
+ * For TS and PES feeds.
+ * @feed.sec: a &struct dmx_section_feed pointer.
+ * For section feed only.
+ * @params: a union describing dmxdev filter parameters.
+ * Depending on the filter type, it can be either
+ * @params.sec or @params.pes.
+ * @params.sec: a &struct dmx_sct_filter_params embedded struct.
+ * For section filter only.
+ * @params.pes: a &struct dmx_pes_filter_params embedded struct.
+ * For PES filter only.
* @type: type of the dmxdev filter, as defined by &enum dmxdev_type.
* @state: state of the dmxdev filter, as defined by &enum dmxdev_state.
* @dev: pointer to &struct dmxdev.
* @buffer: an embedded &struct dvb_ringbuffer buffer.
+ * @vb2_ctx: control struct for VB2 handler
* @mutex: protects the access to &struct dmxdev_filter.
* @timer: &struct timer_list embedded timer, used to check for
* feed timeouts.
@@ -135,6 +142,7 @@ struct dmxdev_filter {
enum dmxdev_state state;
struct dmxdev *dev;
struct dvb_ringbuffer buffer;
+ struct dvb_vb2_ctx vb2_ctx;
struct mutex mutex;
@@ -158,6 +166,7 @@ struct dmxdev_filter {
* @exit: flag to indicate that the demux is being released.
* @dvr_orig_fe: pointer to &struct dmx_frontend.
* @dvr_buffer: embedded &struct dvb_ringbuffer for DVB output.
+ * @dvr_vb2_ctx: control struct for VB2 handler
* @mutex: protects the usage of this structure.
* @lock: protects access to &dmxdev->filter->data.
*/
@@ -178,6 +187,8 @@ struct dmxdev {
struct dvb_ringbuffer dvr_buffer;
#define DVR_BUFFER_SIZE (10*188*1024)
+ struct dvb_vb2_ctx dvr_vb2_ctx;
+
struct mutex mutex;
spinlock_t lock;
};
diff --git a/include/media/drv-intf/cx2341x.h b/include/media/drv-intf/cx2341x.h
index 9635eebaab09..33a97bfcea58 100644
--- a/include/media/drv-intf/cx2341x.h
+++ b/include/media/drv-intf/cx2341x.h
@@ -29,8 +29,8 @@ enum cx2341x_port {
enum cx2341x_cap {
CX2341X_CAP_HAS_SLICED_VBI = 1 << 0,
- CX2341X_CAP_HAS_TS = 1 << 1,
- CX2341X_CAP_HAS_AC3 = 1 << 2,
+ CX2341X_CAP_HAS_TS = 1 << 1,
+ CX2341X_CAP_HAS_AC3 = 1 << 2,
};
struct cx2341x_mpeg_params {
@@ -204,92 +204,92 @@ void cx2341x_handler_set_busy(struct cx2341x_handler *cxhdl, int busy);
/* Firmware API commands */
/* MPEG decoder API, specific to the cx23415 */
-#define CX2341X_DEC_PING_FW 0x00
-#define CX2341X_DEC_START_PLAYBACK 0x01
-#define CX2341X_DEC_STOP_PLAYBACK 0x02
-#define CX2341X_DEC_SET_PLAYBACK_SPEED 0x03
-#define CX2341X_DEC_STEP_VIDEO 0x05
-#define CX2341X_DEC_SET_DMA_BLOCK_SIZE 0x08
+#define CX2341X_DEC_PING_FW 0x00
+#define CX2341X_DEC_START_PLAYBACK 0x01
+#define CX2341X_DEC_STOP_PLAYBACK 0x02
+#define CX2341X_DEC_SET_PLAYBACK_SPEED 0x03
+#define CX2341X_DEC_STEP_VIDEO 0x05
+#define CX2341X_DEC_SET_DMA_BLOCK_SIZE 0x08
#define CX2341X_DEC_GET_XFER_INFO 0x09
#define CX2341X_DEC_GET_DMA_STATUS 0x0a
#define CX2341X_DEC_SCHED_DMA_FROM_HOST 0x0b
-#define CX2341X_DEC_PAUSE_PLAYBACK 0x0d
-#define CX2341X_DEC_HALT_FW 0x0e
-#define CX2341X_DEC_SET_STANDARD 0x10
+#define CX2341X_DEC_PAUSE_PLAYBACK 0x0d
+#define CX2341X_DEC_HALT_FW 0x0e
+#define CX2341X_DEC_SET_STANDARD 0x10
#define CX2341X_DEC_GET_VERSION 0x11
-#define CX2341X_DEC_SET_STREAM_INPUT 0x14
-#define CX2341X_DEC_GET_TIMING_INFO 0x15
-#define CX2341X_DEC_SET_AUDIO_MODE 0x16
+#define CX2341X_DEC_SET_STREAM_INPUT 0x14
+#define CX2341X_DEC_GET_TIMING_INFO 0x15
+#define CX2341X_DEC_SET_AUDIO_MODE 0x16
#define CX2341X_DEC_SET_EVENT_NOTIFICATION 0x17
#define CX2341X_DEC_SET_DISPLAY_BUFFERS 0x18
-#define CX2341X_DEC_EXTRACT_VBI 0x19
-#define CX2341X_DEC_SET_DECODER_SOURCE 0x1a
+#define CX2341X_DEC_EXTRACT_VBI 0x19
+#define CX2341X_DEC_SET_DECODER_SOURCE 0x1a
#define CX2341X_DEC_SET_PREBUFFERING 0x1e
/* MPEG encoder API */
-#define CX2341X_ENC_PING_FW 0x80
-#define CX2341X_ENC_START_CAPTURE 0x81
-#define CX2341X_ENC_STOP_CAPTURE 0x82
-#define CX2341X_ENC_SET_AUDIO_ID 0x89
-#define CX2341X_ENC_SET_VIDEO_ID 0x8b
-#define CX2341X_ENC_SET_PCR_ID 0x8d
-#define CX2341X_ENC_SET_FRAME_RATE 0x8f
-#define CX2341X_ENC_SET_FRAME_SIZE 0x91
-#define CX2341X_ENC_SET_BIT_RATE 0x95
-#define CX2341X_ENC_SET_GOP_PROPERTIES 0x97
-#define CX2341X_ENC_SET_ASPECT_RATIO 0x99
-#define CX2341X_ENC_SET_DNR_FILTER_MODE 0x9b
-#define CX2341X_ENC_SET_DNR_FILTER_PROPS 0x9d
-#define CX2341X_ENC_SET_CORING_LEVELS 0x9f
-#define CX2341X_ENC_SET_SPATIAL_FILTER_TYPE 0xa1
-#define CX2341X_ENC_SET_VBI_LINE 0xb7
-#define CX2341X_ENC_SET_STREAM_TYPE 0xb9
-#define CX2341X_ENC_SET_OUTPUT_PORT 0xbb
-#define CX2341X_ENC_SET_AUDIO_PROPERTIES 0xbd
-#define CX2341X_ENC_HALT_FW 0xc3
+#define CX2341X_ENC_PING_FW 0x80
+#define CX2341X_ENC_START_CAPTURE 0x81
+#define CX2341X_ENC_STOP_CAPTURE 0x82
+#define CX2341X_ENC_SET_AUDIO_ID 0x89
+#define CX2341X_ENC_SET_VIDEO_ID 0x8b
+#define CX2341X_ENC_SET_PCR_ID 0x8d
+#define CX2341X_ENC_SET_FRAME_RATE 0x8f
+#define CX2341X_ENC_SET_FRAME_SIZE 0x91
+#define CX2341X_ENC_SET_BIT_RATE 0x95
+#define CX2341X_ENC_SET_GOP_PROPERTIES 0x97
+#define CX2341X_ENC_SET_ASPECT_RATIO 0x99
+#define CX2341X_ENC_SET_DNR_FILTER_MODE 0x9b
+#define CX2341X_ENC_SET_DNR_FILTER_PROPS 0x9d
+#define CX2341X_ENC_SET_CORING_LEVELS 0x9f
+#define CX2341X_ENC_SET_SPATIAL_FILTER_TYPE 0xa1
+#define CX2341X_ENC_SET_VBI_LINE 0xb7
+#define CX2341X_ENC_SET_STREAM_TYPE 0xb9
+#define CX2341X_ENC_SET_OUTPUT_PORT 0xbb
+#define CX2341X_ENC_SET_AUDIO_PROPERTIES 0xbd
+#define CX2341X_ENC_HALT_FW 0xc3
#define CX2341X_ENC_GET_VERSION 0xc4
-#define CX2341X_ENC_SET_GOP_CLOSURE 0xc5
-#define CX2341X_ENC_GET_SEQ_END 0xc6
-#define CX2341X_ENC_SET_PGM_INDEX_INFO 0xc7
+#define CX2341X_ENC_SET_GOP_CLOSURE 0xc5
+#define CX2341X_ENC_GET_SEQ_END 0xc6
+#define CX2341X_ENC_SET_PGM_INDEX_INFO 0xc7
#define CX2341X_ENC_SET_VBI_CONFIG 0xc8
-#define CX2341X_ENC_SET_DMA_BLOCK_SIZE 0xc9
+#define CX2341X_ENC_SET_DMA_BLOCK_SIZE 0xc9
#define CX2341X_ENC_GET_PREV_DMA_INFO_MB_10 0xca
#define CX2341X_ENC_GET_PREV_DMA_INFO_MB_9 0xcb
-#define CX2341X_ENC_SCHED_DMA_TO_HOST 0xcc
-#define CX2341X_ENC_INITIALIZE_INPUT 0xcd
-#define CX2341X_ENC_SET_FRAME_DROP_RATE 0xd0
-#define CX2341X_ENC_PAUSE_ENCODER 0xd2
-#define CX2341X_ENC_REFRESH_INPUT 0xd3
+#define CX2341X_ENC_SCHED_DMA_TO_HOST 0xcc
+#define CX2341X_ENC_INITIALIZE_INPUT 0xcd
+#define CX2341X_ENC_SET_FRAME_DROP_RATE 0xd0
+#define CX2341X_ENC_PAUSE_ENCODER 0xd2
+#define CX2341X_ENC_REFRESH_INPUT 0xd3
#define CX2341X_ENC_SET_COPYRIGHT 0xd4
-#define CX2341X_ENC_SET_EVENT_NOTIFICATION 0xd5
-#define CX2341X_ENC_SET_NUM_VSYNC_LINES 0xd6
-#define CX2341X_ENC_SET_PLACEHOLDER 0xd7
-#define CX2341X_ENC_MUTE_VIDEO 0xd9
-#define CX2341X_ENC_MUTE_AUDIO 0xda
+#define CX2341X_ENC_SET_EVENT_NOTIFICATION 0xd5
+#define CX2341X_ENC_SET_NUM_VSYNC_LINES 0xd6
+#define CX2341X_ENC_SET_PLACEHOLDER 0xd7
+#define CX2341X_ENC_MUTE_VIDEO 0xd9
+#define CX2341X_ENC_MUTE_AUDIO 0xda
#define CX2341X_ENC_SET_VERT_CROP_LINE 0xdb
-#define CX2341X_ENC_MISC 0xdc
+#define CX2341X_ENC_MISC 0xdc
/* OSD API, specific to the cx23415 */
-#define CX2341X_OSD_GET_FRAMEBUFFER 0x41
-#define CX2341X_OSD_GET_PIXEL_FORMAT 0x42
-#define CX2341X_OSD_SET_PIXEL_FORMAT 0x43
-#define CX2341X_OSD_GET_STATE 0x44
-#define CX2341X_OSD_SET_STATE 0x45
-#define CX2341X_OSD_GET_OSD_COORDS 0x46
-#define CX2341X_OSD_SET_OSD_COORDS 0x47
-#define CX2341X_OSD_GET_SCREEN_COORDS 0x48
-#define CX2341X_OSD_SET_SCREEN_COORDS 0x49
-#define CX2341X_OSD_GET_GLOBAL_ALPHA 0x4a
-#define CX2341X_OSD_SET_GLOBAL_ALPHA 0x4b
-#define CX2341X_OSD_SET_BLEND_COORDS 0x4c
-#define CX2341X_OSD_GET_FLICKER_STATE 0x4f
-#define CX2341X_OSD_SET_FLICKER_STATE 0x50
-#define CX2341X_OSD_BLT_COPY 0x52
-#define CX2341X_OSD_BLT_FILL 0x53
-#define CX2341X_OSD_BLT_TEXT 0x54
-#define CX2341X_OSD_SET_FRAMEBUFFER_WINDOW 0x56
-#define CX2341X_OSD_SET_CHROMA_KEY 0x60
-#define CX2341X_OSD_GET_ALPHA_CONTENT_INDEX 0x61
-#define CX2341X_OSD_SET_ALPHA_CONTENT_INDEX 0x62
+#define CX2341X_OSD_GET_FRAMEBUFFER 0x41
+#define CX2341X_OSD_GET_PIXEL_FORMAT 0x42
+#define CX2341X_OSD_SET_PIXEL_FORMAT 0x43
+#define CX2341X_OSD_GET_STATE 0x44
+#define CX2341X_OSD_SET_STATE 0x45
+#define CX2341X_OSD_GET_OSD_COORDS 0x46
+#define CX2341X_OSD_SET_OSD_COORDS 0x47
+#define CX2341X_OSD_GET_SCREEN_COORDS 0x48
+#define CX2341X_OSD_SET_SCREEN_COORDS 0x49
+#define CX2341X_OSD_GET_GLOBAL_ALPHA 0x4a
+#define CX2341X_OSD_SET_GLOBAL_ALPHA 0x4b
+#define CX2341X_OSD_SET_BLEND_COORDS 0x4c
+#define CX2341X_OSD_GET_FLICKER_STATE 0x4f
+#define CX2341X_OSD_SET_FLICKER_STATE 0x50
+#define CX2341X_OSD_BLT_COPY 0x52
+#define CX2341X_OSD_BLT_FILL 0x53
+#define CX2341X_OSD_BLT_TEXT 0x54
+#define CX2341X_OSD_SET_FRAMEBUFFER_WINDOW 0x56
+#define CX2341X_OSD_SET_CHROMA_KEY 0x60
+#define CX2341X_OSD_GET_ALPHA_CONTENT_INDEX 0x61
+#define CX2341X_OSD_SET_ALPHA_CONTENT_INDEX 0x62
#endif /* CX2341X_H */
diff --git a/include/media/drv-intf/exynos-fimc.h b/include/media/drv-intf/exynos-fimc.h
index 69bcd2a07d5c..f9c64338841f 100644
--- a/include/media/drv-intf/exynos-fimc.h
+++ b/include/media/drv-intf/exynos-fimc.h
@@ -155,7 +155,8 @@ static inline struct exynos_video_entity *vdev_to_exynos_video_entity(
}
#define fimc_pipeline_call(ent, op, args...) \
- (!(ent) ? -ENOENT : (((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
+ ((!(ent) || !(ent)->pipe) ? -ENOENT : \
+ (((ent)->pipe->ops && (ent)->pipe->ops->op) ? \
(ent)->pipe->ops->op(((ent)->pipe), ##args) : -ENOIOCTLCMD)) \
#endif /* S5P_FIMC_H_ */
diff --git a/include/media/drv-intf/msp3400.h b/include/media/drv-intf/msp3400.h
index 1e6e80213a77..db98ce49e17b 100644
--- a/include/media/drv-intf/msp3400.h
+++ b/include/media/drv-intf/msp3400.h
@@ -80,17 +80,17 @@
*/
/* SCART input to DSP selection */
-#define MSP_IN_SCART1 0 /* Pin SC1_IN */
-#define MSP_IN_SCART2 1 /* Pin SC2_IN */
-#define MSP_IN_SCART3 2 /* Pin SC3_IN */
-#define MSP_IN_SCART4 3 /* Pin SC4_IN */
-#define MSP_IN_MONO 6 /* Pin MONO_IN */
-#define MSP_IN_MUTE 7 /* Mute DSP input */
-#define MSP_SCART_TO_DSP(in) (in)
+#define MSP_IN_SCART1 0 /* Pin SC1_IN */
+#define MSP_IN_SCART2 1 /* Pin SC2_IN */
+#define MSP_IN_SCART3 2 /* Pin SC3_IN */
+#define MSP_IN_SCART4 3 /* Pin SC4_IN */
+#define MSP_IN_MONO 6 /* Pin MONO_IN */
+#define MSP_IN_MUTE 7 /* Mute DSP input */
+#define MSP_SCART_TO_DSP(in) (in)
/* Tuner input to demodulator and DSP selection */
-#define MSP_IN_TUNER1 0 /* Analog Sound IF input pin ANA_IN1 */
-#define MSP_IN_TUNER2 1 /* Analog Sound IF input pin ANA_IN2 */
-#define MSP_TUNER_TO_DSP(in) ((in) << 3)
+#define MSP_IN_TUNER1 0 /* Analog Sound IF input pin ANA_IN1 */
+#define MSP_IN_TUNER2 1 /* Analog Sound IF input pin ANA_IN2 */
+#define MSP_TUNER_TO_DSP(in) ((in) << 3)
/* The msp has up to 5 DSP outputs, each output can independently select
a DSP input.
@@ -109,30 +109,30 @@
DSP. This is currently not implemented. Also not implemented is the
multi-channel capable I2S3 input of the 44x0G. If someone can demonstrate
a need for one of those features then additional support can be added. */
-#define MSP_DSP_IN_TUNER 0 /* Tuner DSP input */
-#define MSP_DSP_IN_SCART 2 /* SCART DSP input */
-#define MSP_DSP_IN_I2S1 5 /* I2S1 DSP input */
-#define MSP_DSP_IN_I2S2 6 /* I2S2 DSP input */
-#define MSP_DSP_IN_I2S3 7 /* I2S3 DSP input */
-#define MSP_DSP_IN_MAIN_AVC 11 /* MAIN AVC processed DSP input */
-#define MSP_DSP_IN_MAIN 12 /* MAIN DSP input */
-#define MSP_DSP_IN_AUX 13 /* AUX DSP input */
-#define MSP_DSP_TO_MAIN(in) ((in) << 4)
-#define MSP_DSP_TO_AUX(in) ((in) << 8)
-#define MSP_DSP_TO_SCART1(in) ((in) << 12)
-#define MSP_DSP_TO_SCART2(in) ((in) << 16)
-#define MSP_DSP_TO_I2S(in) ((in) << 20)
+#define MSP_DSP_IN_TUNER 0 /* Tuner DSP input */
+#define MSP_DSP_IN_SCART 2 /* SCART DSP input */
+#define MSP_DSP_IN_I2S1 5 /* I2S1 DSP input */
+#define MSP_DSP_IN_I2S2 6 /* I2S2 DSP input */
+#define MSP_DSP_IN_I2S3 7 /* I2S3 DSP input */
+#define MSP_DSP_IN_MAIN_AVC 11 /* MAIN AVC processed DSP input */
+#define MSP_DSP_IN_MAIN 12 /* MAIN DSP input */
+#define MSP_DSP_IN_AUX 13 /* AUX DSP input */
+#define MSP_DSP_TO_MAIN(in) ((in) << 4)
+#define MSP_DSP_TO_AUX(in) ((in) << 8)
+#define MSP_DSP_TO_SCART1(in) ((in) << 12)
+#define MSP_DSP_TO_SCART2(in) ((in) << 16)
+#define MSP_DSP_TO_I2S(in) ((in) << 20)
/* Output SCART select: the SCART outputs can select which input
to use. */
-#define MSP_SC_IN_SCART1 0 /* SCART1 input, bypassing the DSP */
-#define MSP_SC_IN_SCART2 1 /* SCART2 input, bypassing the DSP */
-#define MSP_SC_IN_SCART3 2 /* SCART3 input, bypassing the DSP */
-#define MSP_SC_IN_SCART4 3 /* SCART4 input, bypassing the DSP */
-#define MSP_SC_IN_DSP_SCART1 4 /* DSP SCART1 input */
-#define MSP_SC_IN_DSP_SCART2 5 /* DSP SCART2 input */
-#define MSP_SC_IN_MONO 6 /* MONO input, bypassing the DSP */
-#define MSP_SC_IN_MUTE 7 /* MUTE output */
+#define MSP_SC_IN_SCART1 0 /* SCART1 input, bypassing the DSP */
+#define MSP_SC_IN_SCART2 1 /* SCART2 input, bypassing the DSP */
+#define MSP_SC_IN_SCART3 2 /* SCART3 input, bypassing the DSP */
+#define MSP_SC_IN_SCART4 3 /* SCART4 input, bypassing the DSP */
+#define MSP_SC_IN_DSP_SCART1 4 /* DSP SCART1 input */
+#define MSP_SC_IN_DSP_SCART2 5 /* DSP SCART2 input */
+#define MSP_SC_IN_MONO 6 /* MONO input, bypassing the DSP */
+#define MSP_SC_IN_MUTE 7 /* MUTE output */
#define MSP_SC_TO_SCART1(in) (in)
#define MSP_SC_TO_SCART2(in) ((in) << 4)
diff --git a/include/media/drv-intf/saa7146.h b/include/media/drv-intf/saa7146.h
index 769c6cf7eb4c..a7bf2c4a2e4d 100644
--- a/include/media/drv-intf/saa7146.h
+++ b/include/media/drv-intf/saa7146.h
@@ -118,7 +118,7 @@ struct saa7146_dev
{
struct module *module;
- struct v4l2_device v4l2_dev;
+ struct v4l2_device v4l2_dev;
struct v4l2_ctrl_handler ctrl_handler;
/* different device locks */
diff --git a/drivers/media/dvb-core/dvb-usb-ids.h b/include/media/dvb-usb-ids.h
index 54d7d8a48b18..28e2be5c8a98 100644
--- a/drivers/media/dvb-core/dvb-usb-ids.h
+++ b/include/media/dvb-usb-ids.h
@@ -81,6 +81,7 @@
#define USB_VID_AZUREWAVE 0x13d3
#define USB_VID_TECHNISAT 0x14f7
#define USB_VID_HAMA 0x147f
+#define USB_VID_MICROSOFT 0x045e
/* Product IDs */
#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -385,6 +386,7 @@
#define USB_PID_SONY_PLAYTV 0x0003
#define USB_PID_MYGICA_D689 0xd811
#define USB_PID_MYGICA_T230 0xc688
+#define USB_PID_MYGICA_T230C 0xc689
#define USB_PID_ELGATO_EYETV_DIVERSITY 0x0011
#define USB_PID_ELGATO_EYETV_DTT 0x0021
#define USB_PID_ELGATO_EYETV_DTT_2 0x003f
@@ -418,4 +420,5 @@
#define USB_PID_WINTV_SOLOHD 0x0264
#define USB_PID_EVOLVEO_XTRATV_STICK 0xa115
#define USB_PID_HAMA_DVBT_HYBRID 0x2758
+#define USB_PID_XBOX_ONE_TUNER 0x02d5
#endif
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.h b/include/media/dvb_ca_en50221.h
index 367687d2b41a..a1c014b0a837 100644
--- a/drivers/media/dvb-core/dvb_ca_en50221.h
+++ b/include/media/dvb_ca_en50221.h
@@ -20,7 +20,7 @@
#include <linux/list.h>
#include <linux/dvb/ca.h>
-#include "dvbdev.h"
+#include <media/dvbdev.h>
#define DVB_CA_EN50221_POLL_CAM_PRESENT 1
#define DVB_CA_EN50221_POLL_CAM_CHANGED 2
diff --git a/drivers/media/dvb-core/dvb_demux.h b/include/media/dvb_demux.h
index cc048f09aa85..b07092038f4b 100644
--- a/drivers/media/dvb-core/dvb_demux.h
+++ b/include/media/dvb_demux.h
@@ -24,7 +24,7 @@
#include <linux/spinlock.h>
#include <linux/mutex.h>
-#include "demux.h"
+#include <media/demux.h>
/**
* enum dvb_dmx_filter_type - type of demux feed.
@@ -94,15 +94,20 @@ struct dvb_demux_filter {
/**
* struct dvb_demux_feed - describes a DVB field
*
- * @feed: a digital TV feed. It can either be a TS or a section feed:
- * if the feed is TS, it contains &struct dvb_ts_feed @ts;
- * if the feed is section, it contains
- * &struct dmx_section_feed @sec.
- * @cb: digital TV callbacks. depending on the feed type, it can be:
- * if the feed is TS, it contains a dmx_ts_cb() @ts callback;
- * if the feed is section, it contains a dmx_section_cb() @sec
- * callback.
- *
+ * @feed: a union describing a digital TV feed.
+ * Depending on the feed type, it can be either
+ * @feed.ts or @feed.sec.
+ * @feed.ts: a &struct dmx_ts_feed pointer.
+ * For TS feed only.
+ * @feed.sec: a &struct dmx_section_feed pointer.
+ * For section feed only.
+ * @cb: a union describing digital TV callbacks.
+ * Depending on the feed type, it can be either
+ * @cb.ts or @cb.sec.
+ * @cb.ts: a dmx_ts_cb() calback function pointer.
+ * For TS feed only.
+ * @cb.sec: a dmx_section_cb() callback function pointer.
+ * For section feed only.
* @demux: pointer to &struct dvb_demux.
* @priv: private data that can optionally be used by a DVB driver.
* @type: type of the filter, as defined by &enum dvb_dmx_filter_type.
diff --git a/drivers/media/dvb-core/dvb_frontend.h b/include/media/dvb_frontend.h
index ace0c2fb26c2..331c8269c00e 100644
--- a/drivers/media/dvb-core/dvb_frontend.h
+++ b/include/media/dvb_frontend.h
@@ -44,7 +44,7 @@
#include <linux/dvb/frontend.h>
-#include "dvbdev.h"
+#include <media/dvbdev.h>
/*
* Maximum number of Delivery systems per frontend. It
@@ -99,10 +99,10 @@ struct dvb_tuner_info {
* struct analog_parameters - Parameters to tune into an analog/radio channel
*
* @frequency: Frequency used by analog TV tuner (either in 62.5 kHz step,
- * for TV, or 62.5 Hz for radio)
+ * for TV, or 62.5 Hz for radio)
* @mode: Tuner mode, as defined on enum v4l2_tuner_type
* @audmode: Audio mode as defined for the rxsubchans field at videodev2.h,
- * e. g. V4L2_TUNER_MODE_*
+ * e. g. V4L2_TUNER_MODE_*
* @std: TV standard bitmap as defined at videodev2.h, e. g. V4L2_STD_*
*
* Hybrid tuners should be supported by both V4L2 and DVB APIs. This
@@ -205,7 +205,7 @@ enum dvbfe_search {
* @get_frequency: get the actual tuned frequency
* @get_bandwidth: get the bandwitdh used by the low pass filters
* @get_if_frequency: get the Intermediate Frequency, in Hz. For baseband,
- * should return 0.
+ * should return 0.
* @get_status: returns the frontend lock status
* @get_rf_strength: returns the RF signal strength. Used mostly to support
* analog TV and radio. Digital TV should report, instead,
@@ -364,7 +364,7 @@ struct dtv_frontend_properties;
* implementing this callback only if DVBv3 API
* compatibility is wanted.
* @read_snr: legacy callback function to return the Signal/Noise
- * rate. Newer drivers should provide such info via
+ * rate. Newer drivers should provide such info via
* DVBv5 API, e. g. @set_frontend/@get_frontend,
* implementing this callback only if DVBv3 API
* compatibility is wanted.
@@ -490,7 +490,7 @@ struct dvb_fe_events {
* @fec_inner: Forward error correction inner Code Rate
* @transmission_mode: Transmission Mode
* @bandwidth_hz: Bandwidth, in Hz. A zero value means that userspace
- * wants to autodetect.
+ * wants to autodetect.
* @guard_interval: Guard Interval
* @hierarchy: Hierarchy
* @symbol_rate: Symbol Rate
@@ -513,6 +513,8 @@ struct dvb_fe_events {
* @layer.interleaving: per layer interleaving.
* @stream_id: If different than zero, enable substream filtering, if
* hardware supports (DVB-S2 and DVB-T2).
+ * @scrambling_sequence_index: Carries the index of the DVB-S2 physical layer
+ * scrambling sequence.
* @atscmh_fic_ver: Version number of the FIC (Fast Information Channel)
* signaling data (only ATSC-M/H)
* @atscmh_parade_id: Parade identification number (only ATSC-M/H)
@@ -536,7 +538,7 @@ struct dvb_fe_events {
* @lna: Power ON/OFF/AUTO the Linear Now-noise Amplifier (LNA)
* @strength: DVBv5 API statistics: Signal Strength
* @cnr: DVBv5 API statistics: Signal to Noise ratio of the
- * (main) carrier
+ * (main) carrier
* @pre_bit_error: DVBv5 API statistics: pre-Viterbi bit error count
* @pre_bit_count: DVBv5 API statistics: pre-Viterbi bit count
* @post_bit_error: DVBv5 API statistics: post-Viterbi bit error count
@@ -591,6 +593,9 @@ struct dtv_frontend_properties {
/* Multistream specifics */
u32 stream_id;
+ /* Physical Layer Scrambling specifics */
+ u32 scrambling_sequence_index;
+
/* ATSC-MH specifics */
u8 atscmh_fic_ver;
u8 atscmh_parade_id;
diff --git a/drivers/media/dvb-core/dvb_math.h b/include/media/dvb_math.h
index 8690ec42954d..8690ec42954d 100644
--- a/drivers/media/dvb-core/dvb_math.h
+++ b/include/media/dvb_math.h
diff --git a/drivers/media/dvb-core/dvb_net.h b/include/media/dvb_net.h
index 1eae8bad7cc1..5e31d37f25fa 100644
--- a/drivers/media/dvb-core/dvb_net.h
+++ b/include/media/dvb_net.h
@@ -24,7 +24,7 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#include "dvbdev.h"
+#include <media/dvbdev.h>
#define DVB_NET_DEVICES_MAX 10
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.h b/include/media/dvb_ringbuffer.h
index 8ed6bcc3a56e..8ed6bcc3a56e 100644
--- a/drivers/media/dvb-core/dvb_ringbuffer.h
+++ b/include/media/dvb_ringbuffer.h
diff --git a/include/media/dvb_vb2.h b/include/media/dvb_vb2.h
new file mode 100644
index 000000000000..01d1202d1a55
--- /dev/null
+++ b/include/media/dvb_vb2.h
@@ -0,0 +1,266 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ *
+ * dvb-vb2.h - DVB driver helper framework for streaming I/O
+ *
+ * Copyright (C) 2015 Samsung Electronics
+ *
+ * Author: jh1009.sung@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.
+ */
+
+#ifndef _DVB_VB2_H
+#define _DVB_VB2_H
+
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/dvb/dmx.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+
+/**
+ * enum dvb_buf_type - types of Digital TV memory-mapped buffers
+ *
+ * @DVB_BUF_TYPE_CAPTURE: buffer is filled by the Kernel,
+ * with a received Digital TV stream
+ */
+enum dvb_buf_type {
+ DVB_BUF_TYPE_CAPTURE = 1,
+};
+
+/**
+ * enum dvb_vb2_states - states to control VB2 state machine
+ * @DVB_VB2_STATE_NONE:
+ * VB2 engine not initialized yet, init failed or VB2 was released.
+ * @DVB_VB2_STATE_INIT:
+ * VB2 engine initialized.
+ * @DVB_VB2_STATE_REQBUFS:
+ * Buffers were requested
+ * @DVB_VB2_STATE_STREAMON:
+ * VB2 is streaming. Callers should not check it directly. Instead,
+ * they should use dvb_vb2_is_streaming().
+ *
+ * Note:
+ *
+ * Callers should not touch at the state machine directly. This
+ * is handled inside dvb_vb2.c.
+ */
+enum dvb_vb2_states {
+ DVB_VB2_STATE_NONE = 0x0,
+ DVB_VB2_STATE_INIT = 0x1,
+ DVB_VB2_STATE_REQBUFS = 0x2,
+ DVB_VB2_STATE_STREAMON = 0x4,
+};
+
+#define DVB_VB2_NAME_MAX (20)
+
+/**
+ * struct dvb_buffer - video buffer information for v4l2.
+ *
+ * @vb: embedded struct &vb2_buffer.
+ * @list: list of &struct dvb_buffer.
+ */
+struct dvb_buffer {
+ struct vb2_buffer vb;
+ struct list_head list;
+};
+
+/**
+ * struct dvb_vb2_ctx - control struct for VB2 handler
+ * @vb_q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @mutex: mutex to serialize vb2 operations. Used by
+ * vb2 core %wait_prepare and %wait_finish operations.
+ * @slock: spin lock used to protect buffer filling at dvb_vb2.c.
+ * @dvb_q: List of buffers that are not filled yet.
+ * @buf: Pointer to the buffer that are currently being filled.
+ * @offset: index to the next position at the @buf to be filled.
+ * @remain: How many bytes are left to be filled at @buf.
+ * @state: bitmask of buffer states as defined by &enum dvb_vb2_states.
+ * @buf_siz: size of each VB2 buffer.
+ * @buf_cnt: number of VB2 buffers.
+ * @nonblocking:
+ * If different than zero, device is operating on non-blocking
+ * mode.
+ * @name: name of the device type. Currently, it can either be
+ * "dvr" or "demux_filter".
+ */
+struct dvb_vb2_ctx {
+ struct vb2_queue vb_q;
+ struct mutex mutex;
+ spinlock_t slock;
+ struct list_head dvb_q;
+ struct dvb_buffer *buf;
+ int offset;
+ int remain;
+ int state;
+ int buf_siz;
+ int buf_cnt;
+ int nonblocking;
+ char name[DVB_VB2_NAME_MAX + 1];
+};
+
+#ifndef DVB_MMAP
+static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx,
+ const char *name, int non_blocking)
+{
+ return 0;
+};
+static inline int dvb_vb2_release(struct dvb_vb2_ctx *ctx)
+{
+ return 0;
+};
+#define dvb_vb2_is_streaming(ctx) (0)
+#define dvb_vb2_fill_buffer(ctx, file, wait) (0)
+
+static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx,
+ struct file *file,
+ poll_table *wait)
+{
+ return 0;
+}
+#else
+/**
+ * dvb_vb2_init - initializes VB2 handler
+ *
+ * @ctx: control struct for VB2 handler
+ * @name: name for the VB2 handler
+ * @non_blocking:
+ * if not zero, it means that the device is at non-blocking mode
+ */
+int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking);
+
+/**
+ * dvb_vb2_release - Releases the VB2 handler allocated resources and
+ * put @ctx at DVB_VB2_STATE_NONE state.
+ * @ctx: control struct for VB2 handler
+ */
+int dvb_vb2_release(struct dvb_vb2_ctx *ctx);
+
+/**
+ * dvb_vb2_is_streaming - checks if the VB2 handler is streaming
+ * @ctx: control struct for VB2 handler
+ *
+ * Return: 0 if not streaming, 1 otherwise.
+ */
+int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx);
+
+/**
+ * dvb_vb2_fill_buffer - fills a VB2 buffer
+ * @ctx: control struct for VB2 handler
+ * @src: place where the data is stored
+ * @len: number of bytes to be copied from @src
+ */
+int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
+ const unsigned char *src, int len);
+
+/**
+ * dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV
+ * buffer handling.
+ *
+ * @ctx: control struct for VB2 handler
+ * @file: &struct file argument passed to the poll
+ * file operation handler.
+ * @wait: &poll_table wait argument passed to the poll
+ * file operation handler.
+ *
+ * Implements poll syscall() logic.
+ */
+__poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file,
+ poll_table *wait);
+#endif
+
+/**
+ * dvb_vb2_stream_on() - Wrapper to vb2_core_streamon() for Digital TV
+ * buffer handling.
+ *
+ * @ctx: control struct for VB2 handler
+ *
+ * Starts dvb streaming
+ */
+int dvb_vb2_stream_on(struct dvb_vb2_ctx *ctx);
+/**
+ * dvb_vb2_stream_off() - Wrapper to vb2_core_streamoff() for Digital TV
+ * buffer handling.
+ *
+ * @ctx: control struct for VB2 handler
+ *
+ * Stops dvb streaming
+ */
+int dvb_vb2_stream_off(struct dvb_vb2_ctx *ctx);
+
+/**
+ * dvb_vb2_reqbufs() - Wrapper to vb2_core_reqbufs() for Digital TV
+ * buffer handling.
+ *
+ * @ctx: control struct for VB2 handler
+ * @req: &struct dmx_requestbuffers passed from userspace in
+ * order to handle &DMX_REQBUFS.
+ *
+ * Initiate streaming by requesting a number of buffers. Also used to
+ * free previously requested buffers, is ``req->count`` is zero.
+ */
+int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req);
+
+/**
+ * dvb_vb2_querybuf() - Wrapper to vb2_core_querybuf() for Digital TV
+ * buffer handling.
+ *
+ * @ctx: control struct for VB2 handler
+ * @b: &struct dmx_buffer passed from userspace in
+ * order to handle &DMX_QUERYBUF.
+ *
+ *
+ */
+int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
+
+/**
+ * dvb_vb2_expbuf() - Wrapper to vb2_core_expbuf() for Digital TV
+ * buffer handling.
+ *
+ * @ctx: control struct for VB2 handler
+ * @exp: &struct dmx_exportbuffer passed from userspace in
+ * order to handle &DMX_EXPBUF.
+ *
+ * Export a buffer as a file descriptor.
+ */
+int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp);
+
+/**
+ * dvb_vb2_qbuf() - Wrapper to vb2_core_qbuf() for Digital TV buffer handling.
+ *
+ * @ctx: control struct for VB2 handler
+ * @b: &struct dmx_buffer passed from userspace in
+ * order to handle &DMX_QBUF.
+ *
+ * Queue a Digital TV buffer as requested by userspace
+ */
+int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
+
+/**
+ * dvb_vb2_dqbuf() - Wrapper to vb2_core_dqbuf() for Digital TV
+ * buffer handling.
+ *
+ * @ctx: control struct for VB2 handler
+ * @b: &struct dmx_buffer passed from userspace in
+ * order to handle &DMX_DQBUF.
+ *
+ * Dequeue a Digital TV buffer to the userspace
+ */
+int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b);
+
+/**
+ * dvb_vb2_mmap() - Wrapper to vb2_mmap() for Digital TV buffer handling.
+ *
+ * @ctx: control struct for VB2 handler
+ * @vma: pointer to &struct vm_area_struct with the vma passed
+ * to the mmap file operation handler in the driver.
+ *
+ * map Digital TV video buffers into application address space.
+ */
+int dvb_vb2_mmap(struct dvb_vb2_ctx *ctx, struct vm_area_struct *vma);
+
+#endif /* _DVB_VB2_H */
diff --git a/drivers/media/dvb-core/dvbdev.h b/include/media/dvbdev.h
index bbc1c20c0529..554db879527f 100644
--- a/drivers/media/dvb-core/dvbdev.h
+++ b/include/media/dvbdev.h
@@ -193,7 +193,7 @@ struct dvb_device {
* @module: initialized with THIS_MODULE at the caller
* @device: pointer to struct device that corresponds to the device driver
* @adapter_nums: Array with a list of the numbers for @dvb_register_adapter;
- * to select among them. Typically, initialized with:
+ * to select among them. Typically, initialized with:
* DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums)
*/
int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
@@ -259,7 +259,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev);
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
/**
* dvb_create_media_graph - Creates media graph for the Digital TV part of the
- * device.
+ * device.
*
* @adap: pointer to &struct dvb_adapter
* @create_rf_connector: if true, it creates the RF connector too
diff --git a/include/media/i2c-addr.h b/include/media/i2c-addr.h
deleted file mode 100644
index 1b6872f5e970..000000000000
--- a/include/media/i2c-addr.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * V4L I2C address list
- *
- *
- * Copyright (C) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>
- * Based on a previous mapping by
- * Ralph Metzler (rjkm@thp.uni-koeln.de)
- * Gerd Knorr <kraxel@goldbach.in-berlin.de>
- *
- */
-
-/* bttv address list */
-#define I2C_ADDR_TSA5522 0xc2
-#define I2C_ADDR_TDA7432 0x8a
-#define I2C_ADDR_TDA8425 0x82
-#define I2C_ADDR_TDA9840 0x84
-#define I2C_ADDR_TDA9850 0xb6 /* also used by 9855,9873 */
-#define I2C_ADDR_TDA9874 0xb0 /* also used by 9875 */
-#define I2C_ADDR_TDA9875 0xb0
-#define I2C_ADDR_HAUPEE 0xa0
-#define I2C_ADDR_STBEE 0xae
-#define I2C_ADDR_VHX 0xc0
-#define I2C_ADDR_MSP3400 0x80
-#define I2C_ADDR_MSP3400_ALT 0x88
-#define I2C_ADDR_TEA6300 0x80 /* also used by 6320 */
-#define I2C_ADDR_DPL3518 0x84
-#define I2C_ADDR_TDA9887 0x86
-
-/*
- * i2c bus addresses for the chips supported by tvaudio.c
- */
-
-#define I2C_ADDR_TDA8425 0x82
-#define I2C_ADDR_TDA9840 0x84 /* also used by TA8874Z */
-#define I2C_ADDR_TDA985x_L 0xb4 /* also used by 9873 */
-#define I2C_ADDR_TDA985x_H 0xb6
-#define I2C_ADDR_TDA9874 0xb0 /* also used by 9875 */
-
-#define I2C_ADDR_TEA6300 0x80 /* also used by 6320 */
-#define I2C_ADDR_TEA6420 0x98
-
-#define I2C_ADDR_PIC16C54 0x96 /* PV951 */
diff --git a/include/media/i2c/as3645a.h b/include/media/i2c/as3645a.h
deleted file mode 100644
index fffd4b563f5a..000000000000
--- a/include/media/i2c/as3645a.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * include/media/i2c/as3645a.h
- *
- * Copyright (C) 2008-2011 Nokia Corporation
- *
- * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- */
-
-#ifndef __AS3645A_H__
-#define __AS3645A_H__
-
-#include <media/v4l2-subdev.h>
-
-#define AS3645A_NAME "as3645a"
-#define AS3645A_I2C_ADDR (0x60 >> 1) /* W:0x60, R:0x61 */
-
-#define AS3645A_FLASH_TIMEOUT_MIN 100000 /* us */
-#define AS3645A_FLASH_TIMEOUT_MAX 850000
-#define AS3645A_FLASH_TIMEOUT_STEP 50000
-
-#define AS3645A_FLASH_INTENSITY_MIN 200 /* mA */
-#define AS3645A_FLASH_INTENSITY_MAX_1LED 500
-#define AS3645A_FLASH_INTENSITY_MAX_2LEDS 400
-#define AS3645A_FLASH_INTENSITY_STEP 20
-
-#define AS3645A_TORCH_INTENSITY_MIN 20 /* mA */
-#define AS3645A_TORCH_INTENSITY_MAX 160
-#define AS3645A_TORCH_INTENSITY_STEP 20
-
-#define AS3645A_INDICATOR_INTENSITY_MIN 0 /* uA */
-#define AS3645A_INDICATOR_INTENSITY_MAX 10000
-#define AS3645A_INDICATOR_INTENSITY_STEP 2500
-
-/*
- * as3645a_platform_data - Flash controller platform data
- * @set_power: Set power callback
- * @vref: VREF offset (0=0V, 1=+0.3V, 2=-0.3V, 3=+0.6V)
- * @peak: Inductor peak current limit (0=1.25A, 1=1.5A, 2=1.75A, 3=2.0A)
- * @ext_strobe: True if external flash strobe can be used
- * @flash_max_current: Max flash current (mA, <= AS3645A_FLASH_INTENSITY_MAX)
- * @torch_max_current: Max torch current (mA, >= AS3645A_TORCH_INTENSITY_MAX)
- * @timeout_max: Max flash timeout (us, <= AS3645A_FLASH_TIMEOUT_MAX)
- */
-struct as3645a_platform_data {
- int (*set_power)(struct v4l2_subdev *subdev, int on);
- unsigned int vref;
- unsigned int peak;
- bool ext_strobe;
-
- /* Flash and torch currents and timeout limits */
- unsigned int flash_max_current;
- unsigned int torch_max_current;
- unsigned int timeout_max;
-};
-
-#endif /* __AS3645A_H__ */
diff --git a/include/media/i2c/bt819.h b/include/media/i2c/bt819.h
index 8025f4bc2bb6..1bcf0dbeb516 100644
--- a/include/media/i2c/bt819.h
+++ b/include/media/i2c/bt819.h
@@ -30,7 +30,7 @@
Note: these ioctls that internal to the kernel and are never called
from userspace. */
-#define BT819_FIFO_RESET_LOW _IO('b', 0)
-#define BT819_FIFO_RESET_HIGH _IO('b', 1)
+#define BT819_FIFO_RESET_LOW _IO('b', 0)
+#define BT819_FIFO_RESET_HIGH _IO('b', 1)
#endif
diff --git a/include/media/i2c/ir-kbd-i2c.h b/include/media/i2c/ir-kbd-i2c.h
index 76491c62c254..9f47d6a48cff 100644
--- a/include/media/i2c/ir-kbd-i2c.h
+++ b/include/media/i2c/ir-kbd-i2c.h
@@ -19,11 +19,15 @@ struct IR_i2c {
u32 polling_interval; /* in ms */
struct delayed_work work;
- char name[32];
char phys[32];
int (*get_key)(struct IR_i2c *ir,
enum rc_proto *protocol,
u32 *scancode, u8 *toggle);
+ /* tx */
+ struct i2c_client *tx_c;
+ struct mutex lock; /* do not poll Rx during Tx */
+ unsigned int carrier;
+ unsigned int duty_cycle;
};
enum ir_kbd_get_key_fn {
diff --git a/include/media/i2c/m52790.h b/include/media/i2c/m52790.h
index 7ddffae31a67..8d9db3cf6fab 100644
--- a/include/media/i2c/m52790.h
+++ b/include/media/i2c/m52790.h
@@ -23,57 +23,57 @@
/* Input routing switch 1 */
-#define M52790_SW1_IN_MASK 0x0003
-#define M52790_SW1_IN_TUNER 0x0000
-#define M52790_SW1_IN_V2 0x0001
-#define M52790_SW1_IN_V3 0x0002
-#define M52790_SW1_IN_V4 0x0003
+#define M52790_SW1_IN_MASK 0x0003
+#define M52790_SW1_IN_TUNER 0x0000
+#define M52790_SW1_IN_V2 0x0001
+#define M52790_SW1_IN_V3 0x0002
+#define M52790_SW1_IN_V4 0x0003
/* Selects component input instead of composite */
-#define M52790_SW1_YCMIX 0x0004
+#define M52790_SW1_YCMIX 0x0004
/* Input routing switch 2 */
-#define M52790_SW2_IN_MASK 0x0300
-#define M52790_SW2_IN_TUNER 0x0000
-#define M52790_SW2_IN_V2 0x0100
-#define M52790_SW2_IN_V3 0x0200
-#define M52790_SW2_IN_V4 0x0300
+#define M52790_SW2_IN_MASK 0x0300
+#define M52790_SW2_IN_TUNER 0x0000
+#define M52790_SW2_IN_V2 0x0100
+#define M52790_SW2_IN_V3 0x0200
+#define M52790_SW2_IN_V4 0x0300
/* Selects component input instead of composite */
-#define M52790_SW2_YCMIX 0x0400
+#define M52790_SW2_YCMIX 0x0400
/* Output routing switch 1 */
/* Enable 6dB amplifier for composite out */
-#define M52790_SW1_V_AMP 0x0008
+#define M52790_SW1_V_AMP 0x0008
/* Enable 6dB amplifier for component out */
-#define M52790_SW1_YC_AMP 0x0010
+#define M52790_SW1_YC_AMP 0x0010
/* Audio output mode */
-#define M52790_SW1_AUDIO_MASK 0x00c0
-#define M52790_SW1_AUDIO_MUTE 0x0000
-#define M52790_SW1_AUDIO_R 0x0040
-#define M52790_SW1_AUDIO_L 0x0080
+#define M52790_SW1_AUDIO_MASK 0x00c0
+#define M52790_SW1_AUDIO_MUTE 0x0000
+#define M52790_SW1_AUDIO_R 0x0040
+#define M52790_SW1_AUDIO_L 0x0080
#define M52790_SW1_AUDIO_STEREO 0x00c0
/* Output routing switch 2 */
/* Enable 6dB amplifier for composite out */
-#define M52790_SW2_V_AMP 0x0800
+#define M52790_SW2_V_AMP 0x0800
/* Enable 6dB amplifier for component out */
-#define M52790_SW2_YC_AMP 0x1000
+#define M52790_SW2_YC_AMP 0x1000
/* Audio output mode */
-#define M52790_SW2_AUDIO_MASK 0xc000
-#define M52790_SW2_AUDIO_MUTE 0x0000
-#define M52790_SW2_AUDIO_R 0x4000
-#define M52790_SW2_AUDIO_L 0x8000
+#define M52790_SW2_AUDIO_MASK 0xc000
+#define M52790_SW2_AUDIO_MUTE 0x0000
+#define M52790_SW2_AUDIO_R 0x4000
+#define M52790_SW2_AUDIO_L 0x8000
#define M52790_SW2_AUDIO_STEREO 0xc000
@@ -83,9 +83,9 @@
#define M52790_IN_V3 (M52790_SW1_IN_V3 | M52790_SW2_IN_V3)
#define M52790_IN_V4 (M52790_SW1_IN_V4 | M52790_SW2_IN_V4)
-#define M52790_OUT_STEREO (M52790_SW1_AUDIO_STEREO | \
+#define M52790_OUT_STEREO (M52790_SW1_AUDIO_STEREO | \
M52790_SW2_AUDIO_STEREO)
-#define M52790_OUT_AMP_STEREO (M52790_SW1_AUDIO_STEREO | \
+#define M52790_OUT_AMP_STEREO (M52790_SW1_AUDIO_STEREO | \
M52790_SW1_V_AMP | \
M52790_SW2_AUDIO_STEREO | \
M52790_SW2_V_AMP)
diff --git a/include/media/i2c/saa7115.h b/include/media/i2c/saa7115.h
index 53954c90e7f6..a0cda423509d 100644
--- a/include/media/i2c/saa7115.h
+++ b/include/media/i2c/saa7115.h
@@ -36,15 +36,15 @@
#define SAA7115_SVIDEO3 9
/* outputs */
-#define SAA7115_IPORT_ON 1
-#define SAA7115_IPORT_OFF 0
+#define SAA7115_IPORT_ON 1
+#define SAA7115_IPORT_OFF 0
/* SAA7111 specific outputs. */
-#define SAA7111_VBI_BYPASS 2
+#define SAA7111_VBI_BYPASS 2
#define SAA7111_FMT_YUV422 0x00
-#define SAA7111_FMT_RGB 0x40
-#define SAA7111_FMT_CCIR 0x80
-#define SAA7111_FMT_YUV411 0xc0
+#define SAA7111_FMT_RGB 0x40
+#define SAA7111_FMT_CCIR 0x80
+#define SAA7111_FMT_YUV411 0xc0
/* config flags */
/*
diff --git a/include/media/i2c/tvaudio.h b/include/media/i2c/tvaudio.h
index 1ac8184693f8..f13e1a386364 100644
--- a/include/media/i2c/tvaudio.h
+++ b/include/media/i2c/tvaudio.h
@@ -21,7 +21,22 @@
#ifndef _TVAUDIO_H
#define _TVAUDIO_H
-#include <media/i2c-addr.h>
+/*
+ * i2c bus addresses for the chips supported by tvaudio.c
+ */
+
+#define I2C_ADDR_TDA8425 0x82
+#define I2C_ADDR_TDA9840 0x84
+#define I2C_ADDR_TDA9874 0xb0 /* also used by 9875 */
+#define I2C_ADDR_TDA9875 0xb0
+#define I2C_ADDR_TDA8425 0x82
+#define I2C_ADDR_TDA9840 0x84 /* also used by TA8874Z */
+#define I2C_ADDR_TDA985x_L 0xb4 /* also used by 9873 */
+#define I2C_ADDR_TDA985x_H 0xb6
+#define I2C_ADDR_TDA9874 0xb0 /* also used by 9875 */
+#define I2C_ADDR_TEA6300 0x80 /* also used by 6320 */
+#define I2C_ADDR_TEA6420 0x98
+#define I2C_ADDR_PIC16C54 0x96 /* PV951 */
/* The tvaudio module accepts the following inputs: */
#define TVAUDIO_INPUT_TUNER 0
diff --git a/include/media/i2c/upd64031a.h b/include/media/i2c/upd64031a.h
index 48ec03c4ef23..1eba24dfee48 100644
--- a/include/media/i2c/upd64031a.h
+++ b/include/media/i2c/upd64031a.h
@@ -18,9 +18,9 @@
#define _UPD64031A_H_
/* Ghost reduction modes */
-#define UPD64031A_GR_ON 0
-#define UPD64031A_GR_OFF 1
-#define UPD64031A_GR_THROUGH 3
+#define UPD64031A_GR_ON 0
+#define UPD64031A_GR_OFF 1
+#define UPD64031A_GR_THROUGH 3
/* Direct 3D/YCS Connection */
#define UPD64031A_3DYCS_DISABLE (0 << 2)
diff --git a/include/media/lirc.h b/include/media/lirc.h
deleted file mode 100644
index 554988c860c1..000000000000
--- a/include/media/lirc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <uapi/linux/lirc.h>
diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h
deleted file mode 100644
index d9c143d17f70..000000000000
--- a/include/media/lirc_dev.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * LIRC base driver
- *
- * by Artur Lipowski <alipowski@interia.pl>
- * This code is licensed under GNU GPL
- *
- */
-
-#ifndef _LINUX_LIRC_DEV_H
-#define _LINUX_LIRC_DEV_H
-
-#define BUFLEN 16
-
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/ioctl.h>
-#include <linux/poll.h>
-#include <linux/kfifo.h>
-#include <media/lirc.h>
-#include <linux/device.h>
-#include <linux/cdev.h>
-
-struct lirc_buffer {
- wait_queue_head_t wait_poll;
- spinlock_t fifo_lock;
- unsigned int chunk_size;
- unsigned int size; /* in chunks */
- /* Using chunks instead of bytes pretends to simplify boundary checking
- * And should allow for some performance fine tunning later */
- struct kfifo fifo;
-};
-
-static inline void lirc_buffer_clear(struct lirc_buffer *buf)
-{
- unsigned long flags;
-
- if (kfifo_initialized(&buf->fifo)) {
- spin_lock_irqsave(&buf->fifo_lock, flags);
- kfifo_reset(&buf->fifo);
- spin_unlock_irqrestore(&buf->fifo_lock, flags);
- } else
- WARN(1, "calling %s on an uninitialized lirc_buffer\n",
- __func__);
-}
-
-static inline int lirc_buffer_init(struct lirc_buffer *buf,
- unsigned int chunk_size,
- unsigned int size)
-{
- int ret;
-
- init_waitqueue_head(&buf->wait_poll);
- spin_lock_init(&buf->fifo_lock);
- buf->chunk_size = chunk_size;
- buf->size = size;
- ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL);
-
- return ret;
-}
-
-static inline void lirc_buffer_free(struct lirc_buffer *buf)
-{
- if (kfifo_initialized(&buf->fifo)) {
- kfifo_free(&buf->fifo);
- } else
- WARN(1, "calling %s on an uninitialized lirc_buffer\n",
- __func__);
-}
-
-static inline int lirc_buffer_len(struct lirc_buffer *buf)
-{
- int len;
- unsigned long flags;
-
- spin_lock_irqsave(&buf->fifo_lock, flags);
- len = kfifo_len(&buf->fifo);
- spin_unlock_irqrestore(&buf->fifo_lock, flags);
-
- return len;
-}
-
-static inline int lirc_buffer_full(struct lirc_buffer *buf)
-{
- return lirc_buffer_len(buf) == buf->size * buf->chunk_size;
-}
-
-static inline int lirc_buffer_empty(struct lirc_buffer *buf)
-{
- return !lirc_buffer_len(buf);
-}
-
-static inline unsigned int lirc_buffer_read(struct lirc_buffer *buf,
- unsigned char *dest)
-{
- unsigned int ret = 0;
-
- if (lirc_buffer_len(buf) >= buf->chunk_size)
- ret = kfifo_out_locked(&buf->fifo, dest, buf->chunk_size,
- &buf->fifo_lock);
- return ret;
-
-}
-
-static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
- unsigned char *orig)
-{
- unsigned int ret;
-
- ret = kfifo_in_locked(&buf->fifo, orig, buf->chunk_size,
- &buf->fifo_lock);
-
- return ret;
-}
-
-/**
- * struct lirc_dev - represents a LIRC device
- *
- * @name: used for logging
- * @minor: the minor device (/dev/lircX) number for the device
- * @code_length: length of a remote control key code expressed in bits
- * @features: lirc compatible hardware features, like LIRC_MODE_RAW,
- * LIRC_CAN\_\*, as defined at include/media/lirc.h.
- * @buffer_size: Number of FIFO buffers with @chunk_size size.
- * Only used if @rbuf is NULL.
- * @chunk_size: Size of each FIFO buffer.
- * Only used if @rbuf is NULL.
- * @data: private per-driver data
- * @buf: if %NULL, lirc_dev will allocate and manage the buffer,
- * otherwise allocated by the caller which will
- * have to write to the buffer by other means, like irq's
- * (see also lirc_serial.c).
- * @buf_internal: whether lirc_dev has allocated the read buffer or not
- * @rdev: &struct rc_dev associated with the device
- * @fops: &struct file_operations for the device
- * @owner: the module owning this struct
- * @attached: if the device is still live
- * @open: open count for the device's chardev
- * @mutex: serialises file_operations calls
- * @dev: &struct device assigned to the device
- * @cdev: &struct cdev assigned to the device
- */
-struct lirc_dev {
- char name[40];
- unsigned int minor;
- __u32 code_length;
- __u32 features;
-
- unsigned int buffer_size; /* in chunks holding one code each */
- unsigned int chunk_size;
- struct lirc_buffer *buf;
- bool buf_internal;
-
- void *data;
- struct rc_dev *rdev;
- const struct file_operations *fops;
- struct module *owner;
-
- bool attached;
- int open;
-
- struct mutex mutex; /* protect from simultaneous accesses */
-
- struct device dev;
- struct cdev cdev;
-};
-
-struct lirc_dev *lirc_allocate_device(void);
-
-void lirc_free_device(struct lirc_dev *d);
-
-int lirc_register_device(struct lirc_dev *d);
-
-void lirc_unregister_device(struct lirc_dev *d);
-
-/* Must be called in the open fop before lirc_get_pdata() can be used */
-void lirc_init_pdata(struct inode *inode, struct file *file);
-
-/* Returns the private data stored in the lirc_dev
- * associated with the given device file pointer.
- */
-void *lirc_get_pdata(struct file *file);
-
-/* default file operations
- * used by drivers if they override only some operations
- */
-int lirc_dev_fop_open(struct inode *inode, struct file *file);
-int lirc_dev_fop_close(struct inode *inode, struct file *file);
-__poll_t lirc_dev_fop_poll(struct file *file, poll_table *wait);
-long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-ssize_t lirc_dev_fop_read(struct file *file, char __user *buffer, size_t length,
- loff_t *ppos);
-#endif
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
index 222d379960b7..a732af1dbba0 100644
--- a/include/media/media-entity.h
+++ b/include/media/media-entity.h
@@ -88,6 +88,8 @@ struct media_entity_enum {
* @stack: Graph traversal stack; the stack contains information
* on the path the media entities to be walked and the
* links through which they were reached.
+ * @stack.entity: pointer to &struct media_entity at the graph.
+ * @stack.link: pointer to &struct list_head.
* @ent_enum: Visited entities
* @top: The top of the stack
*/
@@ -247,6 +249,9 @@ enum media_entity_type {
* @pipe: Pipeline this entity belongs to.
* @info: Union with devnode information. Kept just for backward
* compatibility.
+ * @info.dev: Contains device major and minor info.
+ * @info.dev.major: device node major, if the device is a devnode.
+ * @info.dev.minor: device node minor, if the device is a devnode.
* @major: Devnode major number (zero if not applicable). Kept just
* for backward compatibility.
* @minor: Devnode minor number (zero if not applicable). Kept just
@@ -629,7 +634,11 @@ int media_entity_pads_init(struct media_entity *entity, u16 num_pads,
* This function must be called during the cleanup phase after unregistering
* the entity (currently, it does nothing).
*/
-static inline void media_entity_cleanup(struct media_entity *entity) {};
+#if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
+static inline void media_entity_cleanup(struct media_entity *entity) {}
+#else
+#define media_entity_cleanup(entity) do { } while (false)
+#endif
/**
* media_create_pad_link() - creates a link between two entities.
diff --git a/include/media/rc-core.h b/include/media/rc-core.h
index 314a1edb6189..aed4272d47f5 100644
--- a/include/media/rc-core.h
+++ b/include/media/rc-core.h
@@ -17,6 +17,7 @@
#define _RC_CORE
#include <linux/spinlock.h>
+#include <linux/cdev.h>
#include <linux/kfifo.h>
#include <linux/time.h>
#include <linux/timer.h>
@@ -30,9 +31,9 @@ do { \
} while (0)
/**
- * enum rc_driver_type - type of the RC output
+ * enum rc_driver_type - type of the RC driver.
*
- * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode
+ * @RC_DRIVER_SCANCODE: Driver or hardware generates a scancode.
* @RC_DRIVER_IR_RAW: Driver or hardware generates pulse/space sequences.
* It needs a Infra-Red pulse/space decoder
* @RC_DRIVER_IR_RAW_TX: Device transmitter only,
@@ -68,6 +69,33 @@ enum rc_filter_type {
};
/**
+ * struct lirc_fh - represents an open lirc file
+ * @list: list of open file handles
+ * @rc: rcdev for this lirc chardev
+ * @carrier_low: when setting the carrier range, first the low end must be
+ * set with an ioctl and then the high end with another ioctl
+ * @send_timeout_reports: report timeouts in lirc raw IR.
+ * @rawir: queue for incoming raw IR
+ * @scancodes: queue for incoming decoded scancodes
+ * @wait_poll: poll struct for lirc device
+ * @send_mode: lirc mode for sending, either LIRC_MODE_SCANCODE or
+ * LIRC_MODE_PULSE
+ * @rec_mode: lirc mode for receiving, either LIRC_MODE_SCANCODE or
+ * LIRC_MODE_MODE2
+ */
+struct lirc_fh {
+ struct list_head list;
+ struct rc_dev *rc;
+ int carrier_low;
+ bool send_timeout_reports;
+ DECLARE_KFIFO_PTR(rawir, unsigned int);
+ DECLARE_KFIFO_PTR(scancodes, struct lirc_scancode);
+ wait_queue_head_t wait_poll;
+ u8 send_mode;
+ u8 rec_mode;
+};
+
+/**
* struct rc_dev - represents a remote control device
* @dev: driver model's view of this device
* @managed_alloc: devm_rc_allocate_device was used to create rc_dev
@@ -106,6 +134,8 @@ enum rc_filter_type {
* @keypressed: whether a key is currently pressed
* @keyup_jiffies: time (in jiffies) when the current keypress should be released
* @timer_keyup: timer for releasing a keypress
+ * @timer_repeat: timer for autorepeat events. This is needed for CEC, which
+ * has non-standard repeats.
* @last_keycode: keycode of last keypress
* @last_protocol: protocol of last keypress
* @last_scancode: scancode of last keypress
@@ -115,6 +145,15 @@ enum rc_filter_type {
* @max_timeout: maximum timeout supported by device
* @rx_resolution : resolution (in ns) of input sampler
* @tx_resolution: resolution (in ns) of output sampler
+ * @lirc_dev: lirc device
+ * @lirc_cdev: lirc char cdev
+ * @gap_start: time when gap starts
+ * @gap_duration: duration of initial gap
+ * @gap: true if we're in a gap
+ * @lirc_fh_lock: protects lirc_fh list
+ * @lirc_fh: list of open files
+ * @registered: set to true by rc_register_device(), false by
+ * rc_unregister_device
* @change_protocol: allow changing the protocol used on hardware decoders
* @open: callback to allow drivers to enable polling/irq when IR input device
* is opened.
@@ -165,6 +204,7 @@ struct rc_dev {
bool keypressed;
unsigned long keyup_jiffies;
struct timer_list timer_keyup;
+ struct timer_list timer_repeat;
u32 last_keycode;
enum rc_proto last_protocol;
u32 last_scancode;
@@ -174,6 +214,16 @@ struct rc_dev {
u32 max_timeout;
u32 rx_resolution;
u32 tx_resolution;
+#ifdef CONFIG_LIRC
+ struct device lirc_dev;
+ struct cdev lirc_cdev;
+ ktime_t gap_start;
+ u64 gap_duration;
+ bool gap;
+ spinlock_t lirc_fh_lock;
+ struct list_head lirc_fh;
+#endif
+ bool registered;
int (*change_protocol)(struct rc_dev *dev, u64 *rc_proto);
int (*open)(struct rc_dev *dev);
void (*close)(struct rc_dev *dev);
@@ -248,20 +298,6 @@ int devm_rc_register_device(struct device *parent, struct rc_dev *dev);
*/
void rc_unregister_device(struct rc_dev *dev);
-/**
- * rc_open - Opens a RC device
- *
- * @rdev: pointer to struct rc_dev.
- */
-int rc_open(struct rc_dev *rdev);
-
-/**
- * rc_close - Closes a RC device
- *
- * @rdev: pointer to struct rc_dev.
- */
-void rc_close(struct rc_dev *rdev);
-
void rc_repeat(struct rc_dev *dev);
void rc_keydown(struct rc_dev *dev, enum rc_proto protocol, u32 scancode,
u8 toggle);
@@ -309,6 +345,7 @@ int ir_raw_event_store_with_filter(struct rc_dev *dev,
void ir_raw_event_set_idle(struct rc_dev *dev, bool idle);
int ir_raw_encode_scancode(enum rc_proto protocol, u32 scancode,
struct ir_raw_event *events, unsigned int max);
+int ir_raw_encode_carrier(enum rc_proto protocol);
static inline void ir_raw_event_reset(struct rc_dev *dev)
{
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 72197cb43781..7046734b3895 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -10,59 +10,7 @@
*/
#include <linux/input.h>
-
-/**
- * enum rc_proto - the Remote Controller protocol
- *
- * @RC_PROTO_UNKNOWN: Protocol not known
- * @RC_PROTO_OTHER: Protocol known but proprietary
- * @RC_PROTO_RC5: Philips RC5 protocol
- * @RC_PROTO_RC5X_20: Philips RC5x 20 bit protocol
- * @RC_PROTO_RC5_SZ: StreamZap variant of RC5
- * @RC_PROTO_JVC: JVC protocol
- * @RC_PROTO_SONY12: Sony 12 bit protocol
- * @RC_PROTO_SONY15: Sony 15 bit protocol
- * @RC_PROTO_SONY20: Sony 20 bit protocol
- * @RC_PROTO_NEC: NEC protocol
- * @RC_PROTO_NECX: Extended NEC protocol
- * @RC_PROTO_NEC32: NEC 32 bit protocol
- * @RC_PROTO_SANYO: Sanyo protocol
- * @RC_PROTO_MCIR2_KBD: RC6-ish MCE keyboard
- * @RC_PROTO_MCIR2_MSE: RC6-ish MCE mouse
- * @RC_PROTO_RC6_0: Philips RC6-0-16 protocol
- * @RC_PROTO_RC6_6A_20: Philips RC6-6A-20 protocol
- * @RC_PROTO_RC6_6A_24: Philips RC6-6A-24 protocol
- * @RC_PROTO_RC6_6A_32: Philips RC6-6A-32 protocol
- * @RC_PROTO_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol
- * @RC_PROTO_SHARP: Sharp protocol
- * @RC_PROTO_XMP: XMP protocol
- * @RC_PROTO_CEC: CEC protocol
- */
-enum rc_proto {
- RC_PROTO_UNKNOWN = 0,
- RC_PROTO_OTHER = 1,
- RC_PROTO_RC5 = 2,
- RC_PROTO_RC5X_20 = 3,
- RC_PROTO_RC5_SZ = 4,
- RC_PROTO_JVC = 5,
- RC_PROTO_SONY12 = 6,
- RC_PROTO_SONY15 = 7,
- RC_PROTO_SONY20 = 8,
- RC_PROTO_NEC = 9,
- RC_PROTO_NECX = 10,
- RC_PROTO_NEC32 = 11,
- RC_PROTO_SANYO = 12,
- RC_PROTO_MCIR2_KBD = 13,
- RC_PROTO_MCIR2_MSE = 14,
- RC_PROTO_RC6_0 = 15,
- RC_PROTO_RC6_6A_20 = 16,
- RC_PROTO_RC6_6A_24 = 17,
- RC_PROTO_RC6_6A_32 = 18,
- RC_PROTO_RC6_MCE = 19,
- RC_PROTO_SHARP = 20,
- RC_PROTO_XMP = 21,
- RC_PROTO_CEC = 22,
-};
+#include <uapi/linux/lirc.h>
#define RC_PROTO_BIT_NONE 0ULL
#define RC_PROTO_BIT_UNKNOWN BIT_ULL(RC_PROTO_UNKNOWN)
diff --git a/include/media/v4l2-tpg.h b/include/media/tpg/v4l2-tpg.h
index 13e49d85cae3..823fadede7bf 100644
--- a/include/media/v4l2-tpg.h
+++ b/include/media/tpg/v4l2-tpg.h
@@ -26,8 +26,51 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/videodev2.h>
-#include <media/v4l2-tpg-colors.h>
+struct tpg_rbg_color8 {
+ unsigned char r, g, b;
+};
+
+struct tpg_rbg_color16 {
+ __u16 r, g, b;
+};
+
+enum tpg_color {
+ TPG_COLOR_CSC_WHITE,
+ TPG_COLOR_CSC_YELLOW,
+ TPG_COLOR_CSC_CYAN,
+ TPG_COLOR_CSC_GREEN,
+ TPG_COLOR_CSC_MAGENTA,
+ TPG_COLOR_CSC_RED,
+ TPG_COLOR_CSC_BLUE,
+ TPG_COLOR_CSC_BLACK,
+ TPG_COLOR_75_YELLOW,
+ TPG_COLOR_75_CYAN,
+ TPG_COLOR_75_GREEN,
+ TPG_COLOR_75_MAGENTA,
+ TPG_COLOR_75_RED,
+ TPG_COLOR_75_BLUE,
+ TPG_COLOR_100_WHITE,
+ TPG_COLOR_100_YELLOW,
+ TPG_COLOR_100_CYAN,
+ TPG_COLOR_100_GREEN,
+ TPG_COLOR_100_MAGENTA,
+ TPG_COLOR_100_RED,
+ TPG_COLOR_100_BLUE,
+ TPG_COLOR_100_BLACK,
+ TPG_COLOR_TEXTFG,
+ TPG_COLOR_TEXTBG,
+ TPG_COLOR_RANDOM,
+ TPG_COLOR_RAMP,
+ TPG_COLOR_MAX = TPG_COLOR_RAMP + 256
+};
+
+extern const struct tpg_rbg_color8 tpg_colors[TPG_COLOR_MAX];
+extern const unsigned short tpg_rec709_to_linear[255 * 16 + 1];
+extern const unsigned short tpg_linear_to_rec709[255 * 16 + 1];
+extern const struct tpg_rbg_color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1]
+ [V4L2_XFER_FUNC_SMPTE2084 + 1]
+ [TPG_COLOR_CSC_BLACK + 1];
enum tpg_pattern {
TPG_PAT_75_COLORBAR,
TPG_PAT_100_COLORBAR,
diff --git a/include/media/tuner-types.h b/include/media/tuner-types.h
index 78f0654d9c3d..df76ac8e658c 100644
--- a/include/media/tuner-types.h
+++ b/include/media/tuner-types.h
@@ -171,6 +171,21 @@ struct tuner_params {
struct tuner_range *ranges;
};
+/**
+ * struct tunertype - describes the known tuners.
+ *
+ * @name: string with the tuner's name.
+ * @count: size of &struct tuner_params array.
+ * @params: pointer to &struct tuner_params array.
+ *
+ * @min: minimal tuner frequency, in 62.5 kHz step.
+ * should be multiplied to 16 to convert to MHz.
+ * @max: minimal tuner frequency, in 62.5 kHz step.
+ * Should be multiplied to 16 to convert to MHz.
+ * @stepsize: frequency step, in Hz.
+ * @initdata: optional byte sequence to initialize the tuner.
+ * @sleepdata: optional byte sequence to power down the tuner.
+ */
struct tunertype {
char *name;
unsigned int count;
diff --git a/include/media/v4l2-async.h b/include/media/v4l2-async.h
index 6152434cbe82..1592d323c577 100644
--- a/include/media/v4l2-async.h
+++ b/include/media/v4l2-async.h
@@ -28,7 +28,7 @@ struct v4l2_async_notifier;
* in order to identify a match
*
* @V4L2_ASYNC_MATCH_CUSTOM: Match will use the logic provided by &struct
- * v4l2_async_subdev.match ops
+ * v4l2_async_subdev.match ops
* @V4L2_ASYNC_MATCH_DEVNAME: Match will use the device name
* @V4L2_ASYNC_MATCH_I2C: Match will check for I2C adapter ID and address
* @V4L2_ASYNC_MATCH_FWNODE: Match will use firmware node
@@ -48,6 +48,31 @@ enum v4l2_async_match_type {
*
* @match_type: type of match that will be used
* @match: union of per-bus type matching data sets
+ * @match.fwnode:
+ * pointer to &struct fwnode_handle to be matched.
+ * Used if @match_type is %V4L2_ASYNC_MATCH_FWNODE.
+ * @match.device_name:
+ * string containing the device name to be matched.
+ * Used if @match_type is %V4L2_ASYNC_MATCH_DEVNAME.
+ * @match.i2c: embedded struct with I2C parameters to be matched.
+ * Both @match.i2c.adapter_id and @match.i2c.address
+ * should be matched.
+ * Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.i2c.adapter_id:
+ * I2C adapter ID to be matched.
+ * Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.i2c.address:
+ * I2C address to be matched.
+ * Used if @match_type is %V4L2_ASYNC_MATCH_I2C.
+ * @match.custom:
+ * Driver-specific match criteria.
+ * Used if @match_type is %V4L2_ASYNC_MATCH_CUSTOM.
+ * @match.custom.match:
+ * Driver-specific match function to be used if
+ * %V4L2_ASYNC_MATCH_CUSTOM.
+ * @match.custom.priv:
+ * Driver-specific private struct with match parameters
+ * to be used if %V4L2_ASYNC_MATCH_CUSTOM.
* @list: used to link struct v4l2_async_subdev objects, waiting to be
* probed, to a notifier->waiting list
*
@@ -58,12 +83,8 @@ enum v4l2_async_match_type {
struct v4l2_async_subdev {
enum v4l2_async_match_type match_type;
union {
- struct {
- struct fwnode_handle *fwnode;
- } fwnode;
- struct {
- const char *name;
- } device_name;
+ struct fwnode_handle *fwnode;
+ const char *device_name;
struct {
int adapter_id;
unsigned short address;
@@ -167,7 +188,7 @@ void v4l2_async_notifier_cleanup(struct v4l2_async_notifier *notifier);
/**
* v4l2_async_register_subdev - registers a sub-device to the asynchronous
- * subdevice framework
+ * subdevice framework
*
* @sd: pointer to &struct v4l2_subdev
*/
@@ -197,7 +218,7 @@ int __must_check v4l2_async_register_subdev_sensor_common(
/**
* v4l2_async_unregister_subdev - unregisters a sub-device to the asynchronous
- * subdevice framework
+ * subdevice framework
*
* @sd: pointer to &struct v4l2_subdev
*/
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index aac8b7b6e691..e0d95a7c5d48 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -28,7 +28,7 @@
#include <media/v4l2-dev.h>
-/* Common printk constucts for v4l-i2c drivers. These macros create a unique
+/* Common printk constructs for v4l-i2c drivers. These macros create a unique
prefix consisting of the driver name, the adapter number and the i2c
address. */
#define v4l_printk(level, name, adapter, addr, fmt, arg...) \
@@ -50,7 +50,7 @@
/* These three macros assume that the debug level is set with a module
parameter called 'debug'. */
#define v4l_dbg(level, debug, client, fmt, arg...) \
- do { \
+ do { \
if (debug >= (level)) \
v4l_client_printk(KERN_DEBUG, client, fmt , ## arg); \
} while (0)
@@ -80,9 +80,9 @@
/* These three macros assume that the debug level is set with a module
parameter called 'debug'. */
#define v4l2_dbg(level, debug, dev, fmt, arg...) \
- do { \
+ do { \
if (debug >= (level)) \
- v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); \
+ v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); \
} while (0)
/**
@@ -127,7 +127,7 @@ struct v4l2_subdev_ops;
* @client_type: name of the chip that's on the adapter.
* @addr: I2C address. If zero, it will use @probe_addrs
* @probe_addrs: array with a list of address. The last entry at such
- * array should be %I2C_CLIENT_END.
+ * array should be %I2C_CLIENT_END.
*
* returns a &struct v4l2_subdev pointer.
*/
@@ -146,7 +146,7 @@ struct i2c_board_info;
* @info: pointer to struct i2c_board_info used to replace the irq,
* platform_data and addr arguments.
* @probe_addrs: array with a list of address. The last entry at such
- * array should be %I2C_CLIENT_END.
+ * array should be %I2C_CLIENT_END.
*
* returns a &struct v4l2_subdev pointer.
*/
@@ -174,17 +174,43 @@ void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
*/
unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd);
+/**
+ * enum v4l2_i2c_tuner_type - specifies the range of tuner address that
+ * should be used when seeking for I2C devices.
+ *
+ * @ADDRS_RADIO: Radio tuner addresses.
+ * Represent the following I2C addresses:
+ * 0x10 (if compiled with tea5761 support)
+ * and 0x60.
+ * @ADDRS_DEMOD: Demod tuner addresses.
+ * Represent the following I2C addresses:
+ * 0x42, 0x43, 0x4a and 0x4b.
+ * @ADDRS_TV: TV tuner addresses.
+ * Represent the following I2C addresses:
+ * 0x42, 0x43, 0x4a, 0x4b, 0x60, 0x61, 0x62,
+ * 0x63 and 0x64.
+ * @ADDRS_TV_WITH_DEMOD: TV tuner addresses if demod is present, this
+ * excludes addresses used by the demodulator
+ * from the list of candidates.
+ * Represent the following I2C addresses:
+ * 0x60, 0x61, 0x62, 0x63 and 0x64.
+ *
+ * NOTE: All I2C addresses above use the 7-bit notation.
+ */
enum v4l2_i2c_tuner_type {
- ADDRS_RADIO, /* Radio tuner addresses */
- ADDRS_DEMOD, /* Demod tuner addresses */
- ADDRS_TV, /* TV tuner addresses */
- /* TV tuner addresses if demod is present, this excludes
- addresses used by the demodulator from the list of
- candidates. */
+ ADDRS_RADIO,
+ ADDRS_DEMOD,
+ ADDRS_TV,
ADDRS_TV_WITH_DEMOD,
};
-/* Return a list of I2C tuner addresses to probe. Use only if the tuner
- addresses are unknown. */
+/**
+ * v4l2_i2c_tuner_addrs - Return a list of I2C tuner addresses to probe.
+ *
+ * @type: type of the tuner to seek, as defined by
+ * &enum v4l2_i2c_tuner_type.
+ *
+ * NOTE: Use only if the tuner addresses are unknown.
+ */
const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type);
/* ------------------------------------------------------------------------- */
@@ -224,10 +250,14 @@ void v4l2_spi_subdev_init(struct v4l2_subdev *sd, struct spi_device *spi,
/* ------------------------------------------------------------------------- */
-/* Note: these remaining ioctls/structs should be removed as well, but they are
- still used in tuner-simple.c (TUNER_SET_CONFIG), cx18/ivtv (RESET) and
- v4l2-int-device.h (v4l2_routing). To remove these ioctls some more cleanup
- is needed in those modules. */
+/*
+ * FIXME: these remaining ioctls/structs should be removed as well, but they
+ * are still used in tuner-simple.c (TUNER_SET_CONFIG) and cx18/ivtv (RESET).
+ * To remove these ioctls some more cleanup is needed in those modules.
+ *
+ * It doesn't make much sense on documenting them, as what we really want is
+ * to get rid of them.
+ */
/* s_config */
struct v4l2_priv_tun_config {
@@ -236,32 +266,79 @@ struct v4l2_priv_tun_config {
};
#define TUNER_SET_CONFIG _IOW('d', 92, struct v4l2_priv_tun_config)
-#define VIDIOC_INT_RESET _IOW ('d', 102, u32)
-
-struct v4l2_routing {
- u32 input;
- u32 output;
-};
+#define VIDIOC_INT_RESET _IOW ('d', 102, u32)
/* ------------------------------------------------------------------------- */
/* Miscellaneous helper functions */
-void v4l_bound_align_image(unsigned int *w, unsigned int wmin,
+/**
+ * v4l_bound_align_image - adjust video dimensions according to
+ * a given constraints.
+ *
+ * @width: pointer to width that will be adjusted if needed.
+ * @wmin: minimum width.
+ * @wmax: maximum width.
+ * @walign: least significant bit on width.
+ * @height: pointer to height that will be adjusted if needed.
+ * @hmin: minimum height.
+ * @hmax: maximum height.
+ * @halign: least significant bit on width.
+ * @salign: least significant bit for the image size (e. g.
+ * :math:`width * height`).
+ *
+ * Clip an image to have @width between @wmin and @wmax, and @height between
+ * @hmin and @hmax, inclusive.
+ *
+ * Additionally, the @width will be a multiple of :math:`2^{walign}`,
+ * the @height will be a multiple of :math:`2^{halign}`, and the overall
+ * size :math:`width * height` will be a multiple of :math:`2^{salign}`.
+ *
+ * .. note::
+ *
+ * #. The clipping rectangle may be shrunk or enlarged to fit the alignment
+ * constraints.
+ * #. @wmax must not be smaller than @wmin.
+ * #. @hmax must not be smaller than @hmin.
+ * #. The alignments must not be so high there are no possible image
+ * sizes within the allowed bounds.
+ * #. @wmin and @hmin must be at least 1 (don't use 0).
+ * #. For @walign, @halign and @salign, if you don't care about a certain
+ * alignment, specify ``0``, as :math:`2^0 = 1` and one byte alignment
+ * is equivalent to no alignment.
+ * #. If you only want to adjust downward, specify a maximum that's the
+ * same as the initial value.
+ */
+void v4l_bound_align_image(unsigned int *width, unsigned int wmin,
unsigned int wmax, unsigned int walign,
- unsigned int *h, unsigned int hmin,
+ unsigned int *height, unsigned int hmin,
unsigned int hmax, unsigned int halign,
unsigned int salign);
-struct v4l2_discrete_probe {
- const struct v4l2_frmsize_discrete *sizes;
- int num_sizes;
-};
-
-const struct v4l2_frmsize_discrete *v4l2_find_nearest_format(
- const struct v4l2_discrete_probe *probe,
- s32 width, s32 height);
+/**
+ * v4l2_find_nearest_format - find the nearest format size among a discrete
+ * set of resolutions.
+ *
+ * @sizes: array of &struct v4l2_frmsize_discrete image sizes.
+ * @num_sizes: length of @sizes array.
+ * @width: desired width.
+ * @height: desired height.
+ *
+ * Finds the closest resolution to minimize the width and height differences
+ * between what requested and the supported resolutions.
+ */
+const struct v4l2_frmsize_discrete *
+v4l2_find_nearest_format(const struct v4l2_frmsize_discrete *sizes,
+ const size_t num_sizes,
+ s32 width, s32 height);
+/**
+ * v4l2_get_timestamp - helper routine to get a timestamp to be used when
+ * filling streaming metadata. Internally, it uses ktime_get_ts(),
+ * which is the recommended way to get it.
+ *
+ * @tv: pointer to &struct timeval to be filled.
+ */
void v4l2_get_timestamp(struct timeval *tv);
#endif /* V4L2_COMMON_H_ */
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index a9ced6bbee55..05ebb9ef9e73 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -166,8 +166,15 @@ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv);
* empty strings ("") correspond to non-existing menu items (this
* is in addition to the menu_skip_mask above). The last entry
* must be NULL.
+ * Used only if the @type is %V4L2_CTRL_TYPE_MENU.
+ * @qmenu_int: A 64-bit integer array for with integer menu items.
+ * The size of array must be equal to the menu size, e. g.:
+ * :math:`ceil(\frac{maximum - minimum}{step}) + 1`.
+ * Used only if the @type is %V4L2_CTRL_TYPE_INTEGER_MENU.
* @flags: The control's flags.
- * @cur: The control's current value.
+ * @cur: Structure to store the current value.
+ * @cur.val: The control's current value, if the @type is represented via
+ * a u32 integer (see &enum v4l2_ctrl_type).
* @val: The control's new s32 value.
* @priv: The control's private pointer. For use by the driver. It is
* untouched by the control framework. Note that this pointer is
@@ -1139,7 +1146,7 @@ int v4l2_s_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl,
/**
* v4l2_ctrl_subdev_subscribe_event - Helper function to implement
- * as a &struct v4l2_subdev_core_ops subscribe_event function
+ * as a &struct v4l2_subdev_core_ops subscribe_event function
* that just subscribes control events.
*
* @sd: pointer to &struct v4l2_subdev
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index fa99f6f66712..53f32022fabe 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -21,31 +21,63 @@
#define VIDEO_MAJOR 81
-#define VFL_TYPE_GRABBER 0
-#define VFL_TYPE_VBI 1
-#define VFL_TYPE_RADIO 2
-#define VFL_TYPE_SUBDEV 3
-#define VFL_TYPE_SDR 4
-#define VFL_TYPE_TOUCH 5
-#define VFL_TYPE_MAX 6
-
-/* 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
+/**
+ * enum vfl_devnode_type - type of V4L2 device node
+ *
+ * @VFL_TYPE_GRABBER: for video input/output devices
+ * @VFL_TYPE_VBI: for vertical blank data (i.e. closed captions, teletext)
+ * @VFL_TYPE_RADIO: for radio tuners
+ * @VFL_TYPE_SUBDEV: for V4L2 subdevices
+ * @VFL_TYPE_SDR: for Software Defined Radio tuners
+ * @VFL_TYPE_TOUCH: for touch sensors
+ */
+enum vfl_devnode_type {
+ VFL_TYPE_GRABBER = 0,
+ VFL_TYPE_VBI = 1,
+ VFL_TYPE_RADIO = 2,
+ VFL_TYPE_SUBDEV = 3,
+ VFL_TYPE_SDR = 4,
+ VFL_TYPE_TOUCH = 5,
+};
+#define VFL_TYPE_MAX VFL_TYPE_TOUCH
+
+/**
+ * enum vfl_direction - Identifies if a &struct video_device corresponds
+ * to a receiver, a transmitter or a mem-to-mem device.
+ *
+ * @VFL_DIR_RX: device is a receiver.
+ * @VFL_DIR_TX: device is a transmitter.
+ * @VFL_DIR_M2M: device is a memory to memory device.
+ *
+ * Note: Ignored if &enum vfl_devnode_type is %VFL_TYPE_SUBDEV.
+ */
+enum vfl_devnode_direction {
+ VFL_DIR_RX,
+ VFL_DIR_TX,
+ VFL_DIR_M2M,
+};
struct v4l2_ioctl_callbacks;
struct video_device;
struct v4l2_device;
struct v4l2_ctrl_handler;
-/* Flag to mark the video_device struct as registered.
- Drivers can clear this flag if they want to block all future
- device access. It is cleared by video_unregister_device. */
-#define V4L2_FL_REGISTERED (0)
-/* file->private_data points to struct v4l2_fh */
-#define V4L2_FL_USES_V4L2_FH (1)
+/**
+ * enum v4l2_video_device_flags - Flags used by &struct video_device
+ *
+ * @V4L2_FL_REGISTERED:
+ * indicates that a &struct video_device is registered.
+ * Drivers can clear this flag if they want to block all future
+ * device access. It is cleared by video_unregister_device.
+ * @V4L2_FL_USES_V4L2_FH:
+ * indicates that file->private_data points to &struct v4l2_fh.
+ * This flag is set by the core when v4l2_fh_init() is called.
+ * All new drivers should use it.
+ */
+enum v4l2_video_device_flags {
+ V4L2_FL_REGISTERED = 0,
+ V4L2_FL_USES_V4L2_FH = 1,
+};
/* Priority helper functions */
@@ -166,7 +198,7 @@ struct v4l2_file_operations {
/*
* Newer version of video_device, handled by videodev2.c
- * This version moves redundant code from video device code to
+ * This version moves redundant code from video device code to
* the common handler
*/
@@ -189,11 +221,12 @@ struct v4l2_file_operations {
* @prio: pointer to &struct v4l2_prio_state with device's Priority state.
* If NULL, then v4l2_dev->prio will be used.
* @name: video device name
- * @vfl_type: V4L device type
+ * @vfl_type: V4L device type, as defined by &enum vfl_devnode_type
* @vfl_dir: V4L receiver, transmitter or m2m
* @minor: device node 'minor'. It is set to -1 if the registration failed
* @num: number of the video device node
- * @flags: video device flags. Use bitops to set/clear/test flags
+ * @flags: video device flags. Use bitops to set/clear/test flags.
+ * Contains a set of &enum v4l2_video_device_flags.
* @index: attribute to differentiate multiple indices on one physical device
* @fh_lock: Lock for all v4l2_fhs
* @fh_list: List of &struct v4l2_fh
@@ -237,8 +270,8 @@ struct video_device
/* device info */
char name[32];
- int vfl_type;
- int vfl_dir;
+ enum vfl_devnode_type vfl_type;
+ enum vfl_devnode_direction vfl_dir;
int minor;
u16 num;
unsigned long flags;
@@ -261,18 +294,30 @@ struct video_device
struct mutex *lock;
};
-#define media_entity_to_video_device(__e) \
- container_of(__e, struct video_device, entity)
-/* dev to video-device */
+/**
+ * media_entity_to_video_device - Returns a &struct video_device from
+ * the &struct media_entity embedded on it.
+ *
+ * @entity: pointer to &struct media_entity
+ */
+#define media_entity_to_video_device(entity) \
+ container_of(entity, struct video_device, entity)
+
+/**
+ * to_video_device - Returns a &struct video_device from the
+ * &struct device embedded on it.
+ *
+ * @cd: pointer to &struct device
+ */
#define to_video_device(cd) container_of(cd, struct video_device, dev)
/**
* __video_register_device - register video4linux devices
*
* @vdev: struct video_device to register
- * @type: type of device to register
+ * @type: type of device to register, as defined by &enum vfl_devnode_type
* @nr: which device node number is desired:
- * (0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ * (0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
* @warn_if_nr_in_use: warn if the desired device node number
* was already in use and another number was chosen instead.
* @owner: module that owns the video device node
@@ -289,43 +334,37 @@ struct video_device
*
* Returns 0 on success.
*
- * Valid values for @type are:
- *
- * - %VFL_TYPE_GRABBER - A frame grabber
- * - %VFL_TYPE_VBI - Vertical blank data (undecoded)
- * - %VFL_TYPE_RADIO - A radio card
- * - %VFL_TYPE_SUBDEV - A subdevice
- * - %VFL_TYPE_SDR - Software Defined Radio
- * - %VFL_TYPE_TOUCH - A touch sensor
- *
* .. note::
*
* This function is meant to be used only inside the V4L2 core.
* Drivers should use video_register_device() or
* video_register_device_no_warn().
*/
-int __must_check __video_register_device(struct video_device *vdev, int type,
- int nr, int warn_if_nr_in_use, struct module *owner);
+int __must_check __video_register_device(struct video_device *vdev,
+ enum vfl_devnode_type type,
+ int nr, int warn_if_nr_in_use,
+ struct module *owner);
/**
* video_register_device - register video4linux devices
*
* @vdev: struct video_device to register
- * @type: type of device to register
+ * @type: type of device to register, as defined by &enum vfl_devnode_type
* @nr: which device node number is desired:
- * (0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ * (0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
*
* Internally, it calls __video_register_device(). Please see its
* documentation for more details.
*
* .. note::
- * if video_register_device fails, the release() callback of
+ * if video_register_device fails, the release() callback of
* &struct video_device structure is *not* called, so the caller
* is responsible for freeing any data. Usually that means that
* you video_device_release() should be called on failure.
*/
static inline int __must_check video_register_device(struct video_device *vdev,
- int type, int nr)
+ enum vfl_devnode_type type,
+ int nr)
{
return __video_register_device(vdev, type, nr, 1, vdev->fops->owner);
}
@@ -334,9 +373,9 @@ static inline int __must_check video_register_device(struct video_device *vdev,
* video_register_device_no_warn - register video4linux devices
*
* @vdev: struct video_device to register
- * @type: type of device to register
+ * @type: type of device to register, as defined by &enum vfl_devnode_type
* @nr: which device node number is desired:
- * (0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
+ * (0 == /dev/video0, 1 == /dev/video1, ..., -1 == first free)
*
* This function is identical to video_register_device() except that no
* warning is issued if the desired device node number was already in use.
@@ -345,13 +384,14 @@ static inline int __must_check video_register_device(struct video_device *vdev,
* documentation for more details.
*
* .. note::
- * if video_register_device fails, the release() callback of
+ * if video_register_device fails, the release() callback of
* &struct video_device structure is *not* called, so the caller
* is responsible for freeing any data. Usually that means that
* you video_device_release() should be called on failure.
*/
-static inline int __must_check video_register_device_no_warn(
- struct video_device *vdev, int type, int nr)
+static inline int __must_check
+video_register_device_no_warn(struct video_device *vdev,
+ enum vfl_devnode_type type, int nr)
{
return __video_register_device(vdev, type, nr, 0, vdev->fops->owner);
}
@@ -383,7 +423,7 @@ void video_device_release(struct video_device *vdev);
/**
* video_device_release_empty - helper function to implement the
- * video_device->release\(\) callback.
+ * video_device->release\(\) callback.
*
* @vdev: pointer to &struct video_device
*
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 8ffa94009d1a..0c9e4da55499 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -38,7 +38,7 @@ struct v4l2_ctrl_handler;
* @lock: lock this struct; can be used by the driver as well
* if this struct is embedded into a larger struct.
* @name: unique device name, by default the driver name + bus ID
- * @notify: notify callback called by some sub-devices.
+ * @notify: notify operation called by some sub-devices.
* @ctrl_handler: The control handler. May be %NULL.
* @prio: Device's priority state
* @ref: Keep track of the references to this struct.
@@ -56,7 +56,6 @@ struct v4l2_ctrl_handler;
* #) @dev->driver_data points to this struct.
* #) @dev might be %NULL if there is no parent device
*/
-
struct v4l2_device {
struct device *dev;
#if defined(CONFIG_MEDIA_CONTROLLER)
@@ -166,7 +165,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev);
* v4l2_device_register_subdev - Registers a subdev with a v4l2 device.
*
* @v4l2_dev: pointer to struct &v4l2_device
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
*
* While registered, the subdev module is marked as in-use.
*
@@ -179,7 +178,7 @@ int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
/**
* v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device.
*
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
*
* .. note ::
*
@@ -201,7 +200,7 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
/**
* v4l2_subdev_notify - Sends a notification to v4l2_device.
*
- * @sd: pointer to struct &v4l2_subdev
+ * @sd: pointer to &struct v4l2_subdev
* @notification: type of notification. Please notice that the notification
* type is driver-specific.
* @arg: arguments for the notification. Those are specific to each
@@ -214,13 +213,43 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
sd->v4l2_dev->notify(sd, notification, arg);
}
-/* Iterate over all subdevs. */
+/* Helper macros to iterate over all subdevs. */
+
+/**
+ * v4l2_device_for_each_subdev - Helper macro that interates over all
+ * sub-devices of a given &v4l2_device.
+ *
+ * @sd: pointer that will be filled by the macro with all
+ * &struct v4l2_subdev pointer used as an iterator by the loop.
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ *
+ * This macro iterates over all sub-devices owned by the @v4l2_dev device.
+ * It acts as a for loop iterator and executes the next statement with
+ * the @sd variable pointing to each sub-device in turn.
+ */
#define v4l2_device_for_each_subdev(sd, v4l2_dev) \
list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
-/* Call the specified callback for all subdevs matching the condition.
- Ignore any errors. Note that you cannot add or delete a subdev
- while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_p - Calls the specified operation for
+ * all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @sd: pointer that will be filled by the macro with all
+ * &struct v4l2_subdev pointer used as an iterator by the loop.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * The operation functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
#define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...) \
do { \
list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) \
@@ -228,6 +257,24 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
(sd)->ops->o->f((sd) , ##args); \
} while (0)
+/**
+ * __v4l2_device_call_subdevs - Calls the specified operation for
+ * all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * The operation functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
#define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \
do { \
struct v4l2_subdev *__sd; \
@@ -236,10 +283,30 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
f , ##args); \
} while (0)
-/* Call the specified callback for all subdevs matching the condition.
- If the callback returns an error other than 0 or -ENOIOCTLCMD, then
- return with that error code. Note that you cannot add or delete a
- subdev while walking the subdevs list. */
+/**
+ * __v4l2_device_call_subdevs_until_err_p - Calls the specified operation for
+ * all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @sd: pointer that will be filled by the macro with all
+ * &struct v4l2_subdev sub-devices associated with @v4l2_dev.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * The operation functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code, zero
+ * otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
#define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \
({ \
long __err = 0; \
@@ -253,6 +320,28 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
(__err == -ENOIOCTLCMD) ? 0 : __err; \
})
+/**
+ * __v4l2_device_call_subdevs_until_err - Calls the specified operation for
+ * all subdevs matching the condition.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @cond: condition to be match
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * The operation functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
#define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \
({ \
struct v4l2_subdev *__sd; \
@@ -260,9 +349,26 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
f , ##args); \
})
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
- match them all). Ignore any errors. Note that you cannot add or delete
- a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_all - Calls the specified operation for
+ * all subdevs matching the &v4l2_subdev.grp_id, as assigned
+ * by the bridge driver.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * The operation functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
#define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \
do { \
struct v4l2_subdev *__sd; \
@@ -272,10 +378,30 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
##args); \
} while (0)
-/* Call the specified callback for all subdevs matching grp_id (if 0, then
- match them all). If the callback returns an error other than 0 or
- -ENOIOCTLCMD, then return with that error code. Note that you cannot
- add or delete a subdev while walking the subdevs list. */
+/**
+ * v4l2_device_call_until_err - Calls the specified operation for
+ * all subdevs matching the &v4l2_subdev.grp_id, as assigned
+ * by the bridge driver, until an error occurs.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * The operation functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
+ */
#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \
({ \
struct v4l2_subdev *__sd; \
@@ -284,10 +410,24 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
##args); \
})
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == `0, then match them all). Ignore any errors. Note that you
- * cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_all - Calls the specified operation for
+ * all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ * group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * The operation functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Ignore any errors.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
*/
#define v4l2_device_mask_call_all(v4l2_dev, grpmsk, o, f, args...) \
do { \
@@ -298,11 +438,28 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
##args); \
} while (0)
-/*
- * Call the specified callback for all subdevs where grp_id & grpmsk != 0
- * (if grpmsk == 0, then match them all). If the callback returns an error
- * other than 0 or %-ENOIOCTLCMD, then return with that error code. Note that
- * you cannot add or delete a subdev while walking the subdevs list.
+/**
+ * v4l2_device_mask_call_until_err - Calls the specified operation for
+ * all subdevices where a group ID matches a specified bitmask.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ * group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * The operation functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
+ * @args...: arguments for @f.
+ *
+ * Return:
+ *
+ * If the operation returns an error other than 0 or ``-ENOIOCTLCMD``
+ * for any subdevice, then abort and return with that error code,
+ * zero otherwise.
+ *
+ * Note: subdevs cannot be added or deleted while walking
+ * the subdevs list.
*/
#define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \
({ \
@@ -312,9 +469,19 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
##args); \
})
-/*
- * Does any subdev with matching grpid (or all if grpid == 0) has the given
- * op?
+
+/**
+ * v4l2_device_has_op - checks if any subdev with matching grpid has a
+ * given ops.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpid: &struct v4l2_subdev->grp_id group ID to match.
+ * Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * The operation functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
*/
#define v4l2_device_has_op(v4l2_dev, grpid, o, f) \
({ \
@@ -331,9 +498,18 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd,
__result; \
})
-/*
- * Does any subdev with matching grpmsk (or all if grpmsk == 0) has the given
- * op?
+/**
+ * v4l2_device_mask_has_op - checks if any subdev with matching group
+ * mask has a given ops.
+ *
+ * @v4l2_dev: &struct v4l2_device owning the sub-devices to iterate over.
+ * @grpmsk: bitmask to be checked against &struct v4l2_subdev->grp_id
+ * group ID to be matched. Use 0 to match them all.
+ * @o: name of the element at &struct v4l2_subdev_ops that contains @f.
+ * Each element there groups a set of operations functions.
+ * @f: operation function that will be called if @cond matches.
+ * The operation functions are defined in groups, according to
+ * each element at &struct v4l2_subdev_ops.
*/
#define v4l2_device_mask_has_op(v4l2_dev, grpmsk, o, f) \
({ \
diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h
index 61a18893e004..ebf00e07a515 100644
--- a/include/media/v4l2-dv-timings.h
+++ b/include/media/v4l2-dv-timings.h
@@ -203,13 +203,15 @@ struct v4l2_fract v4l2_calc_aspect_ratio(u8 hor_landscape, u8 vert_portrait);
*/
struct v4l2_fract v4l2_dv_timings_aspect_ratio(const struct v4l2_dv_timings *t);
-/*
- * reduce_fps - check if conditions for reduced fps are true.
- * bt - v4l2 timing structure
- * For different timings reduced fps is allowed if following conditions
- * are met -
- * For CVT timings: if reduced blanking v2 (vsync == 8) is true.
- * For CEA861 timings: if V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
+/**
+ * can_reduce_fps - check if conditions for reduced fps are true.
+ * @bt: v4l2 timing structure
+ *
+ * For different timings reduced fps is allowed if the following conditions
+ * are met:
+ *
+ * - For CVT timings: if reduced blanking v2 (vsync == 8) is true.
+ * - For CEA861 timings: if %V4L2_DV_FL_CAN_REDUCE_FPS flag is true.
*/
static inline bool can_reduce_fps(struct v4l2_bt_timings *bt)
{
diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h
index 6741910c3a18..17833e886e11 100644
--- a/include/media/v4l2-event.h
+++ b/include/media/v4l2-event.h
@@ -24,40 +24,6 @@
#include <linux/videodev2.h>
#include <linux/wait.h>
-/*
- * Overview:
- *
- * Events are subscribed per-filehandle. An event specification consists of a
- * type and is optionally associated with an object identified through the
- * 'id' field. So an event is uniquely identified by the (type, id) tuple.
- *
- * The v4l2-fh struct has a list of subscribed events. The v4l2_subscribed_event
- * struct is added to that list, one for every subscribed event.
- *
- * Each v4l2_subscribed_event struct ends with an array of v4l2_kevent structs.
- * This array (ringbuffer, really) is used to store any events raised by the
- * driver. The v4l2_kevent struct links into the 'available' list of the
- * v4l2_fh struct so VIDIOC_DQEVENT will know which event to dequeue first.
- *
- * Finally, if the event subscription is associated with a particular object
- * such as a V4L2 control, then that object needs to know about that as well
- * so that an event can be raised by that object. So the 'node' field can
- * be used to link the v4l2_subscribed_event struct into a list of that
- * object.
- *
- * So to summarize:
- *
- * struct v4l2_fh has two lists: one of the subscribed events, and one of the
- * pending events.
- *
- * struct v4l2_subscribed_event has a ringbuffer of raised (pending) events of
- * that particular type.
- *
- * If struct v4l2_subscribed_event is associated with a specific object, then
- * that object will have an internal list of struct v4l2_subscribed_event so
- * it knows who subscribed an event to that object.
- */
-
struct v4l2_fh;
struct v4l2_subdev;
struct v4l2_subscribed_event;
@@ -218,7 +184,7 @@ int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd,
struct v4l2_event_subscription *sub);
/**
* v4l2_src_change_event_subscribe - helper function that calls
- * v4l2_event_subscribe() if the event is %V4L2_EVENT_SOURCE_CHANGE.
+ * v4l2_event_subscribe() if the event is %V4L2_EVENT_SOURCE_CHANGE.
*
* @fh: pointer to struct v4l2_fh
* @sub: pointer to &struct v4l2_event_subscription
diff --git a/include/media/v4l2-flash-led-class.h b/include/media/v4l2-flash-led-class.h
index 5c1d50f78e12..0a5e4518ca11 100644
--- a/include/media/v4l2-flash-led-class.h
+++ b/include/media/v4l2-flash-led-class.h
@@ -91,12 +91,24 @@ struct v4l2_flash {
struct v4l2_ctrl **ctrls;
};
+/**
+ * v4l2_subdev_to_v4l2_flash - Returns a &struct v4l2_flash from the
+ * &struct v4l2_subdev embedded on it.
+ *
+ * @sd: pointer to &struct v4l2_subdev
+ */
static inline struct v4l2_flash *v4l2_subdev_to_v4l2_flash(
struct v4l2_subdev *sd)
{
return container_of(sd, struct v4l2_flash, sd);
}
+/**
+ * v4l2_ctrl_to_v4l2_flash - Returns a &struct v4l2_flash from the
+ * &struct v4l2_ctrl embedded on it.
+ *
+ * @c: pointer to &struct v4l2_ctrl
+ */
static inline struct v4l2_flash *v4l2_ctrl_to_v4l2_flash(struct v4l2_ctrl *c)
{
return container_of(c->handler, struct v4l2_flash, hdl);
diff --git a/include/media/v4l2-fwnode.h b/include/media/v4l2-fwnode.h
index b5b465677d28..c228ec1c77cf 100644
--- a/include/media/v4l2-fwnode.h
+++ b/include/media/v4l2-fwnode.h
@@ -81,7 +81,17 @@ struct v4l2_fwnode_bus_mipi_csi1 {
* struct v4l2_fwnode_endpoint - the endpoint data structure
* @base: fwnode endpoint of the v4l2_fwnode
* @bus_type: bus type
- * @bus: bus configuration data structure
+ * @bus: union with bus configuration data structure
+ * @bus.parallel: embedded &struct v4l2_fwnode_bus_parallel.
+ * Used if the bus is parallel.
+ * @bus.mipi_csi1: embedded &struct v4l2_fwnode_bus_mipi_csi1.
+ * Used if the bus is MIPI Alliance's Camera Serial
+ * Interface version 1 (MIPI CSI1) or Standard
+ * Mobile Imaging Architecture's Compact Camera Port 2
+ * (SMIA CCP2).
+ * @bus.mipi_csi2: embedded &struct v4l2_fwnode_bus_mipi_csi2.
+ * Used if the bus is MIPI Alliance's Camera Serial
+ * Interface version 2 (MIPI CSI2).
* @link_frequencies: array of supported link frequencies
* @nr_of_link_frequencies: number of elements in link_frequenccies array
*/
diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h
index 93f8afcb7a22..4d8626c468bc 100644
--- a/include/media/v4l2-mediabus.h
+++ b/include/media/v4l2-mediabus.h
@@ -12,6 +12,8 @@
#define V4L2_MEDIABUS_H
#include <linux/v4l2-mediabus.h>
+#include <linux/bitops.h>
+
/* Parallel flags */
/*
@@ -20,44 +22,44 @@
* horizontal and vertical synchronisation. In "Slave mode" the host is
* providing these signals to the slave.
*/
-#define V4L2_MBUS_MASTER (1 << 0)
-#define V4L2_MBUS_SLAVE (1 << 1)
+#define V4L2_MBUS_MASTER BIT(0)
+#define V4L2_MBUS_SLAVE BIT(1)
/*
* Signal polarity flags
* Note: in BT.656 mode HSYNC, FIELD, and VSYNC are unused
* V4L2_MBUS_[HV]SYNC* flags should be also used for specifying
* configuration of hardware that uses [HV]REF signals
*/
-#define V4L2_MBUS_HSYNC_ACTIVE_HIGH (1 << 2)
-#define V4L2_MBUS_HSYNC_ACTIVE_LOW (1 << 3)
-#define V4L2_MBUS_VSYNC_ACTIVE_HIGH (1 << 4)
-#define V4L2_MBUS_VSYNC_ACTIVE_LOW (1 << 5)
-#define V4L2_MBUS_PCLK_SAMPLE_RISING (1 << 6)
-#define V4L2_MBUS_PCLK_SAMPLE_FALLING (1 << 7)
-#define V4L2_MBUS_DATA_ACTIVE_HIGH (1 << 8)
-#define V4L2_MBUS_DATA_ACTIVE_LOW (1 << 9)
+#define V4L2_MBUS_HSYNC_ACTIVE_HIGH BIT(2)
+#define V4L2_MBUS_HSYNC_ACTIVE_LOW BIT(3)
+#define V4L2_MBUS_VSYNC_ACTIVE_HIGH BIT(4)
+#define V4L2_MBUS_VSYNC_ACTIVE_LOW BIT(5)
+#define V4L2_MBUS_PCLK_SAMPLE_RISING BIT(6)
+#define V4L2_MBUS_PCLK_SAMPLE_FALLING BIT(7)
+#define V4L2_MBUS_DATA_ACTIVE_HIGH BIT(8)
+#define V4L2_MBUS_DATA_ACTIVE_LOW BIT(9)
/* FIELD = 0/1 - Field1 (odd)/Field2 (even) */
-#define V4L2_MBUS_FIELD_EVEN_HIGH (1 << 10)
+#define V4L2_MBUS_FIELD_EVEN_HIGH BIT(10)
/* FIELD = 1/0 - Field1 (odd)/Field2 (even) */
-#define V4L2_MBUS_FIELD_EVEN_LOW (1 << 11)
+#define V4L2_MBUS_FIELD_EVEN_LOW BIT(11)
/* Active state of Sync-on-green (SoG) signal, 0/1 for LOW/HIGH respectively. */
-#define V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH (1 << 12)
-#define V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW (1 << 13)
+#define V4L2_MBUS_VIDEO_SOG_ACTIVE_HIGH BIT(12)
+#define V4L2_MBUS_VIDEO_SOG_ACTIVE_LOW BIT(13)
/* Serial flags */
/* How many lanes the client can use */
-#define V4L2_MBUS_CSI2_1_LANE (1 << 0)
-#define V4L2_MBUS_CSI2_2_LANE (1 << 1)
-#define V4L2_MBUS_CSI2_3_LANE (1 << 2)
-#define V4L2_MBUS_CSI2_4_LANE (1 << 3)
+#define V4L2_MBUS_CSI2_1_LANE BIT(0)
+#define V4L2_MBUS_CSI2_2_LANE BIT(1)
+#define V4L2_MBUS_CSI2_3_LANE BIT(2)
+#define V4L2_MBUS_CSI2_4_LANE BIT(3)
/* On which channels it can send video data */
-#define V4L2_MBUS_CSI2_CHANNEL_0 (1 << 4)
-#define V4L2_MBUS_CSI2_CHANNEL_1 (1 << 5)
-#define V4L2_MBUS_CSI2_CHANNEL_2 (1 << 6)
-#define V4L2_MBUS_CSI2_CHANNEL_3 (1 << 7)
+#define V4L2_MBUS_CSI2_CHANNEL_0 BIT(4)
+#define V4L2_MBUS_CSI2_CHANNEL_1 BIT(5)
+#define V4L2_MBUS_CSI2_CHANNEL_2 BIT(6)
+#define V4L2_MBUS_CSI2_CHANNEL_3 BIT(7)
/* Does it support only continuous or also non-continuous clock mode */
-#define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK (1 << 8)
-#define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK (1 << 9)
+#define V4L2_MBUS_CSI2_CONTINUOUS_CLOCK BIT(8)
+#define V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK BIT(9)
#define V4L2_MBUS_CSI2_LANES (V4L2_MBUS_CSI2_1_LANE | V4L2_MBUS_CSI2_2_LANE | \
V4L2_MBUS_CSI2_3_LANE | V4L2_MBUS_CSI2_4_LANE)
@@ -91,6 +93,13 @@ struct v4l2_mbus_config {
unsigned int flags;
};
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ * v4l2_pix_format fields from a &struct v4l2_mbus_framefmt.
+ *
+ * @pix_fmt: pointer to &struct v4l2_pix_format to be filled
+ * @mbus_fmt: pointer to &struct v4l2_mbus_framefmt to be used as model
+ */
static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
const struct v4l2_mbus_framefmt *mbus_fmt)
{
@@ -103,6 +112,15 @@ static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
pix_fmt->xfer_func = mbus_fmt->xfer_func;
}
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ * v4l2_mbus_framefmt from a &struct v4l2_pix_format and a
+ * data format code.
+ *
+ * @mbus_fmt: pointer to &struct v4l2_mbus_framefmt to be filled
+ * @pix_fmt: pointer to &struct v4l2_pix_format to be used as model
+ * @code: data format code (from &enum v4l2_mbus_pixelcode)
+ */
static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt,
const struct v4l2_pix_format *pix_fmt,
u32 code)
@@ -117,6 +135,13 @@ static inline void v4l2_fill_mbus_format(struct v4l2_mbus_framefmt *mbus_fmt,
mbus_fmt->code = code;
}
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ * v4l2_pix_format_mplane fields from a media bus structure.
+ *
+ * @pix_mp_fmt: pointer to &struct v4l2_pix_format_mplane to be filled
+ * @mbus_fmt: pointer to &struct v4l2_mbus_framefmt to be used as model
+ */
static inline void v4l2_fill_pix_format_mplane(
struct v4l2_pix_format_mplane *pix_mp_fmt,
const struct v4l2_mbus_framefmt *mbus_fmt)
@@ -130,6 +155,13 @@ static inline void v4l2_fill_pix_format_mplane(
pix_mp_fmt->xfer_func = mbus_fmt->xfer_func;
}
+/**
+ * v4l2_fill_pix_format - Ancillary routine that fills a &struct
+ * v4l2_mbus_framefmt from a &struct v4l2_pix_format_mplane.
+ *
+ * @mbus_fmt: pointer to &struct v4l2_mbus_framefmt to be filled
+ * @pix_mp_fmt: pointer to &struct v4l2_pix_format_mplane to be used as model
+ */
static inline void v4l2_fill_mbus_format_mplane(
struct v4l2_mbus_framefmt *mbus_fmt,
const struct v4l2_pix_format_mplane *pix_mp_fmt)
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index ec399c770301..980a86c08fce 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -108,22 +108,31 @@ struct v4l2_decode_vbi_line {
* not yet implemented) since ops provide proper type-checking.
*/
-/* Subdevice external IO pin configuration */
-#define V4L2_SUBDEV_IO_PIN_DISABLE (1 << 0) /* ENABLE assumed */
-#define V4L2_SUBDEV_IO_PIN_OUTPUT (1 << 1)
-#define V4L2_SUBDEV_IO_PIN_INPUT (1 << 2)
-#define V4L2_SUBDEV_IO_PIN_SET_VALUE (1 << 3) /* Set output value */
-#define V4L2_SUBDEV_IO_PIN_ACTIVE_LOW (1 << 4) /* ACTIVE HIGH assumed */
+/**
+ * enum v4l2_subdev_io_pin_bits - Subdevice external IO pin configuration
+ * bits
+ *
+ * @V4L2_SUBDEV_IO_PIN_DISABLE: disables a pin config. ENABLE assumed.
+ * @V4L2_SUBDEV_IO_PIN_OUTPUT: set it if pin is an output.
+ * @V4L2_SUBDEV_IO_PIN_INPUT: set it if pin is an input.
+ * @V4L2_SUBDEV_IO_PIN_SET_VALUE: to set the output value via
+ * &struct v4l2_subdev_io_pin_config->value.
+ * @V4L2_SUBDEV_IO_PIN_ACTIVE_LOW: pin active is bit 0.
+ * Otherwise, ACTIVE HIGH is assumed.
+ */
+enum v4l2_subdev_io_pin_bits {
+ V4L2_SUBDEV_IO_PIN_DISABLE = 0,
+ V4L2_SUBDEV_IO_PIN_OUTPUT = 1,
+ V4L2_SUBDEV_IO_PIN_INPUT = 2,
+ V4L2_SUBDEV_IO_PIN_SET_VALUE = 3,
+ V4L2_SUBDEV_IO_PIN_ACTIVE_LOW = 4,
+};
/**
* struct v4l2_subdev_io_pin_config - Subdevice external IO pin configuration
*
- * @flags: bitmask with flags for this pin's config:
- * %V4L2_SUBDEV_IO_PIN_DISABLE - disables a pin config,
- * %V4L2_SUBDEV_IO_PIN_OUTPUT - if pin is an output,
- * %V4L2_SUBDEV_IO_PIN_INPUT - if pin is an input,
- * %V4L2_SUBDEV_IO_PIN_SET_VALUE - to set the output value via @value
- * and %V4L2_SUBDEV_IO_PIN_ACTIVE_LOW - if active is 0.
+ * @flags: bitmask with flags for this pin's config, whose bits are defined by
+ * &enum v4l2_subdev_io_pin_bits.
* @pin: Chip external IO pin to configure
* @function: Internal signal pad/function to route to IO pin
* @value: Initial value for pin - e.g. GPIO output value
@@ -140,7 +149,7 @@ struct v4l2_subdev_io_pin_config {
/**
* struct v4l2_subdev_core_ops - Define core ops callbacks for subdevs
*
- * @log_status: callback for %VIDIOC_LOG_STATUS ioctl handler code.
+ * @log_status: callback for VIDIOC_LOG_STATUS() ioctl handler code.
*
* @s_io_pin_config: configure one or more chip I/O pins for chips that
* multiplex different internal signal pads out to IO pins. This function
@@ -168,9 +177,9 @@ struct v4l2_subdev_io_pin_config {
* @compat_ioctl32: called when a 32 bits application uses a 64 bits Kernel,
* in order to fix data passed from/to userspace.
*
- * @g_register: callback for %VIDIOC_G_REGISTER ioctl handler code.
+ * @g_register: callback for VIDIOC_DBG_G_REGISTER() ioctl handler code.
*
- * @s_register: callback for %VIDIOC_G_REGISTER ioctl handler code.
+ * @s_register: callback for VIDIOC_DBG_S_REGISTER() ioctl handler code.
*
* @s_power: puts subdevice in power saving mode (on == 0) or normal operation
* mode (on == 1).
@@ -215,29 +224,48 @@ struct v4l2_subdev_core_ops {
* struct v4l2_subdev_tuner_ops - Callbacks used when v4l device was opened
* in radio mode.
*
- * @s_radio: callback for %VIDIOC_S_RADIO ioctl handler code.
+ * @s_radio: callback that switches the tuner to radio mode.
+ * drivers should explicitly call it when a tuner ops should
+ * operate on radio mode, before being able to handle it.
+ * Used on devices that have both AM/FM radio receiver and TV.
*
- * @s_frequency: callback for %VIDIOC_S_FREQUENCY ioctl handler code.
+ * @s_frequency: callback for VIDIOC_S_FREQUENCY() ioctl handler code.
*
- * @g_frequency: callback for %VIDIOC_G_FREQUENCY ioctl handler code.
+ * @g_frequency: callback for VIDIOC_G_FREQUENCY() ioctl handler code.
* freq->type must be filled in. Normally done by video_ioctl2()
* or the bridge driver.
*
- * @enum_freq_bands: callback for %VIDIOC_ENUM_FREQ_BANDS ioctl handler code.
+ * @enum_freq_bands: callback for VIDIOC_ENUM_FREQ_BANDS() ioctl handler code.
*
- * @g_tuner: callback for %VIDIOC_G_TUNER ioctl handler code.
+ * @g_tuner: callback for VIDIOC_G_TUNER() ioctl handler code.
*
- * @s_tuner: callback for %VIDIOC_S_TUNER ioctl handler code. @vt->type must be
+ * @s_tuner: callback for VIDIOC_S_TUNER() ioctl handler code. @vt->type must be
* filled in. Normally done by video_ioctl2 or the
* bridge driver.
*
- * @g_modulator: callback for %VIDIOC_G_MODULATOR ioctl handler code.
+ * @g_modulator: callback for VIDIOC_G_MODULATOR() ioctl handler code.
*
- * @s_modulator: callback for %VIDIOC_S_MODULATOR ioctl handler code.
+ * @s_modulator: callback for VIDIOC_S_MODULATOR() ioctl handler code.
*
* @s_type_addr: sets tuner type and its I2C addr.
*
* @s_config: sets tda9887 specific stuff, like port1, port2 and qss
+ *
+ * .. note::
+ *
+ * On devices that have both AM/FM and TV, it is up to the driver
+ * to explicitly call s_radio when the tuner should be switched to
+ * radio mode, before handling other &struct v4l2_subdev_tuner_ops
+ * that would require it. An example of such usage is::
+ *
+ * static void s_frequency(void *priv, const struct v4l2_frequency *f)
+ * {
+ * ...
+ * if (f.type == V4L2_TUNER_RADIO)
+ * v4l2_device_call_all(v4l2_dev, 0, tuner, s_radio);
+ * ...
+ * v4l2_device_call_all(v4l2_dev, 0, tuner, s_frequency);
+ * }
*/
struct v4l2_subdev_tuner_ops {
int (*s_radio)(struct v4l2_subdev *sd);
@@ -285,25 +313,32 @@ 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 that the format does not have line offsets, i.e. the
- * receiver should use 1D DMA.
+/**
+ * enum v4l2_mbus_frame_desc_entry - media bus frame description flags
+ *
+ * @V4L2_MBUS_FRAME_DESC_FL_LEN_MAX:
+ * Indicates that &struct v4l2_mbus_frame_desc_entry->length field
+ * specifies maximum data length.
+ * @V4L2_MBUS_FRAME_DESC_FL_BLOB:
+ * Indicates that the format does not have line offsets, i.e.
+ * the receiver should use 1D DMA.
*/
-#define V4L2_MBUS_FRAME_DESC_FL_BLOB (1U << 1)
+enum v4l2_mbus_frame_desc_flags {
+ V4L2_MBUS_FRAME_DESC_FL_LEN_MAX = BIT(0),
+ V4L2_MBUS_FRAME_DESC_FL_BLOB = BIT(1),
+};
/**
* struct v4l2_mbus_frame_desc_entry - media bus frame description structure
*
- * @flags: bitmask flags: %V4L2_MBUS_FRAME_DESC_FL_LEN_MAX and
- * %V4L2_MBUS_FRAME_DESC_FL_BLOB.
- * @pixelcode: media bus pixel code, valid if FRAME_DESC_FL_BLOB is not set
- * @length: number of octets per frame, valid if V4L2_MBUS_FRAME_DESC_FL_BLOB
- * is set
+ * @flags: bitmask flags, as defined by &enum v4l2_mbus_frame_desc_flags.
+ * @pixelcode: media bus pixel code, valid if @flags
+ * %FRAME_DESC_FL_BLOB is not set.
+ * @length: number of octets per frame, valid if @flags
+ * %V4L2_MBUS_FRAME_DESC_FL_LEN_MAX is set.
*/
struct v4l2_mbus_frame_desc_entry {
- u16 flags;
+ enum v4l2_mbus_frame_desc_flags flags;
u32 pixelcode;
u32 length;
};
@@ -332,9 +367,9 @@ struct v4l2_mbus_frame_desc {
* regarding clock frequency dividers, etc. If not used, then set flags
* to 0. If the frequency is not supported, then -EINVAL is returned.
*
- * @g_std: callback for %VIDIOC_G_STD ioctl handler code.
+ * @g_std: callback for VIDIOC_G_STD() ioctl handler code.
*
- * @s_std: callback for %VIDIOC_S_STD ioctl handler code.
+ * @s_std: callback for VIDIOC_S_STD() ioctl handler code.
*
* @s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by
* video input devices.
@@ -342,7 +377,7 @@ struct v4l2_mbus_frame_desc {
* @g_std_output: get current standard for video OUTPUT devices. This is ignored
* by video input devices.
*
- * @querystd: callback for %VIDIOC_QUERYSTD ioctl handler code.
+ * @querystd: callback for VIDIOC_QUERYSTD() ioctl handler code.
*
* @g_tvnorms: get &v4l2_std_id with all standards supported by the video
* CAPTURE device. This is ignored by video output devices.
@@ -358,13 +393,15 @@ struct v4l2_mbus_frame_desc {
*
* @g_pixelaspect: callback to return the pixelaspect ratio.
*
- * @g_parm: callback for %VIDIOC_G_PARM ioctl handler code.
+ * @g_parm: callback for VIDIOC_G_PARM() ioctl handler code.
*
- * @s_parm: callback for %VIDIOC_S_PARM ioctl handler code.
+ * @s_parm: callback for VIDIOC_S_PARM() ioctl handler code.
*
- * @g_frame_interval: callback for %VIDIOC_G_FRAMEINTERVAL ioctl handler code.
+ * @g_frame_interval: callback for VIDIOC_SUBDEV_G_FRAME_INTERVAL()
+ * ioctl handler code.
*
- * @s_frame_interval: callback for %VIDIOC_S_FRAMEINTERVAL ioctl handler code.
+ * @s_frame_interval: callback for VIDIOC_SUBDEV_S_FRAME_INTERVAL()
+ * ioctl handler code.
*
* @s_dv_timings: Set custom dv timings in the sub device. This is used
* when sub device is capable of setting detailed timing information
@@ -372,7 +409,7 @@ struct v4l2_mbus_frame_desc {
*
* @g_dv_timings: Get custom dv timings in the sub device.
*
- * @query_dv_timings: callback for %VIDIOC_QUERY_DV_TIMINGS ioctl handler code.
+ * @query_dv_timings: callback for VIDIOC_QUERY_DV_TIMINGS() ioctl handler code.
*
* @g_mbus_config: get supported mediabus configurations
*
@@ -443,7 +480,8 @@ struct v4l2_subdev_video_ops {
* member (to determine whether CC data from the first or second field
* should be obtained).
*
- * @g_sliced_vbi_cap: callback for %VIDIOC_SLICED_VBI_CAP ioctl handler code.
+ * @g_sliced_vbi_cap: callback for VIDIOC_G_SLICED_VBI_CAP() ioctl handler
+ * code.
*
* @s_raw_fmt: setup the video encoder/decoder for raw VBI.
*
@@ -610,30 +648,30 @@ struct v4l2_subdev_pad_config {
* struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations
*
* @init_cfg: initialize the pad config to default values
- * @enum_mbus_code: callback for %VIDIOC_SUBDEV_ENUM_MBUS_CODE ioctl handler
+ * @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE() ioctl handler
* code.
- * @enum_frame_size: callback for %VIDIOC_SUBDEV_ENUM_FRAME_SIZE ioctl handler
+ * @enum_frame_size: callback for VIDIOC_SUBDEV_ENUM_FRAME_SIZE() ioctl handler
* code.
*
- * @enum_frame_interval: callback for %VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL ioctl
+ * @enum_frame_interval: callback for VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL() ioctl
* handler code.
*
- * @get_fmt: callback for %VIDIOC_SUBDEV_G_FMT ioctl handler code.
+ * @get_fmt: callback for VIDIOC_SUBDEV_G_FMT() ioctl handler code.
*
- * @set_fmt: callback for %VIDIOC_SUBDEV_S_FMT ioctl handler code.
+ * @set_fmt: callback for VIDIOC_SUBDEV_S_FMT() ioctl handler code.
*
- * @get_selection: callback for %VIDIOC_SUBDEV_G_SELECTION ioctl handler code.
+ * @get_selection: callback for VIDIOC_SUBDEV_G_SELECTION() ioctl handler code.
*
- * @set_selection: callback for %VIDIOC_SUBDEV_S_SELECTION ioctl handler code.
+ * @set_selection: callback for VIDIOC_SUBDEV_S_SELECTION() ioctl handler code.
*
- * @get_edid: callback for %VIDIOC_SUBDEV_G_EDID ioctl handler code.
+ * @get_edid: callback for VIDIOC_SUBDEV_G_EDID() ioctl handler code.
*
- * @set_edid: callback for %VIDIOC_SUBDEV_S_EDID ioctl handler code.
+ * @set_edid: callback for VIDIOC_SUBDEV_S_EDID() ioctl handler code.
*
- * @dv_timings_cap: callback for %VIDIOC_SUBDEV_DV_TIMINGS_CAP ioctl handler
+ * @dv_timings_cap: callback for VIDIOC_SUBDEV_DV_TIMINGS_CAP() ioctl handler
* code.
*
- * @enum_dv_timings: callback for %VIDIOC_SUBDEV_ENUM_DV_TIMINGS ioctl handler
+ * @enum_dv_timings: callback for VIDIOC_SUBDEV_ENUM_DV_TIMINGS() ioctl handler
* code.
*
* @link_validate: used by the media controller code to check if the links
@@ -766,7 +804,7 @@ struct v4l2_subdev_platform_data {
* @list: List of sub-devices
* @owner: The owner is the same as the driver's &struct device owner.
* @owner_v4l2_dev: true if the &sd->owner matches the owner of @v4l2_dev->dev
- * ownner. Initialized by v4l2_device_register_subdev().
+ * owner. Initialized by v4l2_device_register_subdev().
* @flags: subdev flags. Can be:
* %V4L2_SUBDEV_FL_IS_I2C - Set this flag if this subdev is a i2c device;
* %V4L2_SUBDEV_FL_IS_SPI - Set this flag if this subdev is a spi device;
diff --git a/include/media/v4l2-tpg-colors.h b/include/media/v4l2-tpg-colors.h
deleted file mode 100644
index 2a88d1fae0cd..000000000000
--- a/include/media/v4l2-tpg-colors.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * v4l2-tpg-colors.h - Color definitions for the test pattern generator
- *
- * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
- *
- * This program is free software; you may redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef _V4L2_TPG_COLORS_H_
-#define _V4L2_TPG_COLORS_H_
-
-struct color {
- unsigned char r, g, b;
-};
-
-struct color16 {
- int r, g, b;
-};
-
-enum tpg_color {
- TPG_COLOR_CSC_WHITE,
- TPG_COLOR_CSC_YELLOW,
- TPG_COLOR_CSC_CYAN,
- TPG_COLOR_CSC_GREEN,
- TPG_COLOR_CSC_MAGENTA,
- TPG_COLOR_CSC_RED,
- TPG_COLOR_CSC_BLUE,
- TPG_COLOR_CSC_BLACK,
- TPG_COLOR_75_YELLOW,
- TPG_COLOR_75_CYAN,
- TPG_COLOR_75_GREEN,
- TPG_COLOR_75_MAGENTA,
- TPG_COLOR_75_RED,
- TPG_COLOR_75_BLUE,
- TPG_COLOR_100_WHITE,
- TPG_COLOR_100_YELLOW,
- TPG_COLOR_100_CYAN,
- TPG_COLOR_100_GREEN,
- TPG_COLOR_100_MAGENTA,
- TPG_COLOR_100_RED,
- TPG_COLOR_100_BLUE,
- TPG_COLOR_100_BLACK,
- TPG_COLOR_TEXTFG,
- TPG_COLOR_TEXTBG,
- TPG_COLOR_RANDOM,
- TPG_COLOR_RAMP,
- TPG_COLOR_MAX = TPG_COLOR_RAMP + 256
-};
-
-extern const struct color tpg_colors[TPG_COLOR_MAX];
-extern const unsigned short tpg_rec709_to_linear[255 * 16 + 1];
-extern const unsigned short tpg_linear_to_rec709[255 * 16 + 1];
-extern const struct color16 tpg_csc_colors[V4L2_COLORSPACE_DCI_P3 + 1]
- [V4L2_XFER_FUNC_SMPTE2084 + 1]
- [TPG_COLOR_CSC_BLACK + 1];
-
-#endif
diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h
index a14ac7711c92..c9c81990a56c 100644
--- a/include/media/videobuf-dvb.h
+++ b/include/media/videobuf-dvb.h
@@ -1,9 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
-#include <dvbdev.h>
-#include <dmxdev.h>
-#include <dvb_demux.h>
-#include <dvb_net.h>
-#include <dvb_frontend.h>
+#include <media/dvbdev.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dvb_frontend.h>
#ifndef _VIDEOBUF_DVB_H_
#define _VIDEOBUF_DVB_H_
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index e55efc62a950..aa16c064294f 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -16,6 +16,7 @@
#include <linux/mutex.h>
#include <linux/poll.h>
#include <linux/dma-buf.h>
+#include <linux/bitops.h>
#define VB2_MAX_FRAME (32)
#define VB2_MAX_PLANES (8)
@@ -45,7 +46,7 @@ struct vb2_fileio_data;
struct vb2_threadio_data;
/**
- * struct vb2_mem_ops - memory handling/memory allocator operations
+ * struct vb2_mem_ops - memory handling/memory allocator operations.
* @alloc: allocate video memory and, optionally, allocator private data,
* return ERR_PTR() on failure or a pointer to allocator private,
* per-buffer data on success; the returned private structure
@@ -69,7 +70,7 @@ struct vb2_threadio_data;
* argument to other ops in this structure.
* @put_userptr: inform the allocator that a USERPTR buffer will no longer
* be used.
- * @attach_dmabuf: attach a shared struct dma_buf for a hardware operation;
+ * @attach_dmabuf: attach a shared &struct dma_buf for a hardware operation;
* used for DMABUF memory types; dev is the alloc device
* dbuf is the shared dma_buf; returns ERR_PTR() on failure;
* allocator private per-buffer structure on success;
@@ -145,28 +146,28 @@ struct vb2_mem_ops {
};
/**
- * struct vb2_plane - plane information
- * @mem_priv: private data with this plane
- * @dbuf: dma_buf - shared buffer object
+ * struct vb2_plane - plane information.
+ * @mem_priv: private data with this plane.
+ * @dbuf: dma_buf - shared buffer object.
* @dbuf_mapped: flag to show whether dbuf is mapped or not
- * @bytesused: number of bytes occupied by data in the plane (payload)
- * @length: size of this plane (NOT the payload) in bytes
+ * @bytesused: number of bytes occupied by data in the plane (payload).
+ * @length: size of this plane (NOT the payload) in bytes.
* @min_length: minimum required size of this plane (NOT the payload) in bytes.
* @length is always greater or equal to @min_length.
- * @offset: when memory in the associated struct vb2_buffer is
- * VB2_MEMORY_MMAP, equals the offset from the start of
+ * @m: Union with memtype-specific data.
+ * @m.offset: when memory in the associated struct vb2_buffer is
+ * %VB2_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 VB2_MEMORY_USERPTR, a userspace pointer
- * pointing to this plane
- * @fd: when memory is VB2_MEMORY_DMABUF, a userspace file
- * descriptor associated with this plane
- * @m: Union with memtype-specific data (@offset, @userptr or
- * @fd).
+ * should be passed to mmap() called on the video node).
+ * @m.userptr: when memory is %VB2_MEMORY_USERPTR, a userspace pointer
+ * pointing to this plane.
+ * @m.fd: when memory is %VB2_MEMORY_DMABUF, a userspace file
+ * descriptor associated with 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
+ * unless there is a header in front of the data.
+ *
* Should contain enough information to be able to cover all the fields
- * of struct v4l2_plane at videodev2.h
+ * of &struct v4l2_plane at videodev2.h.
*/
struct vb2_plane {
void *mem_priv;
@@ -184,35 +185,35 @@ struct vb2_plane {
};
/**
- * enum vb2_io_modes - queue access methods
- * @VB2_MMAP: driver supports MMAP with streaming API
- * @VB2_USERPTR: driver supports USERPTR with streaming API
- * @VB2_READ: driver supports read() style access
- * @VB2_WRITE: driver supports write() style access
- * @VB2_DMABUF: driver supports DMABUF with streaming API
+ * enum vb2_io_modes - queue access methods.
+ * @VB2_MMAP: driver supports MMAP with streaming API.
+ * @VB2_USERPTR: driver supports USERPTR with streaming API.
+ * @VB2_READ: driver supports read() style access.
+ * @VB2_WRITE: driver supports write() style access.
+ * @VB2_DMABUF: driver supports DMABUF with streaming API.
*/
enum vb2_io_modes {
- VB2_MMAP = (1 << 0),
- VB2_USERPTR = (1 << 1),
- VB2_READ = (1 << 2),
- VB2_WRITE = (1 << 3),
- VB2_DMABUF = (1 << 4),
+ VB2_MMAP = BIT(0),
+ VB2_USERPTR = BIT(1),
+ VB2_READ = BIT(2),
+ VB2_WRITE = BIT(3),
+ VB2_DMABUF = BIT(4),
};
/**
- * enum vb2_buffer_state - current video buffer state
- * @VB2_BUF_STATE_DEQUEUED: buffer under userspace control
- * @VB2_BUF_STATE_PREPARING: buffer is being prepared in videobuf
- * @VB2_BUF_STATE_PREPARED: buffer prepared in videobuf and by the driver
- * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver
- * @VB2_BUF_STATE_REQUEUEING: re-queue a buffer to the driver
+ * enum vb2_buffer_state - current video buffer state.
+ * @VB2_BUF_STATE_DEQUEUED: buffer under userspace control.
+ * @VB2_BUF_STATE_PREPARING: buffer is being prepared in videobuf.
+ * @VB2_BUF_STATE_PREPARED: buffer prepared in videobuf and by the driver.
+ * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver.
+ * @VB2_BUF_STATE_REQUEUEING: re-queue a buffer to the driver.
* @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used
- * in a hardware operation
+ * in a hardware operation.
* @VB2_BUF_STATE_DONE: buffer returned from driver to videobuf, but
- * not yet dequeued to userspace
+ * not yet dequeued to userspace.
* @VB2_BUF_STATE_ERROR: same as above, but the operation on the buffer
* has ended with an error, which will be reported
- * to the userspace when it is dequeued
+ * to the userspace when it is dequeued.
*/
enum vb2_buffer_state {
VB2_BUF_STATE_DEQUEUED,
@@ -228,15 +229,15 @@ enum vb2_buffer_state {
struct vb2_queue;
/**
- * struct vb2_buffer - represents a video buffer
- * @vb2_queue: the queue to which this driver belongs
- * @index: id number of the buffer
- * @type: buffer type
- * @memory: the method, in which the actual data is passed
+ * struct vb2_buffer - represents a video buffer.
+ * @vb2_queue: pointer to &struct vb2_queue with the queue to
+ * which this driver belongs.
+ * @index: id number of the buffer.
+ * @type: buffer type.
+ * @memory: the method, in which the actual data is passed.
* @num_planes: number of planes in the buffer
- * on an internal driver queue
- * @planes: private per-plane information; do not change
- * @timestamp: frame timestamp in ns
+ * on an internal driver queue.
+ * @timestamp: frame timestamp in ns.
*/
struct vb2_buffer {
struct vb2_queue *vb2_queue;
@@ -244,7 +245,6 @@ struct vb2_buffer {
unsigned int type;
unsigned int memory;
unsigned int num_planes;
- struct vb2_plane planes[VB2_MAX_PLANES];
u64 timestamp;
/* private: internal use only
@@ -254,9 +254,11 @@ struct vb2_buffer {
* all buffers queued from userspace
* done_entry: entry on the list that stores all buffers ready
* to be dequeued to userspace
+ * vb2_plane: per-plane information; do not change
*/
enum vb2_buffer_state state;
+ struct vb2_plane planes[VB2_MAX_PLANES];
struct list_head queued_entry;
struct list_head done_entry;
#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -292,7 +294,7 @@ struct vb2_buffer {
};
/**
- * struct vb2_ops - driver-specific callbacks
+ * struct vb2_ops - driver-specific callbacks.
*
* @queue_setup: called from VIDIOC_REQBUFS() and VIDIOC_CREATE_BUFS()
* handlers before memory allocation. It can be called
@@ -358,8 +360,8 @@ struct vb2_buffer {
* the @buf_queue callback are to be returned by the driver
* by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED.
* If you need a minimum number of buffers before you can
- * start streaming, then set @min_buffers_needed in the
- * vb2_queue structure. If that is non-zero then
+ * start streaming, then set
+ * &vb2_queue->min_buffers_needed. If that is non-zero then
* @start_streaming won't be called until at least that
* many buffers have been queued up by userspace.
* @stop_streaming: called when 'streaming' state must be disabled; driver
@@ -396,18 +398,18 @@ struct vb2_ops {
};
/**
- * struct vb2_buf_ops - driver-specific callbacks
+ * struct vb2_buf_ops - driver-specific callbacks.
*
* @verify_planes_array: Verify that a given user space structure contains
* enough planes for the buffer. This is called
* for each dequeued buffer.
- * @fill_user_buffer: given a vb2_buffer fill in the userspace structure.
- * For V4L2 this is a struct v4l2_buffer.
- * @fill_vb2_buffer: given a userspace structure, fill in the vb2_buffer.
+ * @fill_user_buffer: given a &vb2_buffer fill in the userspace structure.
+ * For V4L2 this is a &struct v4l2_buffer.
+ * @fill_vb2_buffer: given a userspace structure, fill in the &vb2_buffer.
* If the userspace structure is invalid, then this op
* will return an error.
* @copy_timestamp: copy the timestamp from a userspace structure to
- * the vb2_buffer struct.
+ * the &struct vb2_buffer.
*/
struct vb2_buf_ops {
int (*verify_planes_array)(struct vb2_buffer *vb, const void *pb);
@@ -418,20 +420,21 @@ struct vb2_buf_ops {
};
/**
- * struct vb2_queue - a videobuf queue
+ * struct vb2_queue - a videobuf queue.
*
* @type: private buffer type whose content is defined by the vb2-core
* caller. For example, for V4L2, it should match
- * the types defined on enum &v4l2_buf_type
- * @io_modes: supported io methods (see vb2_io_modes enum)
+ * the types defined on &enum v4l2_buf_type.
+ * @io_modes: supported io methods (see &enum vb2_io_modes).
+ * @alloc_devs: &struct device memory type/allocator-specific per-plane device
* @dev: device to use for the default allocation context if the driver
* doesn't fill in the @alloc_devs array.
* @dma_attrs: DMA attributes to use for the DMA.
* @bidirectional: when this flag is set the DMA direction for the buffers of
- * this queue will be overridden with DMA_BIDIRECTIONAL direction.
+ * this queue will be overridden with %DMA_BIDIRECTIONAL direction.
* This is useful in cases where the hardware (firmware) writes to
- * a buffer which is mapped as read (DMA_TO_DEVICE), or reads from
- * buffer which is mapped for write (DMA_FROM_DEVICE) in order
+ * a buffer which is mapped as read (%DMA_TO_DEVICE), or reads from
+ * buffer which is mapped for write (%DMA_FROM_DEVICE) in order
* to satisfy some internal hardware restrictions or adds a padding
* needed by the processing algorithm. In case the DMA mapping is
* not bidirectional but the hardware (firmware) trying to access
@@ -440,10 +443,10 @@ struct vb2_buf_ops {
* @fileio_read_once: report EOF after reading the first buffer
* @fileio_write_immediately: queue buffer after each write() call
* @allow_zero_bytesused: allow bytesused == 0 to be passed to the driver
- * @quirk_poll_must_check_waiting_for_buffers: Return POLLERR at poll when QBUF
+ * @quirk_poll_must_check_waiting_for_buffers: Return %POLLERR at poll when QBUF
* has not been called. This is a vb1 idiom that has been adopted
* also by vb2.
- * @lock: pointer to a mutex that protects the vb2_queue struct. The
+ * @lock: pointer to a mutex that protects the &struct vb2_queue. The
* driver can set this to a mutex to let the v4l2 core serialize
* the queuing ioctls. If the driver wants to handle locking
* itself, then this should be set to NULL. This lock is not used
@@ -454,17 +457,17 @@ struct vb2_buf_ops {
* drivers to easily associate an owner filehandle with the queue.
* @ops: driver-specific callbacks
* @mem_ops: memory allocator specific callbacks
- * @buf_ops: callbacks to deliver buffer information
- * between user-space and kernel-space
- * @drv_priv: driver private data
+ * @buf_ops: callbacks to deliver buffer information.
+ * between user-space and kernel-space.
+ * @drv_priv: driver private data.
* @buf_struct_size: size of the driver-specific buffer structure;
* "0" indicates the driver doesn't want to use a custom buffer
- * structure type. for example, sizeof(struct vb2_v4l2_buffer)
+ * structure type. for example, ``sizeof(struct vb2_v4l2_buffer)``
* will be used for v4l2.
- * @timestamp_flags: Timestamp flags; V4L2_BUF_FLAG_TIMESTAMP_* and
- * V4L2_BUF_FLAG_TSTAMP_SRC_*
+ * @timestamp_flags: Timestamp flags; ``V4L2_BUF_FLAG_TIMESTAMP_*`` and
+ * ``V4L2_BUF_FLAG_TSTAMP_SRC_*``
* @gfp_flags: additional gfp flags used when allocating the buffers.
- * Typically this is 0, but it may be e.g. GFP_DMA or __GFP_DMA32
+ * Typically this is 0, but it may be e.g. %GFP_DMA or %__GFP_DMA32
* to force the buffer allocation to a specific memory zone.
* @min_buffers_needed: the minimum number of buffers needed before
* @start_streaming can be called. Used when a DMA engine
@@ -484,20 +487,19 @@ struct vb2_buf_ops {
* @done_list: list of buffers ready to be dequeued to userspace
* @done_lock: lock to protect done_list list
* @done_wq: waitqueue for processes waiting for buffers ready to be dequeued
- * @alloc_devs: memory type/allocator-specific per-plane device
* @streaming: current streaming state
* @start_streaming_called: @start_streaming was called successfully and we
* started streaming.
* @error: a fatal error occurred on the queue
* @waiting_for_buffers: used in poll() to check if vb2 is still waiting for
* buffers. Only set for capture queues if qbuf has not yet been
- * called since poll() needs to return POLLERR in that situation.
+ * called since poll() needs to return %POLLERR in that situation.
* @is_multiplanar: set if buffer type is multiplanar
* @is_output: set if buffer type is output
* @copy_timestamp: set if vb2-core should set timestamps
* @last_buffer_dequeued: used in poll() and DQBUF to immediately return if the
* last decoded buffer was already dequeued. Set for capture queues
- * when a buffer with the V4L2_BUF_FLAG_LAST is dequeued.
+ * when a buffer with the %V4L2_BUF_FLAG_LAST is dequeued.
* @fileio: file io emulator internal data, used only if emulator is active
* @threadio: thread io internal data, used only if thread is active
*/
@@ -525,6 +527,8 @@ struct vb2_queue {
gfp_t gfp_flags;
u32 min_buffers_needed;
+ struct device *alloc_devs[VB2_MAX_PLANES];
+
/* private: internal use only */
struct mutex mmap_lock;
unsigned int memory;
@@ -540,8 +544,6 @@ struct vb2_queue {
spinlock_t done_lock;
wait_queue_head_t done_wq;
- struct device *alloc_devs[VB2_MAX_PLANES];
-
unsigned int streaming:1;
unsigned int start_streaming_called:1;
unsigned int error:1;
@@ -568,9 +570,10 @@ struct vb2_queue {
};
/**
- * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
- * @vb: vb2_buffer to which the plane in question belongs to
- * @plane_no: plane number for which the address is to be returned
+ * vb2_plane_vaddr() - Return a kernel virtual address of a given plane.
+ * @vb: pointer to &struct vb2_buffer to which the plane in
+ * question belongs to.
+ * @plane_no: plane number for which the address is to be returned.
*
* This function returns a kernel virtual address of a given plane if
* such a mapping exist, NULL otherwise.
@@ -578,9 +581,10 @@ struct vb2_queue {
void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
/**
- * vb2_plane_cookie() - Return allocator specific cookie for the given plane
- * @vb: vb2_buffer to which the plane in question belongs to
- * @plane_no: plane number for which the cookie is to be returned
+ * vb2_plane_cookie() - Return allocator specific cookie for the given plane.
+ * @vb: pointer to &struct vb2_buffer to which the plane in
+ * question belongs to.
+ * @plane_no: plane number for which the cookie is to be returned.
*
* This function returns an allocator specific cookie for a given plane if
* available, NULL otherwise. The allocator should provide some simple static
@@ -591,9 +595,11 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no);
/**
- * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished
- * @vb: vb2_buffer returned from the driver
- * @state: either %VB2_BUF_STATE_DONE if the operation finished
+ * vb2_buffer_done() - inform videobuf that an operation on a buffer
+ * is finished.
+ * @vb: pointer to &struct vb2_buffer to be used.
+ * @state: state of the buffer, as defined by &enum vb2_buffer_state.
+ * Either %VB2_BUF_STATE_DONE if the operation finished
* successfully, %VB2_BUF_STATE_ERROR if the operation finished
* with an error or %VB2_BUF_STATE_QUEUED if the driver wants to
* requeue buffers. If start_streaming fails then it should return
@@ -614,8 +620,8 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no);
void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state);
/**
- * vb2_discard_done() - discard all buffers marked as DONE
- * @q: videobuf2 queue
+ * vb2_discard_done() - discard all buffers marked as DONE.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*
* This function is intended to be used with suspend/resume operations. It
* discards all 'done' buffers as they would be too old to be requested after
@@ -628,74 +634,83 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state);
void vb2_discard_done(struct vb2_queue *q);
/**
- * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2
- * @q: videobuf2 queue
+ * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*
* This function will wait until all buffers that have been given to the driver
* by &vb2_ops->buf_queue are given back to vb2 with vb2_buffer_done(). It
- * doesn't call wait_prepare()/wait_finish() pair. It is intended to be called
- * with all locks taken, for example from &vb2_ops->stop_streaming callback.
+ * doesn't call &vb2_ops->wait_prepare/&vb2_ops->wait_finish pair.
+ * It is intended to be called with all locks taken, for example from
+ * &vb2_ops->stop_streaming callback.
*/
int vb2_wait_for_all_buffers(struct vb2_queue *q);
/**
- * vb2_core_querybuf() - query video buffer information
- * @q: videobuf queue
- * @index: id number of the buffer
- * @pb: buffer struct passed from userspace
+ * vb2_core_querybuf() - query video buffer information.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @index: id number of the buffer.
+ * @pb: buffer struct passed from userspace.
+ *
+ * Videobuf2 core helper to implement VIDIOC_QUERYBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
*
- * Should be called from vidioc_querybuf ioctl handler in driver.
* The passed buffer should have been verified.
+ *
* This function fills the relevant information for the userspace.
+ *
+ * Return: returns zero on success; an error code otherwise.
*/
void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb);
/**
- * vb2_core_reqbufs() - Initiate streaming
- * @q: videobuf2 queue
- * @memory: memory type
- * @count: requested buffer count
+ * vb2_core_reqbufs() - Initiate streaming.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @memory: memory type, as defined by &enum vb2_memory.
+ * @count: requested buffer count.
*
- * Should be called from vidioc_reqbufs ioctl handler of a driver.
+ * Videobuf2 core helper to implement VIDIOC_REQBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
*
* This function:
*
- * #) verifies streaming parameters passed from the userspace,
- * #) sets up the queue,
+ * #) verifies streaming parameters passed from the userspace;
+ * #) sets up the queue;
* #) negotiates number of buffers and planes per buffer with the driver
- * to be used during streaming,
- * #) allocates internal buffer structures (struct vb2_buffer), according to
- * the agreed parameters,
+ * to be used during streaming;
+ * #) allocates internal buffer structures (&struct vb2_buffer), according to
+ * the agreed parameters;
* #) for MMAP memory type, allocates actual video memory, using the
- * memory handling/allocation routines provided during queue initialization
+ * memory handling/allocation routines provided during queue initialization.
*
* If req->count is 0, all the memory will be freed instead.
- * If the queue has been allocated previously (by a previous vb2_reqbufs) call
- * and the queue is not busy, memory will be reallocated.
*
- * The return values from this function are intended to be directly returned
- * from vidioc_reqbufs handler in driver.
+ * If the queue has been allocated previously by a previous vb2_core_reqbufs()
+ * call and the queue is not busy, memory will be reallocated.
+ *
+ * Return: returns zero on success; an error code otherwise.
*/
int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
unsigned int *count);
/**
* vb2_core_create_bufs() - Allocate buffers and any required auxiliary structs
- * @q: videobuf2 queue
- * @memory: memory type
- * @count: requested buffer count
- * @requested_planes: number of planes requested
- * @requested_sizes: array with the size of the planes
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @memory: memory type, as defined by &enum vb2_memory.
+ * @count: requested buffer count.
+ * @requested_planes: number of planes requested.
+ * @requested_sizes: array with the size of the planes.
+ *
+ * Videobuf2 core helper to implement VIDIOC_CREATE_BUFS() operation. It is
+ * called internally by VB2 by an API-specific handler, like
+ * ``videobuf2-v4l2.h``.
*
- * Should be called from VIDIOC_CREATE_BUFS() ioctl handler of a driver.
* This function:
*
- * #) verifies parameter sanity
- * #) calls the .queue_setup() queue operation
- * #) performs any necessary memory allocations
+ * #) verifies parameter sanity;
+ * #) calls the &vb2_ops->queue_setup queue operation;
+ * #) performs any necessary memory allocations.
*
- * Return: the return values from this function are intended to be directly
- * returned from VIDIOC_CREATE_BUFS() handler in driver.
+ * Return: returns zero on success; an error code otherwise.
*/
int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
unsigned int *count, unsigned int requested_planes,
@@ -703,57 +718,61 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory,
/**
* vb2_core_prepare_buf() - Pass ownership of a buffer from userspace
- * to the kernel
- * @q: videobuf2 queue
- * @index: id number of the buffer
- * @pb: buffer structure passed from userspace to vidioc_prepare_buf
- * handler in driver
+ * to the kernel.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @index: id number of the buffer.
+ * @pb: buffer structure passed from userspace to
+ * &v4l2_ioctl_ops->vidioc_prepare_buf handler in driver.
+ *
+ * Videobuf2 core helper to implement VIDIOC_PREPARE_BUF() operation. It is
+ * called internally by VB2 by an API-specific handler, like
+ * ``videobuf2-v4l2.h``.
*
- * Should be called from vidioc_prepare_buf ioctl handler of a driver.
* The passed buffer should have been verified.
- * This function calls buf_prepare callback in the driver (if provided),
- * in which driver-specific buffer initialization can be performed,
*
- * The return values from this function are intended to be directly returned
- * from vidioc_prepare_buf handler in driver.
+ * This function calls vb2_ops->buf_prepare callback in the driver
+ * (if provided), in which driver-specific buffer initialization can
+ * be performed.
+ *
+ * Return: returns zero on success; an error code otherwise.
*/
int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb);
/**
* vb2_core_qbuf() - Queue a buffer from userspace
*
- * @q: videobuf2 queue
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
* @index: id number of the buffer
- * @pb: buffer structure passed from userspace to vidioc_qbuf handler
- * in driver
+ * @pb: buffer structure passed from userspace to
+ * v4l2_ioctl_ops->vidioc_qbuf handler in driver
*
- * Should be called from vidioc_qbuf ioctl handler of a driver.
- * The passed buffer should have been verified.
+ * Videobuf2 core helper to implement VIDIOC_QBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
*
* This function:
*
- * #) if necessary, calls buf_prepare callback in the driver (if provided), in
- * which driver-specific buffer initialization can be performed,
+ * #) if necessary, calls &vb2_ops->buf_prepare callback in the driver
+ * (if provided), in which driver-specific buffer initialization can
+ * be performed;
* #) if streaming is on, queues the buffer in driver by the means of
* &vb2_ops->buf_queue callback for processing.
*
- * The return values from this function are intended to be directly returned
- * from vidioc_qbuf handler in driver.
+ * Return: returns zero on success; an error code otherwise.
*/
int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb);
/**
* vb2_core_dqbuf() - Dequeue a buffer to the userspace
- * @q: videobuf2 queue
+ * @q: pointer to &struct vb2_queue with videobuf2 queue
* @pindex: pointer to the buffer index. May be NULL
- * @pb: buffer structure passed from userspace to vidioc_dqbuf handler
- * in driver
+ * @pb: buffer structure passed from userspace to
+ * v4l2_ioctl_ops->vidioc_dqbuf handler in driver.
* @nonblocking: if true, this call will not sleep waiting for a buffer if no
* buffers ready for dequeuing are present. Normally the driver
- * would be passing (file->f_flags & O_NONBLOCK) here
+ * would be passing (file->f_flags & O_NONBLOCK) here.
*
- * Should be called from vidioc_dqbuf ioctl handler of a driver.
- * The passed buffer should have been verified.
+ * Videobuf2 core helper to implement VIDIOC_DQBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
*
* This function:
*
@@ -763,73 +782,108 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb);
* #) the buffer struct members are filled with relevant information for
* the userspace.
*
- * The return values from this function are intended to be directly returned
- * from vidioc_dqbuf handler in driver.
+ * Return: returns zero on success; an error code otherwise.
*/
int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb,
bool nonblocking);
+/**
+ * vb2_core_streamon() - Implements VB2 stream ON logic
+ *
+ * @q: pointer to &struct vb2_queue with videobuf2 queue
+ * @type: type of the queue to be started.
+ * For V4L2, this is defined by &enum v4l2_buf_type type.
+ *
+ * Videobuf2 core helper to implement VIDIOC_STREAMON() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
int vb2_core_streamon(struct vb2_queue *q, unsigned int type);
+
+/**
+ * vb2_core_streamoff() - Implements VB2 stream OFF logic
+ *
+ * @q: pointer to &struct vb2_queue with videobuf2 queue
+ * @type: type of the queue to be started.
+ * For V4L2, this is defined by &enum v4l2_buf_type type.
+ *
+ * Videobuf2 core helper to implement VIDIOC_STREAMOFF() operation. It is
+ * called internally by VB2 by an API-specific handler, like
+ * ``videobuf2-v4l2.h``.
+ *
+ * Return: returns zero on success; an error code otherwise.
+ */
int vb2_core_streamoff(struct vb2_queue *q, unsigned int type);
/**
- * vb2_core_expbuf() - Export a buffer as a file descriptor
- * @q: videobuf2 queue
- * @fd: file descriptor associated with DMABUF (set by driver) *
- * @type: buffer type
- * @index: id number of the buffer
+ * vb2_core_expbuf() - Export a buffer as a file descriptor.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @fd: pointer to the file descriptor associated with DMABUF
+ * (set by driver).
+ * @type: buffer type.
+ * @index: id number of the buffer.
* @plane: index of the plane to be exported, 0 for single plane queues
- * @flags: flags for newly created file, currently only O_CLOEXEC is
- * supported, refer to manual of open syscall for more details
+ * @flags: file flags for newly created file, as defined at
+ * include/uapi/asm-generic/fcntl.h.
+ * Currently, the only used flag is %O_CLOEXEC.
+ * is supported, refer to manual of open syscall for more details.
*
- * The return values from this function are intended to be directly returned
- * from vidioc_expbuf handler in driver.
+ *
+ * Videobuf2 core helper to implement VIDIOC_EXPBUF() operation. It is called
+ * internally by VB2 by an API-specific handler, like ``videobuf2-v4l2.h``.
+ *
+ * Return: returns zero on success; an error code otherwise.
*/
int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type,
unsigned int index, unsigned int plane, unsigned int flags);
/**
* vb2_core_queue_init() - initialize a videobuf2 queue
- * @q: videobuf2 queue; this structure should be allocated in driver
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * This structure should be allocated in driver
*
- * The vb2_queue structure should be allocated by the driver. The driver is
+ * The &vb2_queue structure should be allocated by the driver. The driver is
* responsible of clearing it's content and setting initial values for some
* required entries before calling this function.
- * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer
- * to the struct vb2_queue description in include/media/videobuf2-core.h
- * for more information.
+ *
+ * .. note::
+ *
+ * The following fields at @q should be set before calling this function:
+ * &vb2_queue->ops, &vb2_queue->mem_ops, &vb2_queue->type.
*/
int vb2_core_queue_init(struct vb2_queue *q);
/**
* vb2_core_queue_release() - stop streaming, release the queue and free memory
- * @q: videobuf2 queue
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*
* This function stops streaming and performs necessary clean ups, including
* freeing video buffer memory. The driver is responsible for freeing
- * the vb2_queue structure itself.
+ * the &struct vb2_queue itself.
*/
void vb2_core_queue_release(struct vb2_queue *q);
/**
* vb2_queue_error() - signal a fatal error on the queue
- * @q: videobuf2 queue
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*
* Flag that a fatal unrecoverable error has occurred and wake up all processes
- * waiting on the queue. Polling will now set POLLERR and queuing and dequeuing
- * buffers will return -EIO.
+ * waiting on the queue. Polling will now set %POLLERR and queuing and dequeuing
+ * buffers will return %-EIO.
*
- * The error flag will be cleared when cancelling the queue, either from
- * vb2_streamoff or vb2_queue_release. Drivers should thus not call this
+ * The error flag will be cleared when canceling the queue, either from
+ * vb2_streamoff() or vb2_queue_release(). Drivers should thus not call this
* function before starting the stream, otherwise the error flag will remain set
* until the queue is released when closing the device node.
*/
void vb2_queue_error(struct vb2_queue *q);
/**
- * vb2_mmap() - map video buffers into application address space
- * @q: videobuf2 queue
- * @vma: vma passed to the mmap file operation handler in the driver
+ * vb2_mmap() - map video buffers into application address space.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @vma: pointer to &struct vm_area_struct with the vma passed
+ * to the mmap file operation handler in the driver.
*
* Should be called from mmap file operation handler of a driver.
* This function maps one plane of one of the available video buffers to
@@ -837,8 +891,10 @@ void vb2_queue_error(struct vb2_queue *q);
* has to be called once per each plane per each buffer previously allocated.
*
* When the userspace application calls mmap, it passes to it an offset returned
- * to it earlier by the means of vidioc_querybuf handler. That offset acts as
- * a "cookie", which is then used to identify the plane to be mapped.
+ * to it earlier by the means of &v4l2_ioctl_ops->vidioc_querybuf handler.
+ * That offset acts as a "cookie", which is then used to identify the plane
+ * to be mapped.
+ *
* This function finds a plane with a matching offset and a mapping is performed
* by the means of a provided memory operation.
*
@@ -848,6 +904,21 @@ void vb2_queue_error(struct vb2_queue *q);
int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma);
#ifndef CONFIG_MMU
+/**
+ * vb2_get_unmapped_area - map video buffers into application address space.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @addr: memory address.
+ * @len: buffer size.
+ * @pgoff: page offset.
+ * @flags: memory flags.
+ *
+ * This function is used in noMMU platforms to propose address mapping
+ * for a given buffer. It's intended to be used as a handler for the
+ * &file_operations->get_unmapped_area operation.
+ *
+ * This is called by the mmap() syscall routines will call this
+ * to get a proposed address for the mapping, when ``!CONFIG_MMU``.
+ */
unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
unsigned long addr,
unsigned long len,
@@ -856,10 +927,12 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
#endif
/**
- * vb2_core_poll() - implements poll userspace operation
- * @q: videobuf2 queue
- * @file: file argument passed to the poll file operation handler
- * @wait: wait argument passed to the poll file operation handler
+ * vb2_core_poll() - implements poll syscall() logic.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @file: &struct file argument passed to the poll
+ * file operation handler.
+ * @wait: &poll_table wait argument passed to the poll
+ * file operation handler.
*
* This function implements poll file operation handler for a driver.
* For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
@@ -874,16 +947,32 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
__poll_t vb2_core_poll(struct vb2_queue *q, struct file *file,
poll_table *wait);
+/**
+ * vb2_read() - implements read() syscall logic.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @data: pointed to target userspace buffer
+ * @count: number of bytes to read
+ * @ppos: file handle position tracking pointer
+ * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking)
+ */
size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
loff_t *ppos, int nonblock);
+/**
+ * vb2_read() - implements write() syscall logic.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @data: pointed to target userspace buffer
+ * @count: number of bytes to write
+ * @ppos: file handle position tracking pointer
+ * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking)
+ */
size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count,
loff_t *ppos, int nonblock);
/**
- * typedef vb2_thread_fnc - callback function for use with vb2_thread
+ * typedef vb2_thread_fnc - callback function for use with vb2_thread.
*
- * @vb: pointer to struct &vb2_buffer
- * @priv: pointer to a private pointer
+ * @vb: pointer to struct &vb2_buffer.
+ * @priv: pointer to a private data.
*
* This is called whenever a buffer is dequeued in the thread.
*/
@@ -891,13 +980,13 @@ typedef int (*vb2_thread_fnc)(struct vb2_buffer *vb, void *priv);
/**
* vb2_thread_start() - start a thread for the given queue.
- * @q: videobuf queue
- * @fnc: callback function
- * @priv: priv pointer passed to the callback function
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @fnc: &vb2_thread_fnc callback function.
+ * @priv: priv pointer passed to the callback function.
* @thread_name:the name of the thread. This will be prefixed with "vb2-".
*
* This starts a thread that will queue and dequeue until an error occurs
- * or @vb2_thread_stop is called.
+ * or vb2_thread_stop() is called.
*
* .. attention::
*
@@ -910,13 +999,13 @@ int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv,
/**
* vb2_thread_stop() - stop the thread for the given queue.
- * @q: videobuf queue
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*/
int vb2_thread_stop(struct vb2_queue *q);
/**
- * vb2_is_streaming() - return streaming status of the queue
- * @q: videobuf queue
+ * vb2_is_streaming() - return streaming status of the queue.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*/
static inline bool vb2_is_streaming(struct vb2_queue *q)
{
@@ -925,15 +1014,16 @@ static inline bool vb2_is_streaming(struct vb2_queue *q)
/**
* vb2_fileio_is_active() - return true if fileio is active.
- * @q: videobuf queue
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*
* This returns true if read() or write() is used to stream the data
* as opposed to stream I/O. This is almost never an important distinction,
* except in rare cases. One such case is that using read() or write() to
- * stream a format using V4L2_FIELD_ALTERNATE is not allowed since there
+ * stream a format using %V4L2_FIELD_ALTERNATE is not allowed since there
* is no way you can pass the field information of each buffer to/from
* userspace. A driver that supports this field format should check for
- * this in the queue_setup op and reject it if this function returns true.
+ * this in the &vb2_ops->queue_setup op and reject it if this function returns
+ * true.
*/
static inline bool vb2_fileio_is_active(struct vb2_queue *q)
{
@@ -941,8 +1031,8 @@ static inline bool vb2_fileio_is_active(struct vb2_queue *q)
}
/**
- * vb2_is_busy() - return busy status of the queue
- * @q: videobuf queue
+ * vb2_is_busy() - return busy status of the queue.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*
* This function checks if queue has any buffers allocated.
*/
@@ -952,8 +1042,8 @@ static inline bool vb2_is_busy(struct vb2_queue *q)
}
/**
- * vb2_get_drv_priv() - return driver private data associated with the queue
- * @q: videobuf queue
+ * vb2_get_drv_priv() - return driver private data associated with the queue.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*/
static inline void *vb2_get_drv_priv(struct vb2_queue *q)
{
@@ -961,10 +1051,11 @@ static inline void *vb2_get_drv_priv(struct vb2_queue *q)
}
/**
- * vb2_set_plane_payload() - set bytesused for the plane plane_no
- * @vb: buffer for which plane payload should be set
- * @plane_no: plane number for which payload should be set
- * @size: payload in bytes
+ * vb2_set_plane_payload() - set bytesused for the plane @plane_no.
+ * @vb: pointer to &struct vb2_buffer to which the plane in
+ * question belongs to.
+ * @plane_no: plane number for which payload should be set.
+ * @size: payload in bytes.
*/
static inline void vb2_set_plane_payload(struct vb2_buffer *vb,
unsigned int plane_no, unsigned long size)
@@ -975,8 +1066,9 @@ static inline void vb2_set_plane_payload(struct vb2_buffer *vb,
/**
* vb2_get_plane_payload() - get bytesused for the plane plane_no
- * @vb: buffer for which plane payload should be set
- * @plane_no: plane number for which payload should be set
+ * @vb: pointer to &struct vb2_buffer to which the plane in
+ * question belongs to.
+ * @plane_no: plane number for which payload should be set.
*/
static inline unsigned long vb2_get_plane_payload(struct vb2_buffer *vb,
unsigned int plane_no)
@@ -987,9 +1079,10 @@ static inline unsigned long vb2_get_plane_payload(struct vb2_buffer *vb,
}
/**
- * vb2_plane_size() - return plane size in bytes
- * @vb: buffer for which plane size should be returned
- * @plane_no: plane number for which size should be returned
+ * vb2_plane_size() - return plane size in bytes.
+ * @vb: pointer to &struct vb2_buffer to which the plane in
+ * question belongs to.
+ * @plane_no: plane number for which size should be returned.
*/
static inline unsigned long
vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no)
@@ -1000,8 +1093,8 @@ vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no)
}
/**
- * vb2_start_streaming_called() - return streaming status of driver
- * @q: videobuf queue
+ * vb2_start_streaming_called() - return streaming status of driver.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*/
static inline bool vb2_start_streaming_called(struct vb2_queue *q)
{
@@ -1009,8 +1102,8 @@ static inline bool vb2_start_streaming_called(struct vb2_queue *q)
}
/**
- * vb2_clear_last_buffer_dequeued() - clear last buffer dequeued flag of queue
- * @q: videobuf queue
+ * vb2_clear_last_buffer_dequeued() - clear last buffer dequeued flag of queue.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*/
static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q)
{
@@ -1024,10 +1117,10 @@ static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q)
/**
* vb2_buffer_in_use() - return true if the buffer is in use and
- * the queue cannot be freed (by the means of REQBUFS(0)) call
+ * the queue cannot be freed (by the means of VIDIOC_REQBUFS(0)) call.
*
- * @vb: buffer for which plane size should be returned
- * @q: videobuf queue
+ * @vb: buffer for which plane size should be returned.
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*/
bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb);
@@ -1035,11 +1128,11 @@ bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb);
* vb2_verify_memory_type() - Check whether the memory type and buffer type
* passed to a buffer operation are compatible with the queue.
*
- * @q: videobuf queue
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
* @memory: memory model, as defined by enum &vb2_memory.
* @type: private buffer type whose content is defined by the vb2-core
* caller. For example, for V4L2, it should match
- * the types defined on enum &v4l2_buf_type
+ * the types defined on enum &v4l2_buf_type.
*/
int vb2_verify_memory_type(struct vb2_queue *q,
enum vb2_memory memory, unsigned int type);
diff --git a/include/media/videobuf2-dvb.h b/include/media/videobuf2-dvb.h
index 5a31faa24f1a..8605366ec87c 100644
--- a/include/media/videobuf2-dvb.h
+++ b/include/media/videobuf2-dvb.h
@@ -2,12 +2,11 @@
#ifndef _VIDEOBUF2_DVB_H_
#define _VIDEOBUF2_DVB_H_
-#include <dvbdev.h>
-#include <dmxdev.h>
-#include <dvb_demux.h>
-#include <dvb_net.h>
-#include <dvb_frontend.h>
-
+#include <media/dvbdev.h>
+#include <media/dmxdev.h>
+#include <media/dvb_demux.h>
+#include <media/dvb_net.h>
+#include <media/dvb_frontend.h>
#include <media/videobuf2-v4l2.h>
/* We don't actually need to include media-device.h here */
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
index a6ed091b79ce..4b5b84f93538 100644
--- a/include/media/videobuf2-memops.h
+++ b/include/media/videobuf2-memops.h
@@ -19,11 +19,11 @@
#include <linux/refcount.h>
/**
- * struct vb2_vmarea_handler - common vma refcount tracking handler
+ * struct vb2_vmarea_handler - common vma refcount tracking handler.
*
- * @refcount: pointer to refcount entry in the buffer
- * @put: callback to function that decreases buffer refcount
- * @arg: argument for @put callback
+ * @refcount: pointer to &refcount_t entry in the buffer.
+ * @put: callback to function that decreases buffer refcount.
+ * @arg: argument for @put callback.
*/
struct vb2_vmarea_handler {
refcount_t *refcount;
diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h
index c2fa55657440..3d5e2d739f05 100644
--- a/include/media/videobuf2-v4l2.h
+++ b/include/media/videobuf2-v4l2.h
@@ -24,16 +24,17 @@
#endif
/**
- * struct vb2_v4l2_buffer - video buffer information for v4l2
+ * struct vb2_v4l2_buffer - video buffer information for v4l2.
*
- * @vb2_buf: video buffer 2
- * @flags: buffer informational flags
- * @field: enum v4l2_field; field order of the image in the buffer
- * @timecode: frame timecode
- * @sequence: sequence count of this frame
+ * @vb2_buf: embedded struct &vb2_buffer.
+ * @flags: buffer informational flags.
+ * @field: field order of the image in the buffer, as defined by
+ * &enum v4l2_field.
+ * @timecode: frame timecode.
+ * @sequence: sequence count of this frame.
*
* Should contain enough information to be able to cover all the fields
- * of struct v4l2_buffer at videodev2.h
+ * of &struct v4l2_buffer at ``videodev2.h``.
*/
struct vb2_v4l2_buffer {
struct vb2_buffer vb2_buf;
@@ -56,9 +57,9 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b);
* vb2_reqbufs() - Wrapper for vb2_core_reqbufs() that also verifies
* the memory and type values.
*
- * @q: videobuf2 queue
- * @req: struct passed from userspace to vidioc_reqbufs handler
- * in driver
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @req: &struct v4l2_requestbuffers passed from userspace to
+ * &v4l2_ioctl_ops->vidioc_reqbufs handler in driver.
*/
int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
@@ -66,94 +67,99 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
* vb2_create_bufs() - Wrapper for vb2_core_create_bufs() that also verifies
* the memory and type values.
*
- * @q: videobuf2 queue
- * @create: creation parameters, passed from userspace to vidioc_create_bufs
- * handler in driver
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @create: creation parameters, passed from userspace to
+ * &v4l2_ioctl_ops->vidioc_create_bufs handler in driver
*/
int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create);
/**
* vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
*
- * @q: videobuf2 queue
- * @b: buffer structure passed from userspace to vidioc_prepare_buf
- * handler in driver
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @b: buffer structure passed from userspace to
+ * &v4l2_ioctl_ops->vidioc_prepare_buf handler in driver
+ *
+ * Should be called from &v4l2_ioctl_ops->vidioc_prepare_buf ioctl handler
+ * of a driver.
*
- * Should be called from vidioc_prepare_buf ioctl handler of a driver.
* This function:
*
* #) verifies the passed buffer,
- * #) calls buf_prepare callback in the driver (if provided), in which
- * driver-specific buffer initialization can be performed.
+ * #) calls &vb2_ops->buf_prepare callback in the driver (if provided),
+ * in which driver-specific buffer initialization can be performed.
*
* The return values from this function are intended to be directly returned
- * from vidioc_prepare_buf handler in driver.
+ * from &v4l2_ioctl_ops->vidioc_prepare_buf handler in driver.
*/
int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b);
/**
* vb2_qbuf() - Queue a buffer from userspace
- * @q: videobuf2 queue
- * @b: buffer structure passed from userspace to VIDIOC_QBUF() handler
- * in driver
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @b: buffer structure passed from userspace to
+ * &v4l2_ioctl_ops->vidioc_qbuf handler in driver
*
- * Should be called from VIDIOC_QBUF() ioctl handler of a driver.
+ * Should be called from &v4l2_ioctl_ops->vidioc_qbuf handler of a driver.
*
* This function:
*
- * #) verifies the passed buffer,
- * #) if necessary, calls buf_prepare callback in the driver (if provided), in
- * which driver-specific buffer initialization can be performed,
- * #) if streaming is on, queues the buffer in driver by the means of buf_queue
- * callback for processing.
+ * #) verifies the passed buffer;
+ * #) if necessary, calls &vb2_ops->buf_prepare callback in the driver
+ * (if provided), in which driver-specific buffer initialization can
+ * be performed;
+ * #) if streaming is on, queues the buffer in driver by the means of
+ * &vb2_ops->buf_queue callback for processing.
*
* The return values from this function are intended to be directly returned
- * from VIDIOC_QBUF() handler in driver.
+ * from &v4l2_ioctl_ops->vidioc_qbuf handler in driver.
*/
int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
/**
* vb2_expbuf() - Export a buffer as a file descriptor
- * @q: videobuf2 queue
- * @eb: export buffer structure passed from userspace to VIDIOC_EXPBUF()
- * handler in driver
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @eb: export buffer structure passed from userspace to
+ * &v4l2_ioctl_ops->vidioc_expbuf handler in driver
*
* The return values from this function are intended to be directly returned
- * from VIDIOC_EXPBUF() handler in driver.
+ * from &v4l2_ioctl_ops->vidioc_expbuf handler in driver.
*/
int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
/**
* vb2_dqbuf() - Dequeue a buffer to the userspace
- * @q: videobuf2 queue
- * @b: buffer structure passed from userspace to VIDIOC_DQBUF() handler
- * in driver
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @b: buffer structure passed from userspace to
+ * &v4l2_ioctl_ops->vidioc_dqbuf handler in driver
* @nonblocking: if true, this call will not sleep waiting for a buffer if no
* buffers ready for dequeuing are present. Normally the driver
- * would be passing (file->f_flags & O_NONBLOCK) here
+ * would be passing (&file->f_flags & %O_NONBLOCK) here
*
- * Should be called from VIDIOC_DQBUF() ioctl handler of a driver.
+ * Should be called from &v4l2_ioctl_ops->vidioc_dqbuf ioctl handler
+ * of a driver.
*
* This function:
*
- * #) verifies the passed buffer,
- * #) calls buf_finish callback in the driver (if provided), in which
+ * #) verifies the passed buffer;
+ * #) calls &vb2_ops->buf_finish callback in the driver (if provided), in which
* driver can perform any additional operations that may be required before
- * returning the buffer to userspace, such as cache sync,
+ * returning the buffer to userspace, such as cache sync;
* #) the buffer struct members are filled with relevant information for
* the userspace.
*
* The return values from this function are intended to be directly returned
- * from VIDIOC_DQBUF() handler in driver.
+ * from &v4l2_ioctl_ops->vidioc_dqbuf handler in driver.
*/
int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
/**
* vb2_streamon - start streaming
- * @q: videobuf2 queue
- * @type: type argument passed from userspace to vidioc_streamon handler
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
+ * @type: type argument passed from userspace to vidioc_streamon handler,
+ * as defined by &enum v4l2_buf_type.
*
- * Should be called from vidioc_streamon handler of a driver.
+ * Should be called from &v4l2_ioctl_ops->vidioc_streamon handler of a driver.
*
* This function:
*
@@ -161,13 +167,13 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
* 2) passes any previously queued buffers to the driver and starts streaming
*
* The return values from this function are intended to be directly returned
- * from vidioc_streamon handler in the driver.
+ * from &v4l2_ioctl_ops->vidioc_streamon handler in the driver.
*/
int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
/**
* vb2_streamoff - stop streaming
- * @q: videobuf2 queue
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
* @type: type argument passed from userspace to vidioc_streamoff handler
*
* Should be called from vidioc_streamoff handler of a driver.
@@ -186,7 +192,7 @@ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type);
/**
* vb2_queue_init() - initialize a videobuf2 queue
- * @q: videobuf2 queue; this structure should be allocated in driver
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*
* The vb2_queue structure should be allocated by the driver. The driver is
* responsible of clearing it's content and setting initial values for some
@@ -199,7 +205,7 @@ int __must_check vb2_queue_init(struct vb2_queue *q);
/**
* vb2_queue_release() - stop streaming, release the queue and free memory
- * @q: videobuf2 queue
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
*
* This function stops streaming and performs necessary clean ups, including
* freeing video buffer memory. The driver is responsible for freeing
@@ -209,7 +215,7 @@ void vb2_queue_release(struct vb2_queue *q);
/**
* vb2_poll() - implements poll userspace operation
- * @q: videobuf2 queue
+ * @q: pointer to &struct vb2_queue with videobuf2 queue.
* @file: file argument passed to the poll file operation handler
* @wait: wait argument passed to the poll file operation handler
*
@@ -270,7 +276,7 @@ unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr,
/**
* vb2_ops_wait_prepare - helper function to lock a struct &vb2_queue
*
- * @vq: pointer to struct vb2_queue
+ * @vq: pointer to &struct vb2_queue
*
* ..note:: only use if vq->lock is non-NULL.
*/
@@ -279,7 +285,7 @@ void vb2_ops_wait_prepare(struct vb2_queue *vq);
/**
* vb2_ops_wait_finish - helper function to unlock a struct &vb2_queue
*
- * @vq: pointer to struct vb2_queue
+ * @vq: pointer to &struct vb2_queue
*
* ..note:: only use if vq->lock is non-NULL.
*/
diff --git a/include/net/erspan.h b/include/net/erspan.h
index 5daa4866412b..d044aa60cc76 100644
--- a/include/net/erspan.h
+++ b/include/net/erspan.h
@@ -159,13 +159,13 @@ static inline void erspan_build_header(struct sk_buff *skb,
struct ethhdr *eth = (struct ethhdr *)skb->data;
enum erspan_encap_type enc_type;
struct erspan_base_hdr *ershdr;
- struct erspan_metadata *ersmd;
struct qtag_prefix {
__be16 eth_type;
__be16 tci;
} *qp;
u16 vlan_tci = 0;
u8 tos;
+ __be32 *idx;
tos = is_ipv4 ? ip_hdr(skb)->tos :
(ipv6_hdr(skb)->priority << 4) +
@@ -195,8 +195,8 @@ static inline void erspan_build_header(struct sk_buff *skb,
set_session_id(ershdr, id);
/* Build metadata */
- ersmd = (struct erspan_metadata *)(ershdr + 1);
- ersmd->u.index = htonl(index & INDEX_MASK);
+ idx = (__be32 *)(ershdr + 1);
+ *idx = htonl(index & INDEX_MASK);
}
/* ERSPAN GRA: timestamp granularity
@@ -225,7 +225,7 @@ static inline void erspan_build_header_v2(struct sk_buff *skb,
{
struct ethhdr *eth = (struct ethhdr *)skb->data;
struct erspan_base_hdr *ershdr;
- struct erspan_metadata *md;
+ struct erspan_md2 *md2;
struct qtag_prefix {
__be16 eth_type;
__be16 tci;
@@ -261,15 +261,15 @@ static inline void erspan_build_header_v2(struct sk_buff *skb,
set_session_id(ershdr, id);
/* Build metadata */
- md = (struct erspan_metadata *)(ershdr + 1);
- md->u.md2.timestamp = erspan_get_timestamp();
- md->u.md2.sgt = htons(sgt);
- md->u.md2.p = 1;
- md->u.md2.ft = 0;
- md->u.md2.dir = direction;
- md->u.md2.gra = gra;
- md->u.md2.o = 0;
- set_hwid(&md->u.md2, hwid);
+ md2 = (struct erspan_md2 *)(ershdr + 1);
+ md2->timestamp = erspan_get_timestamp();
+ md2->sgt = htons(sgt);
+ md2->p = 1;
+ md2->ft = 0;
+ md2->dir = direction;
+ md2->gra = gra;
+ md2->o = 0;
+ set_hwid(md2, hwid);
}
#endif
diff --git a/include/rdma/ib_hdrs.h b/include/rdma/ib_hdrs.h
index c124d515f7d5..6e35416170a3 100644
--- a/include/rdma/ib_hdrs.h
+++ b/include/rdma/ib_hdrs.h
@@ -313,16 +313,14 @@ static inline u32 ib_bth_get_qpn(struct ib_other_headers *ohdr)
return (u32)((be32_to_cpu(ohdr->bth[1])) & IB_QPN_MASK);
}
-static inline u8 ib_bth_get_becn(struct ib_other_headers *ohdr)
+static inline bool ib_bth_get_becn(struct ib_other_headers *ohdr)
{
- return (u8)((be32_to_cpu(ohdr->bth[1]) >> IB_BECN_SHIFT) &
- IB_BECN_MASK);
+ return (ohdr->bth[1]) & cpu_to_be32(IB_BECN_SMASK);
}
-static inline u8 ib_bth_get_fecn(struct ib_other_headers *ohdr)
+static inline bool ib_bth_get_fecn(struct ib_other_headers *ohdr)
{
- return (u8)((be32_to_cpu(ohdr->bth[1]) >> IB_FECN_SHIFT) &
- IB_FECN_MASK);
+ return (ohdr->bth[1]) & cpu_to_be32(IB_FECN_SMASK);
}
static inline u8 ib_bth_get_tver(struct ib_other_headers *ohdr)
@@ -331,4 +329,13 @@ static inline u8 ib_bth_get_tver(struct ib_other_headers *ohdr)
IB_BTH_TVER_MASK);
}
+static inline bool ib_bth_is_solicited(struct ib_other_headers *ohdr)
+{
+ return ohdr->bth[0] & cpu_to_be32(IB_BTH_SOLICITED);
+}
+
+static inline bool ib_bth_is_migration(struct ib_other_headers *ohdr)
+{
+ return ohdr->bth[0] & cpu_to_be32(IB_BTH_MIG_REQ);
+}
#endif /* IB_HDRS_H */
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 5263c86fd103..73b2387e3f74 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -874,6 +874,7 @@ struct ib_mr_status {
__attribute_const__ enum ib_rate mult_to_ib_rate(int mult);
enum rdma_ah_attr_type {
+ RDMA_AH_ATTR_TYPE_UNDEFINED,
RDMA_AH_ATTR_TYPE_IB,
RDMA_AH_ATTR_TYPE_ROCE,
RDMA_AH_ATTR_TYPE_OPA,
@@ -3810,17 +3811,24 @@ static inline void rdma_ah_set_grh(struct rdma_ah_attr *attr,
grh->traffic_class = traffic_class;
}
-/*Get AH type */
+/**
+ * rdma_ah_find_type - Return address handle type.
+ *
+ * @dev: Device to be checked
+ * @port_num: Port number
+ */
static inline enum rdma_ah_attr_type rdma_ah_find_type(struct ib_device *dev,
- u32 port_num)
+ u8 port_num)
{
if (rdma_protocol_roce(dev, port_num))
return RDMA_AH_ATTR_TYPE_ROCE;
- else if ((rdma_protocol_ib(dev, port_num)) &&
- (rdma_cap_opa_ah(dev, port_num)))
- return RDMA_AH_ATTR_TYPE_OPA;
- else
+ if (rdma_protocol_ib(dev, port_num)) {
+ if (rdma_cap_opa_ah(dev, port_num))
+ return RDMA_AH_ATTR_TYPE_OPA;
return RDMA_AH_ATTR_TYPE_IB;
+ }
+
+ return RDMA_AH_ATTR_TYPE_UNDEFINED;
}
/**
diff --git a/include/sound/soc.h b/include/sound/soc.h
index b655d987fbe7..747fd583b9dc 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -841,7 +841,7 @@ struct snd_soc_component_driver {
/* bits */
unsigned int idle_bias_on:1;
unsigned int suspend_bias_off:1;
- unsigned int pmdown_time:1; /* care pmdown_time at stop */
+ unsigned int use_pmdown_time:1; /* care pmdown_time at stop */
unsigned int endianness:1;
unsigned int non_legacy_dai_naming:1;
};
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
index 254afc31e3be..85dc965afd89 100644
--- a/include/uapi/asm-generic/siginfo.h
+++ b/include/uapi/asm-generic/siginfo.h
@@ -280,8 +280,8 @@ typedef struct siginfo {
#define NSIGTRAP 4
/*
- * There are an additional set of SIGTRAP si_codes used by ptrace
- * that of the form: ((PTRACE_EVENT_XXX << 8) | SIGTRAP)
+ * There is an additional set of SIGTRAP si_codes used by ptrace
+ * that are of the form: ((PTRACE_EVENT_XXX << 8) | SIGTRAP)
*/
/*
diff --git a/include/uapi/linux/dvb/dmx.h b/include/uapi/linux/dvb/dmx.h
index c10f1324b4ca..5f3c5a918f00 100644
--- a/include/uapi/linux/dvb/dmx.h
+++ b/include/uapi/linux/dvb/dmx.h
@@ -211,6 +211,61 @@ struct dmx_stc {
__u64 stc;
};
+/**
+ * struct dmx_buffer - dmx buffer info
+ *
+ * @index: id number of the buffer
+ * @bytesused: number of bytes occupied by data in the buffer (payload);
+ * @offset: for buffers with memory == DMX_MEMORY_MMAP;
+ * offset from the start of the device memory for this plane,
+ * (or a "cookie" that should be passed to mmap() as offset)
+ * @length: size in bytes of the buffer
+ *
+ * Contains data exchanged by application and driver using one of the streaming
+ * I/O methods.
+ */
+struct dmx_buffer {
+ __u32 index;
+ __u32 bytesused;
+ __u32 offset;
+ __u32 length;
+};
+
+/**
+ * struct dmx_requestbuffers - request dmx buffer information
+ *
+ * @count: number of requested buffers,
+ * @size: size in bytes of the requested buffer
+ *
+ * Contains data used for requesting a dmx buffer.
+ * All reserved fields must be set to zero.
+ */
+struct dmx_requestbuffers {
+ __u32 count;
+ __u32 size;
+};
+
+/**
+ * struct dmx_exportbuffer - export of dmx buffer as DMABUF file descriptor
+ *
+ * @index: id number of the buffer
+ * @flags: flags for newly created file, currently only O_CLOEXEC is
+ * supported, refer to manual of open syscall for more details
+ * @fd: file descriptor associated with DMABUF (set by driver)
+ *
+ * Contains data used for exporting a dmx buffer as DMABUF file descriptor.
+ * The buffer is identified by a 'cookie' returned by DMX_QUERYBUF
+ * (identical to the cookie used to mmap() the buffer to userspace). All
+ * reserved fields must be set to zero. The field reserved0 is expected to
+ * become a structure 'type' allowing an alternative layout of the structure
+ * content. Therefore this field should not be used for any other extensions.
+ */
+struct dmx_exportbuffer {
+ __u32 index;
+ __u32 flags;
+ __s32 fd;
+};
+
#define DMX_START _IO('o', 41)
#define DMX_STOP _IO('o', 42)
#define DMX_SET_FILTER _IOW('o', 43, struct dmx_sct_filter_params)
@@ -231,4 +286,10 @@ typedef struct dmx_filter dmx_filter_t;
#endif
-#endif /* _UAPI_DVBDMX_H_ */
+#define DMX_REQBUFS _IOWR('o', 60, struct dmx_requestbuffers)
+#define DMX_QUERYBUF _IOWR('o', 61, struct dmx_buffer)
+#define DMX_EXPBUF _IOWR('o', 62, struct dmx_exportbuffer)
+#define DMX_QBUF _IOWR('o', 63, struct dmx_buffer)
+#define DMX_DQBUF _IOWR('o', 64, struct dmx_buffer)
+
+#endif /* _DVBDMX_H_ */
diff --git a/include/uapi/linux/dvb/frontend.h b/include/uapi/linux/dvb/frontend.h
index b297b65845d6..4f9b4551c534 100644
--- a/include/uapi/linux/dvb/frontend.h
+++ b/include/uapi/linux/dvb/frontend.h
@@ -547,7 +547,10 @@ enum fe_interleaving {
#define DTV_STAT_ERROR_BLOCK_COUNT 68
#define DTV_STAT_TOTAL_BLOCK_COUNT 69
-#define DTV_MAX_COMMAND DTV_STAT_TOTAL_BLOCK_COUNT
+/* Physical layer scrambling */
+#define DTV_SCRAMBLING_SEQUENCE_INDEX 70
+
+#define DTV_MAX_COMMAND DTV_SCRAMBLING_SEQUENCE_INDEX
/**
* enum fe_pilot - Type of pilot tone
@@ -756,16 +759,15 @@ enum fecap_scale_params {
/**
* struct dtv_stats - Used for reading a DTV status property
*
- * @scale: Filled with enum fecap_scale_params - the scale
- * in usage for that parameter
- *
- * The ``{unnamed_union}`` may have either one of the values below:
+ * @scale:
+ * Filled with enum fecap_scale_params - the scale in usage
+ * for that parameter
*
- * %svalue
+ * @svalue:
* integer value of the measure, for %FE_SCALE_DECIBEL,
* used for dB measures. The unit is 0.001 dB.
*
- * %uvalue
+ * @uvalue:
* unsigned integer value of the measure, used when @scale is
* either %FE_SCALE_RELATIVE or %FE_SCALE_COUNTER.
*
@@ -828,19 +830,19 @@ struct dtv_fe_stats {
/**
* struct dtv_property - store one of frontend command and its value
*
- * @cmd: Digital TV command.
- * @reserved: Not used.
- * @u: Union with the values for the command.
- * @result: Unused
- *
- * The @u union may have either one of the values below:
+ * @cmd: Digital TV command.
+ * @reserved: Not used.
+ * @u: Union with the values for the command.
+ * @u.data: A unsigned 32 bits integer with command value.
+ * @u.buffer: Struct to store bigger properties.
+ * Currently unused.
+ * @u.buffer.data: an unsigned 32-bits array.
+ * @u.buffer.len: number of elements of the buffer.
+ * @u.buffer.reserved1: Reserved.
+ * @u.buffer.reserved2: Reserved.
+ * @u.st: a &struct dtv_fe_stats array of statistics.
+ * @result: Currently unused.
*
- * %data
- * an unsigned 32-bits number.
- * %st
- * a &struct dtv_fe_stats array of statistics.
- * %buffer
- * a buffer of up to 32 characters (currently unused).
*/
struct dtv_property {
__u32 cmd;
diff --git a/include/uapi/linux/dvb/version.h b/include/uapi/linux/dvb/version.h
index 02e32ea83984..2c5cffe6d2a0 100644
--- a/include/uapi/linux/dvb/version.h
+++ b/include/uapi/linux/dvb/version.h
@@ -25,6 +25,6 @@
#define _DVBVERSION_H_
#define DVB_API_VERSION 5
-#define DVB_API_VERSION_MINOR 10
+#define DVB_API_VERSION_MINOR 11
#endif /*_DVBVERSION_H_*/
diff --git a/include/uapi/linux/dvb/video.h b/include/uapi/linux/dvb/video.h
index 4d51f98182bb..df3d7028c807 100644
--- a/include/uapi/linux/dvb/video.h
+++ b/include/uapi/linux/dvb/video.h
@@ -83,11 +83,11 @@ typedef enum {
#define VIDEO_CMD_CONTINUE (3)
/* Flags for VIDEO_CMD_FREEZE */
-#define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0)
+#define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0)
/* Flags for VIDEO_CMD_STOP */
-#define VIDEO_CMD_STOP_TO_BLACK (1 << 0)
-#define VIDEO_CMD_STOP_IMMEDIATELY (1 << 1)
+#define VIDEO_CMD_STOP_TO_BLACK (1 << 0)
+#define VIDEO_CMD_STOP_IMMEDIATELY (1 << 1)
/* Play input formats: */
/* The decoder has no special format requirements */
@@ -124,8 +124,8 @@ struct video_command {
/* FIELD_UNKNOWN can be used if the hardware does not know whether
the Vsync is for an odd, even or progressive (i.e. non-interlaced)
field. */
-#define VIDEO_VSYNC_FIELD_UNKNOWN (0)
-#define VIDEO_VSYNC_FIELD_ODD (1)
+#define VIDEO_VSYNC_FIELD_UNKNOWN (0)
+#define VIDEO_VSYNC_FIELD_ODD (1)
#define VIDEO_VSYNC_FIELD_EVEN (2)
#define VIDEO_VSYNC_FIELD_PROGRESSIVE (3)
@@ -133,8 +133,8 @@ struct video_event {
__s32 type;
#define VIDEO_EVENT_SIZE_CHANGED 1
#define VIDEO_EVENT_FRAME_RATE_CHANGED 2
-#define VIDEO_EVENT_DECODER_STOPPED 3
-#define VIDEO_EVENT_VSYNC 4
+#define VIDEO_EVENT_DECODER_STOPPED 3
+#define VIDEO_EVENT_VSYNC 4
/* unused, make sure to use atomic time for y2038 if it ever gets used */
long timestamp;
union {
@@ -268,9 +268,9 @@ typedef __u16 video_attributes_t;
#define VIDEO_GET_PTS _IOR('o', 57, __u64)
/* Read the number of displayed frames since the decoder was started */
-#define VIDEO_GET_FRAME_COUNT _IOR('o', 58, __u64)
+#define VIDEO_GET_FRAME_COUNT _IOR('o', 58, __u64)
-#define VIDEO_COMMAND _IOWR('o', 59, struct video_command)
-#define VIDEO_TRY_COMMAND _IOWR('o', 60, struct video_command)
+#define VIDEO_COMMAND _IOWR('o', 59, struct video_command)
+#define VIDEO_TRY_COMMAND _IOWR('o', 60, struct video_command)
#endif /* _UAPI_DVBVIDEO_H_ */
diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
index 061fa62958a2..53fbae27b280 100644
--- a/include/uapi/linux/input-event-codes.h
+++ b/include/uapi/linux/input-event-codes.h
@@ -594,6 +594,7 @@
#define BTN_DPAD_RIGHT 0x223
#define KEY_ALS_TOGGLE 0x230 /* Ambient light sensor */
+#define KEY_ROTATE_LOCK_TOGGLE 0x231 /* Display rotation lock */
#define KEY_BUTTONCONFIG 0x240 /* AL Button Configuration */
#define KEY_TASKMANAGER 0x241 /* AL Task/Project Manager */
diff --git a/include/uapi/linux/lirc.h b/include/uapi/linux/lirc.h
index c3aef4316fbf..4fe580d36e41 100644
--- a/include/uapi/linux/lirc.h
+++ b/include/uapi/linux/lirc.h
@@ -47,12 +47,14 @@
#define LIRC_MODE_RAW 0x00000001
#define LIRC_MODE_PULSE 0x00000002
#define LIRC_MODE_MODE2 0x00000004
+#define LIRC_MODE_SCANCODE 0x00000008
#define LIRC_MODE_LIRCCODE 0x00000010
#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW)
#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE)
#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2)
+#define LIRC_CAN_SEND_SCANCODE LIRC_MODE2SEND(LIRC_MODE_SCANCODE)
#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE)
#define LIRC_CAN_SEND_MASK 0x0000003f
@@ -64,6 +66,7 @@
#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW)
#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE)
#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2)
+#define LIRC_CAN_REC_SCANCODE LIRC_MODE2REC(LIRC_MODE_SCANCODE)
#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE)
#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK)
@@ -131,4 +134,83 @@
#define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32)
+/*
+ * struct lirc_scancode - decoded scancode with protocol for use with
+ * LIRC_MODE_SCANCODE
+ *
+ * @timestamp: Timestamp in nanoseconds using CLOCK_MONOTONIC when IR
+ * was decoded.
+ * @flags: should be 0 for transmit. When receiving scancodes,
+ * LIRC_SCANCODE_FLAG_TOGGLE or LIRC_SCANCODE_FLAG_REPEAT can be set
+ * depending on the protocol
+ * @rc_proto: see enum rc_proto
+ * @keycode: the translated keycode. Set to 0 for transmit.
+ * @scancode: the scancode received or to be sent
+ */
+struct lirc_scancode {
+ __u64 timestamp;
+ __u16 flags;
+ __u16 rc_proto;
+ __u32 keycode;
+ __u64 scancode;
+};
+
+/* Set if the toggle bit of rc-5 or rc-6 is enabled */
+#define LIRC_SCANCODE_FLAG_TOGGLE 1
+/* Set if this is a nec or sanyo repeat */
+#define LIRC_SCANCODE_FLAG_REPEAT 2
+
+/**
+ * enum rc_proto - the Remote Controller protocol
+ *
+ * @RC_PROTO_UNKNOWN: Protocol not known
+ * @RC_PROTO_OTHER: Protocol known but proprietary
+ * @RC_PROTO_RC5: Philips RC5 protocol
+ * @RC_PROTO_RC5X_20: Philips RC5x 20 bit protocol
+ * @RC_PROTO_RC5_SZ: StreamZap variant of RC5
+ * @RC_PROTO_JVC: JVC protocol
+ * @RC_PROTO_SONY12: Sony 12 bit protocol
+ * @RC_PROTO_SONY15: Sony 15 bit protocol
+ * @RC_PROTO_SONY20: Sony 20 bit protocol
+ * @RC_PROTO_NEC: NEC protocol
+ * @RC_PROTO_NECX: Extended NEC protocol
+ * @RC_PROTO_NEC32: NEC 32 bit protocol
+ * @RC_PROTO_SANYO: Sanyo protocol
+ * @RC_PROTO_MCIR2_KBD: RC6-ish MCE keyboard
+ * @RC_PROTO_MCIR2_MSE: RC6-ish MCE mouse
+ * @RC_PROTO_RC6_0: Philips RC6-0-16 protocol
+ * @RC_PROTO_RC6_6A_20: Philips RC6-6A-20 protocol
+ * @RC_PROTO_RC6_6A_24: Philips RC6-6A-24 protocol
+ * @RC_PROTO_RC6_6A_32: Philips RC6-6A-32 protocol
+ * @RC_PROTO_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol
+ * @RC_PROTO_SHARP: Sharp protocol
+ * @RC_PROTO_XMP: XMP protocol
+ * @RC_PROTO_CEC: CEC protocol
+ */
+enum rc_proto {
+ RC_PROTO_UNKNOWN = 0,
+ RC_PROTO_OTHER = 1,
+ RC_PROTO_RC5 = 2,
+ RC_PROTO_RC5X_20 = 3,
+ RC_PROTO_RC5_SZ = 4,
+ RC_PROTO_JVC = 5,
+ RC_PROTO_SONY12 = 6,
+ RC_PROTO_SONY15 = 7,
+ RC_PROTO_SONY20 = 8,
+ RC_PROTO_NEC = 9,
+ RC_PROTO_NECX = 10,
+ RC_PROTO_NEC32 = 11,
+ RC_PROTO_SANYO = 12,
+ RC_PROTO_MCIR2_KBD = 13,
+ RC_PROTO_MCIR2_MSE = 14,
+ RC_PROTO_RC6_0 = 15,
+ RC_PROTO_RC6_6A_20 = 16,
+ RC_PROTO_RC6_6A_24 = 17,
+ RC_PROTO_RC6_6A_32 = 18,
+ RC_PROTO_RC6_MCE = 19,
+ RC_PROTO_SHARP = 20,
+ RC_PROTO_XMP = 21,
+ RC_PROTO_CEC = 22,
+};
+
#endif
diff --git a/include/uapi/linux/membarrier.h b/include/uapi/linux/membarrier.h
index 4e01ad7ffe98..5891d7614c8c 100644
--- a/include/uapi/linux/membarrier.h
+++ b/include/uapi/linux/membarrier.h
@@ -31,7 +31,7 @@
* enum membarrier_cmd - membarrier system call command
* @MEMBARRIER_CMD_QUERY: Query the set of supported commands. It returns
* a bitmask of valid commands.
- * @MEMBARRIER_CMD_SHARED: Execute a memory barrier on all running threads.
+ * @MEMBARRIER_CMD_GLOBAL: Execute a memory barrier on all running threads.
* Upon return from system call, the caller thread
* is ensured that all running threads have passed
* through a state where all memory accesses to
@@ -40,6 +40,28 @@
* (non-running threads are de facto in such a
* state). This covers threads from all processes
* running on the system. This command returns 0.
+ * @MEMBARRIER_CMD_GLOBAL_EXPEDITED:
+ * Execute a memory barrier on all running threads
+ * of all processes which previously registered
+ * with MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED.
+ * Upon return from system call, the caller thread
+ * is ensured that all running threads have passed
+ * through a state where all memory accesses to
+ * user-space addresses match program order between
+ * entry to and return from the system call
+ * (non-running threads are de facto in such a
+ * state). This only covers threads from processes
+ * which registered with
+ * MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED.
+ * This command returns 0. Given that
+ * registration is about the intent to receive
+ * the barriers, it is valid to invoke
+ * MEMBARRIER_CMD_GLOBAL_EXPEDITED from a
+ * non-registered process.
+ * @MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED:
+ * Register the process intent to receive
+ * MEMBARRIER_CMD_GLOBAL_EXPEDITED memory
+ * barriers. Always returns 0.
* @MEMBARRIER_CMD_PRIVATE_EXPEDITED:
* Execute a memory barrier on each running
* thread belonging to the same process as the current
@@ -51,7 +73,7 @@
* to and return from the system call
* (non-running threads are de facto in such a
* state). This only covers threads from the
- * same processes as the caller thread. This
+ * same process as the caller thread. This
* command returns 0 on success. The
* "expedited" commands complete faster than
* the non-expedited ones, they never block,
@@ -64,18 +86,54 @@
* Register the process intent to use
* MEMBARRIER_CMD_PRIVATE_EXPEDITED. Always
* returns 0.
+ * @MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE:
+ * In addition to provide memory ordering
+ * guarantees described in
+ * MEMBARRIER_CMD_PRIVATE_EXPEDITED, ensure
+ * the caller thread, upon return from system
+ * call, that all its running threads siblings
+ * have executed a core serializing
+ * instruction. (architectures are required to
+ * guarantee that non-running threads issue
+ * core serializing instructions before they
+ * resume user-space execution). This only
+ * covers threads from the same process as the
+ * caller thread. This command returns 0 on
+ * success. The "expedited" commands complete
+ * faster than the non-expedited ones, they
+ * never block, but have the downside of
+ * causing extra overhead. If this command is
+ * not implemented by an architecture, -EINVAL
+ * is returned. A process needs to register its
+ * intent to use the private expedited sync
+ * core command prior to using it, otherwise
+ * this command returns -EPERM.
+ * @MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE:
+ * Register the process intent to use
+ * MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE.
+ * If this command is not implemented by an
+ * architecture, -EINVAL is returned.
+ * Returns 0 on success.
+ * @MEMBARRIER_CMD_SHARED:
+ * Alias to MEMBARRIER_CMD_GLOBAL. Provided for
+ * header backward compatibility.
*
* Command to be passed to the membarrier system call. The commands need to
* be a single bit each, except for MEMBARRIER_CMD_QUERY which is assigned to
* the value 0.
*/
enum membarrier_cmd {
- MEMBARRIER_CMD_QUERY = 0,
- MEMBARRIER_CMD_SHARED = (1 << 0),
- /* reserved for MEMBARRIER_CMD_SHARED_EXPEDITED (1 << 1) */
- /* reserved for MEMBARRIER_CMD_PRIVATE (1 << 2) */
- MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3),
- MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
+ MEMBARRIER_CMD_QUERY = 0,
+ MEMBARRIER_CMD_GLOBAL = (1 << 0),
+ MEMBARRIER_CMD_GLOBAL_EXPEDITED = (1 << 1),
+ MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = (1 << 2),
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3),
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 5),
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = (1 << 6),
+
+ /* Alias for header backward compatibility. */
+ MEMBARRIER_CMD_SHARED = MEMBARRIER_CMD_GLOBAL,
};
#endif /* _UAPI_LINUX_MEMBARRIER_H */
diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 3f03567631cb..7e27070b9440 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -15,54 +15,6 @@
#include <linux/types.h>
-struct nd_cmd_smart {
- __u32 status;
- __u8 data[128];
-} __packed;
-
-#define ND_SMART_HEALTH_VALID (1 << 0)
-#define ND_SMART_SPARES_VALID (1 << 1)
-#define ND_SMART_USED_VALID (1 << 2)
-#define ND_SMART_TEMP_VALID (1 << 3)
-#define ND_SMART_CTEMP_VALID (1 << 4)
-#define ND_SMART_ALARM_VALID (1 << 9)
-#define ND_SMART_SHUTDOWN_VALID (1 << 10)
-#define ND_SMART_VENDOR_VALID (1 << 11)
-#define ND_SMART_SPARE_TRIP (1 << 0)
-#define ND_SMART_TEMP_TRIP (1 << 1)
-#define ND_SMART_CTEMP_TRIP (1 << 2)
-#define ND_SMART_NON_CRITICAL_HEALTH (1 << 0)
-#define ND_SMART_CRITICAL_HEALTH (1 << 1)
-#define ND_SMART_FATAL_HEALTH (1 << 2)
-
-struct nd_smart_payload {
- __u32 flags;
- __u8 reserved0[4];
- __u8 health;
- __u8 spares;
- __u8 life_used;
- __u8 alarm_flags;
- __u16 temperature;
- __u16 ctrl_temperature;
- __u8 reserved1[15];
- __u8 shutdown_state;
- __u32 vendor_size;
- __u8 vendor_data[92];
-} __packed;
-
-struct nd_cmd_smart_threshold {
- __u32 status;
- __u8 data[8];
-} __packed;
-
-struct nd_smart_threshold_payload {
- __u8 alarm_control;
- __u8 reserved0;
- __u16 temperature;
- __u8 spares;
- __u8 reserved[3];
-} __packed;
-
struct nd_cmd_dimm_flags {
__u32 status;
__u32 flags;
@@ -211,12 +163,6 @@ static inline const char *nvdimm_cmd_name(unsigned cmd)
#define ND_IOCTL 'N'
-#define ND_IOCTL_SMART _IOWR(ND_IOCTL, ND_CMD_SMART,\
- struct nd_cmd_smart)
-
-#define ND_IOCTL_SMART_THRESHOLD _IOWR(ND_IOCTL, ND_CMD_SMART_THRESHOLD,\
- struct nd_cmd_smart_threshold)
-
#define ND_IOCTL_DIMM_FLAGS _IOWR(ND_IOCTL, ND_CMD_DIMM_FLAGS,\
struct nd_cmd_dimm_flags)
@@ -263,7 +209,7 @@ enum nd_driver_flags {
};
enum {
- ND_MIN_NAMESPACE_SIZE = 0x00400000,
+ ND_MIN_NAMESPACE_SIZE = PAGE_SIZE,
};
enum ars_masks {
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index 70c2b2ade048..0c79eac5e9b8 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -622,15 +622,19 @@
* safely.
*/
#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */
+#define PCI_EXP_DEVCAP2_COMP_TMOUT_DIS 0x00000010 /* Completion Timeout Disable supported */
#define PCI_EXP_DEVCAP2_ARI 0x00000020 /* Alternative Routing-ID */
#define PCI_EXP_DEVCAP2_ATOMIC_ROUTE 0x00000040 /* Atomic Op routing */
-#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* Atomic 64-bit compare */
+#define PCI_EXP_DEVCAP2_ATOMIC_COMP32 0x00000080 /* 32b AtomicOp completion */
+#define PCI_EXP_DEVCAP2_ATOMIC_COMP64 0x00000100 /* 64b AtomicOp completion */
+#define PCI_EXP_DEVCAP2_ATOMIC_COMP128 0x00000200 /* 128b AtomicOp completion */
#define PCI_EXP_DEVCAP2_LTR 0x00000800 /* Latency tolerance reporting */
#define PCI_EXP_DEVCAP2_OBFF_MASK 0x000c0000 /* OBFF support mechanism */
#define PCI_EXP_DEVCAP2_OBFF_MSG 0x00040000 /* New message signaling */
#define PCI_EXP_DEVCAP2_OBFF_WAKE 0x00080000 /* Re-use WAKE# for OBFF */
#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
#define PCI_EXP_DEVCTL2_COMP_TIMEOUT 0x000f /* Completion Timeout Value */
+#define PCI_EXP_DEVCTL2_COMP_TMOUT_DIS 0x0010 /* Completion Timeout Disable */
#define PCI_EXP_DEVCTL2_ARI 0x0020 /* Alternative Routing-ID */
#define PCI_EXP_DEVCTL2_ATOMIC_REQ 0x0040 /* Set Atomic requests */
#define PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK 0x0080 /* Block atomic egress */
@@ -966,26 +970,28 @@
/* Downstream Port Containment */
#define PCI_EXP_DPC_CAP 4 /* DPC Capability */
-#define PCI_EXP_DPC_IRQ 0x1f /* DPC Interrupt Message Number */
-#define PCI_EXP_DPC_CAP_RP_EXT 0x20 /* Root Port Extensions for DPC */
-#define PCI_EXP_DPC_CAP_POISONED_TLP 0x40 /* Poisoned TLP Egress Blocking Supported */
-#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x80 /* Software Triggering Supported */
-#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0xF00 /* RP PIO log size */
+#define PCI_EXP_DPC_IRQ 0x001F /* Interrupt Message Number */
+#define PCI_EXP_DPC_CAP_RP_EXT 0x0020 /* Root Port Extensions */
+#define PCI_EXP_DPC_CAP_POISONED_TLP 0x0040 /* Poisoned TLP Egress Blocking Supported */
+#define PCI_EXP_DPC_CAP_SW_TRIGGER 0x0080 /* Software Triggering Supported */
+#define PCI_EXP_DPC_RP_PIO_LOG_SIZE 0x0F00 /* RP PIO Log Size */
#define PCI_EXP_DPC_CAP_DL_ACTIVE 0x1000 /* ERR_COR signal on DL_Active supported */
#define PCI_EXP_DPC_CTL 6 /* DPC control */
-#define PCI_EXP_DPC_CTL_EN_NONFATAL 0x02 /* Enable trigger on ERR_NONFATAL message */
-#define PCI_EXP_DPC_CTL_INT_EN 0x08 /* DPC Interrupt Enable */
+#define PCI_EXP_DPC_CTL_EN_NONFATAL 0x0002 /* Enable trigger on ERR_NONFATAL message */
+#define PCI_EXP_DPC_CTL_INT_EN 0x0008 /* DPC Interrupt Enable */
#define PCI_EXP_DPC_STATUS 8 /* DPC Status */
-#define PCI_EXP_DPC_STATUS_TRIGGER 0x01 /* Trigger Status */
-#define PCI_EXP_DPC_STATUS_INTERRUPT 0x08 /* Interrupt Status */
-#define PCI_EXP_DPC_RP_BUSY 0x10 /* Root Port Busy */
+#define PCI_EXP_DPC_STATUS_TRIGGER 0x0001 /* Trigger Status */
+#define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x0006 /* Trigger Reason */
+#define PCI_EXP_DPC_STATUS_INTERRUPT 0x0008 /* Interrupt Status */
+#define PCI_EXP_DPC_RP_BUSY 0x0010 /* Root Port Busy */
+#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */
#define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */
#define PCI_EXP_DPC_RP_PIO_STATUS 0x0C /* RP PIO Status */
-#define PCI_EXP_DPC_RP_PIO_MASK 0x10 /* RP PIO MASK */
+#define PCI_EXP_DPC_RP_PIO_MASK 0x10 /* RP PIO Mask */
#define PCI_EXP_DPC_RP_PIO_SEVERITY 0x14 /* RP PIO Severity */
#define PCI_EXP_DPC_RP_PIO_SYSERROR 0x18 /* RP PIO SysError */
#define PCI_EXP_DPC_RP_PIO_EXCEPTION 0x1C /* RP PIO Exception */
diff --git a/include/uapi/linux/switchtec_ioctl.h b/include/uapi/linux/switchtec_ioctl.h
index 75df44373034..4f4daf8db954 100644
--- a/include/uapi/linux/switchtec_ioctl.h
+++ b/include/uapi/linux/switchtec_ioctl.h
@@ -88,7 +88,8 @@ struct switchtec_ioctl_event_summary {
#define SWITCHTEC_IOCTL_EVENT_FORCE_SPEED 26
#define SWITCHTEC_IOCTL_EVENT_CREDIT_TIMEOUT 27
#define SWITCHTEC_IOCTL_EVENT_LINK_STATE 28
-#define SWITCHTEC_IOCTL_MAX_EVENTS 29
+#define SWITCHTEC_IOCTL_EVENT_GFMS 29
+#define SWITCHTEC_IOCTL_MAX_EVENTS 30
#define SWITCHTEC_IOCTL_EVENT_LOCAL_PART_IDX -1
#define SWITCHTEC_IOCTL_EVENT_IDX_ALL -2
diff --git a/include/uapi/linux/uuid.h b/include/uapi/linux/uuid.h
index 5c04130bb524..e5a7eecef7c3 100644
--- a/include/uapi/linux/uuid.h
+++ b/include/uapi/linux/uuid.h
@@ -19,7 +19,6 @@
#define _UAPI_LINUX_UUID_H_
#include <linux/types.h>
-#include <linux/string.h>
typedef struct {
__u8 b[16];
diff --git a/include/uapi/linux/uvcvideo.h b/include/uapi/linux/uvcvideo.h
index e80b4655d8cd..020714d2c5bd 100644
--- a/include/uapi/linux/uvcvideo.h
+++ b/include/uapi/linux/uvcvideo.h
@@ -68,4 +68,30 @@ struct uvc_xu_control_query {
#define UVCIOC_CTRL_MAP _IOWR('u', 0x20, struct uvc_xu_control_mapping)
#define UVCIOC_CTRL_QUERY _IOWR('u', 0x21, struct uvc_xu_control_query)
+/*
+ * Metadata node
+ */
+
+/**
+ * struct uvc_meta_buf - metadata buffer building block
+ * @ns - system timestamp of the payload in nanoseconds
+ * @sof - USB Frame Number
+ * @length - length of the payload header
+ * @flags - payload header flags
+ * @buf - optional device-specific header data
+ *
+ * UVC metadata nodes fill buffers with possibly multiple instances of this
+ * struct. The first two fields are added by the driver, they can be used for
+ * clock synchronisation. The rest is an exact copy of a UVC payload header.
+ * Only complete objects with complete buffers are included. Therefore it's
+ * always sizeof(meta->ts) + sizeof(meta->sof) + meta->length bytes large.
+ */
+struct uvc_meta_buf {
+ __u64 ns;
+ __u16 sof;
+ __u8 length;
+ __u8 flags;
+ __u8 buf[];
+} __packed;
+
#endif
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index a692623e0236..cbbb750d87d1 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -67,8 +67,8 @@
/* 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_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)
@@ -102,7 +102,7 @@ enum v4l2_power_line_frequency {
#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_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)
@@ -194,11 +194,11 @@ enum v4l2_colorfx {
/* The MPEG controls are applicable to all codec controls
* and the 'MPEG' part of the define is historical */
-#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
-#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
+#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)
+#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 */
@@ -207,26 +207,26 @@ enum v4l2_mpeg_stream_type {
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)
+#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)
+#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)
+#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,
@@ -234,7 +234,7 @@ enum v4l2_mpeg_audio_encoding {
V4L2_MPEG_AUDIO_ENCODING_AAC = 3,
V4L2_MPEG_AUDIO_ENCODING_AC3 = 4,
};
-#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102)
+#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,
@@ -251,7 +251,7 @@ enum v4l2_mpeg_audio_l1_bitrate {
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)
+#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,
@@ -268,7 +268,7 @@ enum v4l2_mpeg_audio_l2_bitrate {
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)
+#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,
@@ -285,32 +285,32 @@ enum v4l2_mpeg_audio_l3_bitrate {
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)
+#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)
+#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)
+#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)
+#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_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 {
@@ -346,33 +346,33 @@ enum v4l2_mpeg_audio_dec_playback {
#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)
+#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)
+#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)
+#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_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_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)
@@ -590,14 +590,14 @@ enum v4l2_vp8_golden_frame_sel {
#define V4L2_CID_MPEG_VIDEO_VPX_PROFILE (V4L2_CID_MPEG_BASE+511)
/* 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)
+#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)
+#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,
@@ -605,18 +605,18 @@ enum v4l2_mpeg_cx2341x_video_luma_spatial_filter_type {
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)
+#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)
+#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)
+#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,
@@ -624,11 +624,11 @@ enum v4l2_mpeg_cx2341x_video_median_filter_type {
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_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)
+#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)
@@ -660,8 +660,8 @@ enum v4l2_mpeg_mfc51_video_force_frame_type {
/* 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_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 {
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index 1c095b5a99c5..982718965180 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -107,14 +107,14 @@ enum v4l2_field {
transmitted first */
};
#define V4L2_FIELD_HAS_TOP(field) \
- ((field) == V4L2_FIELD_TOP ||\
+ ((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_BOTTOM ||\
(field) == V4L2_FIELD_INTERLACED ||\
(field) == V4L2_FIELD_INTERLACED_TB ||\
(field) == V4L2_FIELD_INTERLACED_BT ||\
@@ -467,12 +467,12 @@ struct v4l2_capability {
* V I D E O I M A G E F O R M A T
*/
struct v4l2_pix_format {
- __u32 width;
+ __u32 width;
__u32 height;
__u32 pixelformat;
__u32 field; /* enum v4l2_field */
- __u32 bytesperline; /* for padding, zero if unused */
- __u32 sizeimage;
+ __u32 bytesperline; /* for padding, zero if unused */
+ __u32 sizeimage;
__u32 colorspace; /* enum v4l2_colorspace */
__u32 priv; /* private data, depends on pixelformat */
__u32 flags; /* format flags (V4L2_PIX_FMT_FLAG_*) */
@@ -669,6 +669,12 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') /* Mediatek compressed block mode */
#define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */
+/* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */
+#define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */
+#define V4L2_PIX_FMT_IPU3_SGBRG10 v4l2_fourcc('i', 'p', '3', 'g') /* IPU3 packed 10-bit GBRG bayer */
+#define V4L2_PIX_FMT_IPU3_SGRBG10 v4l2_fourcc('i', 'p', '3', 'G') /* IPU3 packed 10-bit GRBG bayer */
+#define V4L2_PIX_FMT_IPU3_SRGGB10 v4l2_fourcc('i', 'p', '3', 'r') /* IPU3 packed 10-bit RGGB bayer */
+
/* SDR formats - used only for Software Defined Radio devices */
#define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') /* IQ u8 */
#define V4L2_SDR_FMT_CU16LE v4l2_fourcc('C', 'U', '1', '6') /* IQ u16le */
@@ -688,6 +694,7 @@ struct v4l2_pix_format {
/* Meta-data formats */
#define V4L2_META_FMT_VSP1_HGO v4l2_fourcc('V', 'S', 'P', 'H') /* R-Car VSP1 1-D Histogram */
#define V4L2_META_FMT_VSP1_HGT v4l2_fourcc('V', 'S', 'P', 'T') /* R-Car VSP1 2-D Histogram */
+#define V4L2_META_FMT_UVC v4l2_fourcc('U', 'V', 'C', 'H') /* UVC Payload Header metadata */
/* priv field value to indicates that subsequent fields are valid. */
#define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe
@@ -1166,7 +1173,7 @@ typedef __u64 v4l2_std_id;
V4L2_STD_NTSC_M_JP |\
V4L2_STD_NTSC_M_KR)
/* Secam macros */
-#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
+#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
V4L2_STD_SECAM_K |\
V4L2_STD_SECAM_K1)
/* All Secam Standards */
@@ -1247,7 +1254,7 @@ struct v4l2_standard {
};
/*
- * D V B T T I M I N G S
+ * D V B T T I M I N G S
*/
/** struct v4l2_bt_timings - BT.656/BT.1120 timing data
@@ -1588,7 +1595,7 @@ struct v4l2_ext_controls {
struct v4l2_ext_control *controls;
};
-#define V4L2_CTRL_ID_MASK (0x0fffffff)
+#define V4L2_CTRL_ID_MASK (0x0fffffff)
#ifndef __KERNEL__
#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
#endif
@@ -1660,11 +1667,11 @@ struct v4l2_querymenu {
/* 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_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
#define V4L2_CTRL_FLAG_HAS_PAYLOAD 0x0100
#define V4L2_CTRL_FLAG_EXECUTE_ON_WRITE 0x0200
@@ -1778,21 +1785,21 @@ struct v4l2_hw_freq_seek {
*/
struct v4l2_rds_data {
- __u8 lsb;
- __u8 msb;
- __u8 block;
+ __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_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
+#define V4L2_RDS_BLOCK_ERROR 0x80
/*
* A U D I O
@@ -2348,8 +2355,8 @@ struct v4l2_create_buffers {
#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_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 */
@@ -2370,8 +2377,8 @@ struct v4l2_create_buffers {
* 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)
+#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct v4l2_dbg_register)
+#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct v4l2_dbg_register)
#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek)
#define VIDIOC_S_DV_TIMINGS _IOWR('V', 87, struct v4l2_dv_timings)
diff --git a/include/uapi/rdma/rdma_netlink.h b/include/uapi/rdma/rdma_netlink.h
index 17e59bec169e..4c77e2a7b07e 100644
--- a/include/uapi/rdma/rdma_netlink.h
+++ b/include/uapi/rdma/rdma_netlink.h
@@ -227,16 +227,14 @@ enum rdma_nldev_command {
RDMA_NLDEV_CMD_UNSPEC,
RDMA_NLDEV_CMD_GET, /* can dump */
- RDMA_NLDEV_CMD_SET,
- RDMA_NLDEV_CMD_NEW,
- RDMA_NLDEV_CMD_DEL,
- RDMA_NLDEV_CMD_PORT_GET, /* can dump */
- RDMA_NLDEV_CMD_PORT_SET,
- RDMA_NLDEV_CMD_PORT_NEW,
- RDMA_NLDEV_CMD_PORT_DEL,
+ /* 2 - 4 are free to use */
- RDMA_NLDEV_CMD_RES_GET, /* can dump */
+ RDMA_NLDEV_CMD_PORT_GET = 5, /* can dump */
+
+ /* 6 - 8 are free to use */
+
+ RDMA_NLDEV_CMD_RES_GET = 9, /* can dump */
RDMA_NLDEV_CMD_RES_QP_GET, /* can dump */
diff --git a/include/video/udlfb.h b/include/video/udlfb.h
index 1252a7a89bc0..0cabe6b09095 100644
--- a/include/video/udlfb.h
+++ b/include/video/udlfb.h
@@ -19,7 +19,7 @@ struct dloarea {
struct urb_node {
struct list_head entry;
- struct dlfb_data *dev;
+ struct dlfb_data *dlfb;
struct delayed_work release_urb_work;
struct urb *urb;
};
@@ -35,7 +35,6 @@ struct urb_list {
struct dlfb_data {
struct usb_device *udev;
- struct device *gdev; /* &udev->dev */
struct fb_info *info;
struct urb_list urbs;
struct kref kref;
diff --git a/init/Kconfig b/init/Kconfig
index a9a2e2c86671..e37f4b2a6445 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1412,6 +1412,12 @@ config USERFAULTFD
Enable the userfaultfd() system call that allows to intercept and
handle page faults in userland.
+config ARCH_HAS_MEMBARRIER_CALLBACKS
+ bool
+
+config ARCH_HAS_MEMBARRIER_SYNC_CORE
+ bool
+
config EMBEDDED
bool "Embedded system"
option allnoconfig_y
@@ -1915,3 +1921,6 @@ config ASN1
functions to call on what tags.
source "kernel/Kconfig.locks"
+
+config ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
+ bool
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 690ae6665500..360e564ae7d1 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -596,7 +596,7 @@ static void wq_add(struct mqueue_inode_info *info, int sr,
ewp->task = current;
list_for_each_entry(walk, &info->e_wait_q[sr].list, list) {
- if (walk->task->static_prio <= current->static_prio) {
+ if (walk->task->prio <= current->prio) {
list_add_tail(&ewp->list, &walk->list);
return;
}
diff --git a/ipc/msg.c b/ipc/msg.c
index 1bbc029d2b17..0dcc6699dc53 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -476,9 +476,9 @@ static int msgctl_info(struct ipc_namespace *ns, int msqid,
static int msgctl_stat(struct ipc_namespace *ns, int msqid,
int cmd, struct msqid64_ds *p)
{
- int err;
struct msg_queue *msq;
- int success_return;
+ int id = 0;
+ int err;
memset(p, 0, sizeof(*p));
@@ -489,14 +489,13 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
err = PTR_ERR(msq);
goto out_unlock;
}
- success_return = msq->q_perm.id;
+ id = msq->q_perm.id;
} else {
msq = msq_obtain_object_check(ns, msqid);
if (IS_ERR(msq)) {
err = PTR_ERR(msq);
goto out_unlock;
}
- success_return = 0;
}
err = -EACCES;
@@ -507,6 +506,14 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
if (err)
goto out_unlock;
+ ipc_lock_object(&msq->q_perm);
+
+ if (!ipc_valid_object(&msq->q_perm)) {
+ ipc_unlock_object(&msq->q_perm);
+ err = -EIDRM;
+ goto out_unlock;
+ }
+
kernel_to_ipc64_perm(&msq->q_perm, &p->msg_perm);
p->msg_stime = msq->q_stime;
p->msg_rtime = msq->q_rtime;
@@ -516,9 +523,10 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
p->msg_qbytes = msq->q_qbytes;
p->msg_lspid = msq->q_lspid;
p->msg_lrpid = msq->q_lrpid;
- rcu_read_unlock();
- return success_return;
+ ipc_unlock_object(&msq->q_perm);
+ rcu_read_unlock();
+ return id;
out_unlock:
rcu_read_unlock();
diff --git a/ipc/sem.c b/ipc/sem.c
index 87bd38f38dc3..a4af04979fd2 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -1213,10 +1213,20 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
if (err)
goto out_unlock;
+ ipc_lock_object(&sma->sem_perm);
+
+ if (!ipc_valid_object(&sma->sem_perm)) {
+ ipc_unlock_object(&sma->sem_perm);
+ err = -EIDRM;
+ goto out_unlock;
+ }
+
kernel_to_ipc64_perm(&sma->sem_perm, &semid64->sem_perm);
semid64->sem_otime = get_semotime(sma);
semid64->sem_ctime = sma->sem_ctime;
semid64->sem_nsems = sma->sem_nsems;
+
+ ipc_unlock_object(&sma->sem_perm);
rcu_read_unlock();
return id;
diff --git a/ipc/shm.c b/ipc/shm.c
index 7acda23430aa..4643865e9171 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -909,9 +909,11 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
int cmd, struct shmid64_ds *tbuf)
{
struct shmid_kernel *shp;
- int result;
+ int id = 0;
int err;
+ memset(tbuf, 0, sizeof(*tbuf));
+
rcu_read_lock();
if (cmd == SHM_STAT) {
shp = shm_obtain_object(ns, shmid);
@@ -919,14 +921,13 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
err = PTR_ERR(shp);
goto out_unlock;
}
- result = shp->shm_perm.id;
+ id = shp->shm_perm.id;
} else {
shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
goto out_unlock;
}
- result = 0;
}
err = -EACCES;
@@ -937,7 +938,14 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
if (err)
goto out_unlock;
- memset(tbuf, 0, sizeof(*tbuf));
+ ipc_lock_object(&shp->shm_perm);
+
+ if (!ipc_valid_object(&shp->shm_perm)) {
+ ipc_unlock_object(&shp->shm_perm);
+ err = -EIDRM;
+ goto out_unlock;
+ }
+
kernel_to_ipc64_perm(&shp->shm_perm, &tbuf->shm_perm);
tbuf->shm_segsz = shp->shm_segsz;
tbuf->shm_atime = shp->shm_atim;
@@ -946,8 +954,10 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
tbuf->shm_cpid = shp->shm_cprid;
tbuf->shm_lpid = shp->shm_lprid;
tbuf->shm_nattch = shp->shm_nattch;
+
+ ipc_unlock_object(&shp->shm_perm);
rcu_read_unlock();
- return result;
+ return id;
out_unlock:
rcu_read_unlock();
diff --git a/ipc/util.c b/ipc/util.c
index ff045fec8d83..4ed5a17dd06f 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -23,9 +23,12 @@
* tree.
* - perform initial checks (capabilities, auditing and permission,
* etc).
- * - perform read-only operations, such as STAT, INFO commands.
+ * - perform read-only operations, such as INFO command, that
+ * do not demand atomicity
* acquire the ipc lock (kern_ipc_perm.lock) through
* ipc_lock_object()
+ * - perform read-only operations that demand atomicity,
+ * such as STAT command.
* - perform data updates, such as SET, RMID commands and
* mechanism-specific operations (semop/semtimedop,
* msgsnd/msgrcv, shmat/shmdt).
diff --git a/kernel/async.c b/kernel/async.c
index 2cbd3dd5940d..a893d6170944 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -84,20 +84,24 @@ static atomic_t entry_count;
static async_cookie_t lowest_in_progress(struct async_domain *domain)
{
- struct list_head *pending;
+ struct async_entry *first = NULL;
async_cookie_t ret = ASYNC_COOKIE_MAX;
unsigned long flags;
spin_lock_irqsave(&async_lock, flags);
- if (domain)
- pending = &domain->pending;
- else
- pending = &async_global_pending;
+ if (domain) {
+ if (!list_empty(&domain->pending))
+ first = list_first_entry(&domain->pending,
+ struct async_entry, domain_list);
+ } else {
+ if (!list_empty(&async_global_pending))
+ first = list_first_entry(&async_global_pending,
+ struct async_entry, global_list);
+ }
- if (!list_empty(pending))
- ret = list_first_entry(pending, struct async_entry,
- domain_list)->cookie;
+ if (first)
+ ret = first->cookie;
spin_unlock_irqrestore(&async_lock, flags);
return ret;
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 5f35f93dcab2..29ca9208dcfa 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1576,25 +1576,41 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
__u32 __user *prog_ids, u32 cnt)
{
struct bpf_prog **prog;
- u32 i = 0, id;
-
+ unsigned long err = 0;
+ u32 i = 0, *ids;
+ bool nospc;
+
+ /* users of this function are doing:
+ * cnt = bpf_prog_array_length();
+ * if (cnt > 0)
+ * bpf_prog_array_copy_to_user(..., cnt);
+ * so below kcalloc doesn't need extra cnt > 0 check, but
+ * bpf_prog_array_length() releases rcu lock and
+ * prog array could have been swapped with empty or larger array,
+ * so always copy 'cnt' prog_ids to the user.
+ * In a rare race the user will see zero prog_ids
+ */
+ ids = kcalloc(cnt, sizeof(u32), GFP_USER);
+ if (!ids)
+ return -ENOMEM;
rcu_read_lock();
prog = rcu_dereference(progs)->progs;
for (; *prog; prog++) {
if (*prog == &dummy_bpf_prog.prog)
continue;
- id = (*prog)->aux->id;
- if (copy_to_user(prog_ids + i, &id, sizeof(id))) {
- rcu_read_unlock();
- return -EFAULT;
- }
+ ids[i] = (*prog)->aux->id;
if (++i == cnt) {
prog++;
break;
}
}
+ nospc = !!(*prog);
rcu_read_unlock();
- if (*prog)
+ err = copy_to_user(prog_ids, ids, cnt * sizeof(u32));
+ kfree(ids);
+ if (err)
+ return -EFAULT;
+ if (nospc)
return -ENOSPC;
return 0;
}
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index f7efa7b4d825..b42037e6e81d 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1254,9 +1254,9 @@ done:
return retval;
}
-int current_cpuset_is_being_rebound(void)
+bool current_cpuset_is_being_rebound(void)
{
- int ret;
+ bool ret;
rcu_read_lock();
ret = task_cs(current) == cpuset_being_rebound;
diff --git a/kernel/compat.c b/kernel/compat.c
index d1cee656a7ed..3247fe761f60 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -355,7 +355,7 @@ COMPAT_SYSCALL_DEFINE3(sched_getaffinity, compat_pid_t, pid, unsigned int, len,
ret = sched_getaffinity(pid, mask);
if (ret == 0) {
- size_t retlen = min_t(size_t, len, cpumask_size());
+ unsigned int retlen = min(len, cpumask_size());
if (compat_put_bitmap(user_mask_ptr, cpumask_bits(mask), retlen * 8))
ret = -EFAULT;
diff --git a/kernel/configs/tiny.config b/kernel/configs/tiny.config
index 7fa0c4ae6394..9bfdffc100da 100644
--- a/kernel/configs/tiny.config
+++ b/kernel/configs/tiny.config
@@ -10,3 +10,7 @@ CONFIG_OPTIMIZE_INLINING=y
# CONFIG_SLAB is not set
# CONFIG_SLUB is not set
CONFIG_SLOB=y
+CONFIG_CC_STACKPROTECTOR_NONE=y
+# CONFIG_CC_STACKPROTECTOR_REGULAR is not set
+# CONFIG_CC_STACKPROTECTOR_STRONG is not set
+# CONFIG_CC_STACKPROTECTOR_AUTO is not set
diff --git a/kernel/fork.c b/kernel/fork.c
index 5c372c954f3b..be8aa5b98666 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -606,6 +606,11 @@ static void __mmdrop(struct mm_struct *mm)
void mmdrop(struct mm_struct *mm)
{
+ /*
+ * The implicit full barrier implied by atomic_dec_and_test() is
+ * required by the membarrier system call before returning to
+ * user-space, after storing to rq->curr.
+ */
if (unlikely(atomic_dec_and_test(&mm->mm_count)))
__mmdrop(mm);
}
@@ -1587,6 +1592,10 @@ static __latent_entropy struct task_struct *copy_process(
int retval;
struct task_struct *p;
+ /*
+ * Don't allow sharing the root directory with processes in a different
+ * namespace
+ */
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
return ERR_PTR(-EINVAL);
@@ -2062,6 +2071,8 @@ long _do_fork(unsigned long clone_flags,
int __user *child_tidptr,
unsigned long tls)
{
+ struct completion vfork;
+ struct pid *pid;
struct task_struct *p;
int trace = 0;
long nr;
@@ -2087,43 +2098,40 @@ long _do_fork(unsigned long clone_flags,
p = copy_process(clone_flags, stack_start, stack_size,
child_tidptr, NULL, trace, tls, NUMA_NO_NODE);
add_latent_entropy();
+
+ if (IS_ERR(p))
+ return PTR_ERR(p);
+
/*
* Do this prior waking up the new thread - the thread pointer
* might get invalid after that point, if the thread exits quickly.
*/
- if (!IS_ERR(p)) {
- struct completion vfork;
- struct pid *pid;
-
- trace_sched_process_fork(current, p);
+ trace_sched_process_fork(current, p);
- pid = get_task_pid(p, PIDTYPE_PID);
- nr = pid_vnr(pid);
+ pid = get_task_pid(p, PIDTYPE_PID);
+ nr = pid_vnr(pid);
- if (clone_flags & CLONE_PARENT_SETTID)
- put_user(nr, parent_tidptr);
+ if (clone_flags & CLONE_PARENT_SETTID)
+ put_user(nr, parent_tidptr);
- if (clone_flags & CLONE_VFORK) {
- p->vfork_done = &vfork;
- init_completion(&vfork);
- get_task_struct(p);
- }
-
- wake_up_new_task(p);
+ if (clone_flags & CLONE_VFORK) {
+ p->vfork_done = &vfork;
+ init_completion(&vfork);
+ get_task_struct(p);
+ }
- /* forking complete and child started to run, tell ptracer */
- if (unlikely(trace))
- ptrace_event_pid(trace, pid);
+ wake_up_new_task(p);
- if (clone_flags & CLONE_VFORK) {
- if (!wait_for_vfork_done(p, &vfork))
- ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid);
- }
+ /* forking complete and child started to run, tell ptracer */
+ if (unlikely(trace))
+ ptrace_event_pid(trace, pid);
- put_pid(pid);
- } else {
- nr = PTR_ERR(p);
+ if (clone_flags & CLONE_VFORK) {
+ if (!wait_for_vfork_done(p, &vfork))
+ ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid);
}
+
+ put_pid(pid);
return nr;
}
diff --git a/kernel/futex.c b/kernel/futex.c
index 7f719d110908..1f450e092c74 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -862,24 +862,6 @@ static void put_pi_state(struct futex_pi_state *pi_state)
}
}
-/*
- * Look up the task based on what TID userspace gave us.
- * We dont trust it.
- */
-static struct task_struct *futex_find_get_task(pid_t pid)
-{
- struct task_struct *p;
-
- rcu_read_lock();
- p = find_task_by_vpid(pid);
- if (p)
- get_task_struct(p);
-
- rcu_read_unlock();
-
- return p;
-}
-
#ifdef CONFIG_FUTEX_PI
/*
@@ -1183,7 +1165,7 @@ static int attach_to_pi_owner(u32 uval, union futex_key *key,
*/
if (!pid)
return -ESRCH;
- p = futex_find_get_task(pid);
+ p = find_get_task_by_vpid(pid);
if (!p)
return -ESRCH;
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index ef2a47e0eab6..6cdecc6f4c53 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -10,7 +10,6 @@
#include <linux/jiffies.h>
#include <linux/irq.h>
#include <linux/module.h>
-#include <linux/kallsyms.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/timer.h>
diff --git a/kernel/kcov.c b/kernel/kcov.c
index 7594c033d98a..2c16f1ab5e10 100644
--- a/kernel/kcov.c
+++ b/kernel/kcov.c
@@ -358,7 +358,8 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
*/
if (kcov->mode != KCOV_MODE_INIT || !kcov->area)
return -EINVAL;
- if (kcov->t != NULL)
+ t = current;
+ if (kcov->t != NULL || t->kcov != NULL)
return -EBUSY;
if (arg == KCOV_TRACE_PC)
kcov->mode = KCOV_MODE_TRACE_PC;
@@ -370,7 +371,6 @@ static int kcov_ioctl_locked(struct kcov *kcov, unsigned int cmd,
#endif
else
return -EINVAL;
- t = current;
/* Cache in task struct for performance. */
t->kcov_size = kcov->size;
t->kcov_area = kcov->area;
diff --git a/kernel/memremap.c b/kernel/memremap.c
index 403ab9cdb949..4849be5f9b3c 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -188,13 +188,6 @@ static RADIX_TREE(pgmap_radix, GFP_KERNEL);
#define SECTION_MASK ~((1UL << PA_SECTION_SHIFT) - 1)
#define SECTION_SIZE (1UL << PA_SECTION_SHIFT)
-struct page_map {
- struct resource res;
- struct percpu_ref *ref;
- struct dev_pagemap pgmap;
- struct vmem_altmap altmap;
-};
-
static unsigned long order_at(struct resource *res, unsigned long pgoff)
{
unsigned long phys_pgoff = PHYS_PFN(res->start) + pgoff;
@@ -248,34 +241,36 @@ int device_private_entry_fault(struct vm_area_struct *vma,
EXPORT_SYMBOL(device_private_entry_fault);
#endif /* CONFIG_DEVICE_PRIVATE */
-static void pgmap_radix_release(struct resource *res)
+static void pgmap_radix_release(struct resource *res, unsigned long end_pgoff)
{
unsigned long pgoff, order;
mutex_lock(&pgmap_lock);
- foreach_order_pgoff(res, order, pgoff)
+ foreach_order_pgoff(res, order, pgoff) {
+ if (pgoff >= end_pgoff)
+ break;
radix_tree_delete(&pgmap_radix, PHYS_PFN(res->start) + pgoff);
+ }
mutex_unlock(&pgmap_lock);
synchronize_rcu();
}
-static unsigned long pfn_first(struct page_map *page_map)
+static unsigned long pfn_first(struct dev_pagemap *pgmap)
{
- struct dev_pagemap *pgmap = &page_map->pgmap;
- const struct resource *res = &page_map->res;
- struct vmem_altmap *altmap = pgmap->altmap;
+ const struct resource *res = &pgmap->res;
+ struct vmem_altmap *altmap = &pgmap->altmap;
unsigned long pfn;
pfn = res->start >> PAGE_SHIFT;
- if (altmap)
+ if (pgmap->altmap_valid)
pfn += vmem_altmap_offset(altmap);
return pfn;
}
-static unsigned long pfn_end(struct page_map *page_map)
+static unsigned long pfn_end(struct dev_pagemap *pgmap)
{
- const struct resource *res = &page_map->res;
+ const struct resource *res = &pgmap->res;
return (res->start + resource_size(res)) >> PAGE_SHIFT;
}
@@ -283,15 +278,15 @@ static unsigned long pfn_end(struct page_map *page_map)
#define for_each_device_pfn(pfn, map) \
for (pfn = pfn_first(map); pfn < pfn_end(map); pfn++)
-static void devm_memremap_pages_release(struct device *dev, void *data)
+static void devm_memremap_pages_release(void *data)
{
- struct page_map *page_map = data;
- struct resource *res = &page_map->res;
+ struct dev_pagemap *pgmap = data;
+ struct device *dev = pgmap->dev;
+ struct resource *res = &pgmap->res;
resource_size_t align_start, align_size;
- struct dev_pagemap *pgmap = &page_map->pgmap;
unsigned long pfn;
- for_each_device_pfn(pfn, page_map)
+ for_each_device_pfn(pfn, pgmap)
put_page(pfn_to_page(pfn));
if (percpu_ref_tryget_live(pgmap->ref)) {
@@ -301,56 +296,51 @@ static void devm_memremap_pages_release(struct device *dev, void *data)
/* pages are dead and unused, undo the arch mapping */
align_start = res->start & ~(SECTION_SIZE - 1);
- align_size = ALIGN(resource_size(res), SECTION_SIZE);
+ align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
+ - align_start;
mem_hotplug_begin();
- arch_remove_memory(align_start, align_size);
+ arch_remove_memory(align_start, align_size, pgmap->altmap_valid ?
+ &pgmap->altmap : NULL);
mem_hotplug_done();
untrack_pfn(NULL, PHYS_PFN(align_start), align_size);
- pgmap_radix_release(res);
- dev_WARN_ONCE(dev, pgmap->altmap && pgmap->altmap->alloc,
- "%s: failed to free all reserved pages\n", __func__);
-}
-
-/* assumes rcu_read_lock() held at entry */
-struct dev_pagemap *find_dev_pagemap(resource_size_t phys)
-{
- struct page_map *page_map;
-
- WARN_ON_ONCE(!rcu_read_lock_held());
-
- page_map = radix_tree_lookup(&pgmap_radix, PHYS_PFN(phys));
- return page_map ? &page_map->pgmap : NULL;
+ pgmap_radix_release(res, -1);
+ dev_WARN_ONCE(dev, pgmap->altmap.alloc,
+ "%s: failed to free all reserved pages\n", __func__);
}
/**
* devm_memremap_pages - remap and provide memmap backing for the given resource
* @dev: hosting device for @res
- * @res: "host memory" address range
- * @ref: a live per-cpu reference count
- * @altmap: optional descriptor for allocating the memmap from @res
+ * @pgmap: pointer to a struct dev_pgmap
*
* Notes:
- * 1/ @ref must be 'live' on entry and 'dead' before devm_memunmap_pages() time
- * (or devm release event). The expected order of events is that @ref has
+ * 1/ At a minimum the res, ref and type members of @pgmap must be initialized
+ * by the caller before passing it to this function
+ *
+ * 2/ The altmap field may optionally be initialized, in which case altmap_valid
+ * must be set to true
+ *
+ * 3/ pgmap.ref must be 'live' on entry and 'dead' before devm_memunmap_pages()
+ * time (or devm release event). The expected order of events is that ref has
* been through percpu_ref_kill() before devm_memremap_pages_release(). The
* wait for the completion of all references being dropped and
* percpu_ref_exit() must occur after devm_memremap_pages_release().
*
- * 2/ @res is expected to be a host memory range that could feasibly be
+ * 4/ res is expected to be a host memory range that could feasibly be
* treated as a "System RAM" range, i.e. not a device mmio range, but
* this is not enforced.
*/
-void *devm_memremap_pages(struct device *dev, struct resource *res,
- struct percpu_ref *ref, struct vmem_altmap *altmap)
+void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
{
resource_size_t align_start, align_size, align_end;
+ struct vmem_altmap *altmap = pgmap->altmap_valid ?
+ &pgmap->altmap : NULL;
unsigned long pfn, pgoff, order;
pgprot_t pgprot = PAGE_KERNEL;
- struct dev_pagemap *pgmap;
- struct page_map *page_map;
int error, nid, is_ram, i = 0;
+ struct resource *res = &pgmap->res;
align_start = res->start & ~(SECTION_SIZE - 1);
align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
@@ -367,47 +357,18 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
if (is_ram == REGION_INTERSECTS)
return __va(res->start);
- if (!ref)
+ if (!pgmap->ref)
return ERR_PTR(-EINVAL);
- page_map = devres_alloc_node(devm_memremap_pages_release,
- sizeof(*page_map), GFP_KERNEL, dev_to_node(dev));
- if (!page_map)
- return ERR_PTR(-ENOMEM);
- pgmap = &page_map->pgmap;
-
- memcpy(&page_map->res, res, sizeof(*res));
-
pgmap->dev = dev;
- if (altmap) {
- memcpy(&page_map->altmap, altmap, sizeof(*altmap));
- pgmap->altmap = &page_map->altmap;
- }
- pgmap->ref = ref;
- pgmap->res = &page_map->res;
- pgmap->type = MEMORY_DEVICE_HOST;
- pgmap->page_fault = NULL;
- pgmap->page_free = NULL;
- pgmap->data = NULL;
mutex_lock(&pgmap_lock);
error = 0;
align_end = align_start + align_size - 1;
foreach_order_pgoff(res, order, pgoff) {
- struct dev_pagemap *dup;
-
- rcu_read_lock();
- dup = find_dev_pagemap(res->start + PFN_PHYS(pgoff));
- rcu_read_unlock();
- if (dup) {
- dev_err(dev, "%s: %pr collides with mapping for %s\n",
- __func__, res, dev_name(dup->dev));
- error = -EBUSY;
- break;
- }
error = __radix_tree_insert(&pgmap_radix,
- PHYS_PFN(res->start) + pgoff, order, page_map);
+ PHYS_PFN(res->start) + pgoff, order, pgmap);
if (error) {
dev_err(dev, "%s: failed: %d\n", __func__, error);
break;
@@ -427,16 +388,16 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
goto err_pfn_remap;
mem_hotplug_begin();
- error = arch_add_memory(nid, align_start, align_size, false);
+ error = arch_add_memory(nid, align_start, align_size, altmap, false);
if (!error)
move_pfn_range_to_zone(&NODE_DATA(nid)->node_zones[ZONE_DEVICE],
align_start >> PAGE_SHIFT,
- align_size >> PAGE_SHIFT);
+ align_size >> PAGE_SHIFT, altmap);
mem_hotplug_done();
if (error)
goto err_add_memory;
- for_each_device_pfn(pfn, page_map) {
+ for_each_device_pfn(pfn, pgmap) {
struct page *page = pfn_to_page(pfn);
/*
@@ -447,19 +408,21 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
*/
list_del(&page->lru);
page->pgmap = pgmap;
- percpu_ref_get(ref);
+ percpu_ref_get(pgmap->ref);
if (!(++i % 1024))
cond_resched();
}
- devres_add(dev, page_map);
+
+ devm_add_action(dev, devm_memremap_pages_release, pgmap);
+
return __va(res->start);
err_add_memory:
untrack_pfn(NULL, PHYS_PFN(align_start), align_size);
err_pfn_remap:
err_radix:
- pgmap_radix_release(res);
- devres_free(page_map);
+ pgmap_radix_release(res, pgoff);
+ devres_free(pgmap);
return ERR_PTR(error);
}
EXPORT_SYMBOL(devm_memremap_pages);
@@ -475,34 +438,39 @@ void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns)
altmap->alloc -= nr_pfns;
}
-struct vmem_altmap *to_vmem_altmap(unsigned long memmap_start)
+/**
+ * get_dev_pagemap() - take a new live reference on the dev_pagemap for @pfn
+ * @pfn: page frame number to lookup page_map
+ * @pgmap: optional known pgmap that already has a reference
+ *
+ * If @pgmap is non-NULL and covers @pfn it will be returned as-is. If @pgmap
+ * is non-NULL but does not cover @pfn the reference to it will be released.
+ */
+struct dev_pagemap *get_dev_pagemap(unsigned long pfn,
+ struct dev_pagemap *pgmap)
{
- /*
- * 'memmap_start' is the virtual address for the first "struct
- * page" in this range of the vmemmap array. In the case of
- * CONFIG_SPARSEMEM_VMEMMAP a page_to_pfn conversion is simple
- * pointer arithmetic, so we can perform this to_vmem_altmap()
- * conversion without concern for the initialization state of
- * the struct page fields.
- */
- struct page *page = (struct page *) memmap_start;
- struct dev_pagemap *pgmap;
+ resource_size_t phys = PFN_PHYS(pfn);
/*
- * Unconditionally retrieve a dev_pagemap associated with the
- * given physical address, this is only for use in the
- * arch_{add|remove}_memory() for setting up and tearing down
- * the memmap.
+ * In the cached case we're already holding a live reference.
*/
+ if (pgmap) {
+ if (phys >= pgmap->res.start && phys <= pgmap->res.end)
+ return pgmap;
+ put_dev_pagemap(pgmap);
+ }
+
+ /* fall back to slow path lookup */
rcu_read_lock();
- pgmap = find_dev_pagemap(__pfn_to_phys(page_to_pfn(page)));
+ pgmap = radix_tree_lookup(&pgmap_radix, PHYS_PFN(phys));
+ if (pgmap && !percpu_ref_tryget_live(pgmap->ref))
+ pgmap = NULL;
rcu_read_unlock();
- return pgmap ? pgmap->altmap : NULL;
+ return pgmap;
}
#endif /* CONFIG_ZONE_DEVICE */
-
#if IS_ENABLED(CONFIG_DEVICE_PRIVATE) || IS_ENABLED(CONFIG_DEVICE_PUBLIC)
void put_zone_device_private_or_public_page(struct page *page)
{
diff --git a/kernel/module.c b/kernel/module.c
index ccdf24c4949e..ad2d420024f6 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -3804,6 +3804,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
module_disable_nx(mod);
ddebug_cleanup:
+ ftrace_release_mod(mod);
dynamic_debug_remove(mod, info->debug);
synchronize_sched();
kfree(mod->args);
@@ -3823,12 +3824,6 @@ static int load_module(struct load_info *info, const char __user *uargs,
synchronize_sched();
mutex_unlock(&module_mutex);
free_module:
- /*
- * Ftrace needs to clean up what it initialized.
- * This does nothing if ftrace_module_init() wasn't called,
- * but it must be called outside of module_mutex.
- */
- ftrace_release_mod(mod);
/* Free lock-classes; relies on the preceding sync_rcu() */
lockdep_free_key_range(mod->core_layout.base, mod->core_layout.size);
diff --git a/kernel/pid.c b/kernel/pid.c
index 5d30c87e3c42..ed6c343fe50d 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -343,6 +343,19 @@ struct task_struct *find_task_by_vpid(pid_t vnr)
return find_task_by_pid_ns(vnr, task_active_pid_ns(current));
}
+struct task_struct *find_get_task_by_vpid(pid_t nr)
+{
+ struct task_struct *task;
+
+ rcu_read_lock();
+ task = find_task_by_vpid(nr);
+ if (task)
+ get_task_struct(task);
+ rcu_read_unlock();
+
+ return task;
+}
+
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{
struct pid *pid;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 5e1d713c8e61..21fec73d45d4 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -1103,21 +1103,6 @@ int ptrace_request(struct task_struct *child, long request,
return ret;
}
-static struct task_struct *ptrace_get_task_struct(pid_t pid)
-{
- struct task_struct *child;
-
- rcu_read_lock();
- child = find_task_by_vpid(pid);
- if (child)
- get_task_struct(child);
- rcu_read_unlock();
-
- if (!child)
- return ERR_PTR(-ESRCH);
- return child;
-}
-
#ifndef arch_ptrace_attach
#define arch_ptrace_attach(child) do { } while (0)
#endif
@@ -1135,9 +1120,9 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
goto out;
}
- child = ptrace_get_task_struct(pid);
- if (IS_ERR(child)) {
- ret = PTR_ERR(child);
+ child = find_get_task_by_vpid(pid);
+ if (!child) {
+ ret = -ESRCH;
goto out;
}
@@ -1281,9 +1266,9 @@ COMPAT_SYSCALL_DEFINE4(ptrace, compat_long_t, request, compat_long_t, pid,
goto out;
}
- child = ptrace_get_task_struct(pid);
- if (IS_ERR(child)) {
- ret = PTR_ERR(child);
+ child = find_get_task_by_vpid(pid);
+ if (!child) {
+ ret = -ESRCH;
goto out;
}
diff --git a/kernel/relay.c b/kernel/relay.c
index 41280033a4c5..f7f40a6e6352 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -611,7 +611,6 @@ free_bufs:
kref_put(&chan->kref, relay_destroy_channel);
mutex_unlock(&relay_channels_mutex);
- kfree(chan);
return NULL;
}
EXPORT_SYMBOL_GPL(relay_open);
diff --git a/kernel/resource.c b/kernel/resource.c
index 54ba6de3757c..e270b5048988 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -1022,6 +1022,7 @@ static void __init __reserve_region_with_split(struct resource *root,
struct resource *conflict;
struct resource *res = alloc_resource(GFP_ATOMIC);
struct resource *next_res = NULL;
+ int type = resource_type(root);
if (!res)
return;
@@ -1029,7 +1030,7 @@ static void __init __reserve_region_with_split(struct resource *root,
res->name = name;
res->start = start;
res->end = end;
- res->flags = IORESOURCE_BUSY;
+ res->flags = type | IORESOURCE_BUSY;
res->desc = IORES_DESC_NONE;
while (1) {
@@ -1064,7 +1065,7 @@ static void __init __reserve_region_with_split(struct resource *root,
next_res->name = name;
next_res->start = conflict->end + 1;
next_res->end = end;
- next_res->flags = IORESOURCE_BUSY;
+ next_res->flags = type | IORESOURCE_BUSY;
next_res->desc = IORES_DESC_NONE;
}
} else {
@@ -1478,7 +1479,7 @@ void __devm_release_region(struct device *dev, struct resource *parent,
EXPORT_SYMBOL(__devm_release_region);
/*
- * Called from init/main.c to reserve IO ports.
+ * Reserve I/O ports or memory based on "reserve=" kernel parameter.
*/
#define MAXRESERVE 4
static int __init reserve_setup(char *str)
@@ -1489,26 +1490,38 @@ static int __init reserve_setup(char *str)
for (;;) {
unsigned int io_start, io_num;
int x = reserved;
+ struct resource *parent;
- if (get_option (&str, &io_start) != 2)
+ if (get_option(&str, &io_start) != 2)
break;
- if (get_option (&str, &io_num) == 0)
+ if (get_option(&str, &io_num) == 0)
break;
if (x < MAXRESERVE) {
struct resource *res = reserve + x;
+
+ /*
+ * If the region starts below 0x10000, we assume it's
+ * I/O port space; otherwise assume it's memory.
+ */
+ if (io_start < 0x10000) {
+ res->flags = IORESOURCE_IO;
+ parent = &ioport_resource;
+ } else {
+ res->flags = IORESOURCE_MEM;
+ parent = &iomem_resource;
+ }
res->name = "reserved";
res->start = io_start;
res->end = io_start + io_num - 1;
- res->flags = IORESOURCE_BUSY;
+ res->flags |= IORESOURCE_BUSY;
res->desc = IORES_DESC_NONE;
res->child = NULL;
- if (request_resource(res->start >= 0x10000 ? &iomem_resource : &ioport_resource, res) == 0)
+ if (request_resource(parent, res) == 0)
reserved = x+1;
}
}
return 1;
}
-
__setup("reserve=", reserve_setup);
/*
@@ -1563,17 +1576,17 @@ static int strict_iomem_checks;
/*
* check if an address is reserved in the iomem resource tree
- * returns 1 if reserved, 0 if not reserved.
+ * returns true if reserved, false if not reserved.
*/
-int iomem_is_exclusive(u64 addr)
+bool iomem_is_exclusive(u64 addr)
{
struct resource *p = &iomem_resource;
- int err = 0;
+ bool err = false;
loff_t l;
int size = PAGE_SIZE;
if (!strict_iomem_checks)
- return 0;
+ return false;
addr = addr & PAGE_MASK;
@@ -1596,7 +1609,7 @@ int iomem_is_exclusive(u64 addr)
continue;
if (IS_ENABLED(CONFIG_IO_STRICT_DEVMEM)
|| p->flags & IORESOURCE_EXCLUSIVE) {
- err = 1;
+ err = true;
break;
}
}
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 3da7a2444a91..bf724c1952ea 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1630,16 +1630,16 @@ ttwu_stat(struct task_struct *p, int cpu, int wake_flags)
#ifdef CONFIG_SMP
if (cpu == rq->cpu) {
- schedstat_inc(rq->ttwu_local);
- schedstat_inc(p->se.statistics.nr_wakeups_local);
+ __schedstat_inc(rq->ttwu_local);
+ __schedstat_inc(p->se.statistics.nr_wakeups_local);
} else {
struct sched_domain *sd;
- schedstat_inc(p->se.statistics.nr_wakeups_remote);
+ __schedstat_inc(p->se.statistics.nr_wakeups_remote);
rcu_read_lock();
for_each_domain(rq->cpu, sd) {
if (cpumask_test_cpu(cpu, sched_domain_span(sd))) {
- schedstat_inc(sd->ttwu_wake_remote);
+ __schedstat_inc(sd->ttwu_wake_remote);
break;
}
}
@@ -1647,14 +1647,14 @@ ttwu_stat(struct task_struct *p, int cpu, int wake_flags)
}
if (wake_flags & WF_MIGRATED)
- schedstat_inc(p->se.statistics.nr_wakeups_migrate);
+ __schedstat_inc(p->se.statistics.nr_wakeups_migrate);
#endif /* CONFIG_SMP */
- schedstat_inc(rq->ttwu_count);
- schedstat_inc(p->se.statistics.nr_wakeups);
+ __schedstat_inc(rq->ttwu_count);
+ __schedstat_inc(p->se.statistics.nr_wakeups);
if (wake_flags & WF_SYNC)
- schedstat_inc(p->se.statistics.nr_wakeups_sync);
+ __schedstat_inc(p->se.statistics.nr_wakeups_sync);
}
static inline void ttwu_activate(struct rq *rq, struct task_struct *p, int en_flags)
@@ -2461,6 +2461,7 @@ void wake_up_new_task(struct task_struct *p)
* Use __set_task_cpu() to avoid calling sched_class::migrate_task_rq,
* as we're not fully set-up yet.
*/
+ p->recent_used_cpu = task_cpu(p);
__set_task_cpu(p, select_task_rq(p, task_cpu(p), SD_BALANCE_FORK, 0));
#endif
rq = __task_rq_lock(p, &rf);
@@ -2698,23 +2699,27 @@ static struct rq *finish_task_switch(struct task_struct *prev)
prev_state = prev->state;
vtime_task_switch(prev);
perf_event_task_sched_in(prev, current);
- /*
- * The membarrier system call requires a full memory barrier
- * after storing to rq->curr, before going back to user-space.
- *
- * TODO: This smp_mb__after_unlock_lock can go away if PPC end
- * up adding a full barrier to switch_mm(), or we should figure
- * out if a smp_mb__after_unlock_lock is really the proper API
- * to use.
- */
- smp_mb__after_unlock_lock();
finish_task(prev);
finish_lock_switch(rq);
finish_arch_post_lock_switch();
fire_sched_in_preempt_notifiers(current);
- if (mm)
+ /*
+ * When switching through a kernel thread, the loop in
+ * membarrier_{private,global}_expedited() may have observed that
+ * kernel thread and not issued an IPI. It is therefore possible to
+ * schedule between user->kernel->user threads without passing though
+ * switch_mm(). Membarrier requires a barrier after storing to
+ * rq->curr, before returning to userspace, so provide them here:
+ *
+ * - a full memory barrier for {PRIVATE,GLOBAL}_EXPEDITED, implicitly
+ * provided by mmdrop(),
+ * - a sync_core for SYNC_CORE.
+ */
+ if (mm) {
+ membarrier_mm_sync_core_before_usermode(mm);
mmdrop(mm);
+ }
if (unlikely(prev_state == TASK_DEAD)) {
if (prev->sched_class->task_dead)
prev->sched_class->task_dead(prev);
@@ -2818,6 +2823,13 @@ context_switch(struct rq *rq, struct task_struct *prev,
*/
arch_start_context_switch(prev);
+ /*
+ * If mm is non-NULL, we pass through switch_mm(). If mm is
+ * NULL, we will pass through mmdrop() in finish_task_switch().
+ * Both of these contain the full memory barrier required by
+ * membarrier after storing to rq->curr, before returning to
+ * user-space.
+ */
if (!mm) {
next->active_mm = oldmm;
mmgrab(oldmm);
@@ -3354,6 +3366,9 @@ static void __sched notrace __schedule(bool preempt)
* Make sure that signal_pending_state()->signal_pending() below
* can't be reordered with __set_current_state(TASK_INTERRUPTIBLE)
* done by the caller to avoid the race with signal_wake_up().
+ *
+ * The membarrier system call requires a full memory barrier
+ * after coming from user-space, before storing to rq->curr.
*/
rq_lock(rq, &rf);
smp_mb__after_spinlock();
@@ -3401,17 +3416,16 @@ static void __sched notrace __schedule(bool preempt)
/*
* The membarrier system call requires each architecture
* to have a full memory barrier after updating
- * rq->curr, before returning to user-space. For TSO
- * (e.g. x86), the architecture must provide its own
- * barrier in switch_mm(). For weakly ordered machines
- * for which spin_unlock() acts as a full memory
- * barrier, finish_lock_switch() in common code takes
- * care of this barrier. For weakly ordered machines for
- * which spin_unlock() acts as a RELEASE barrier (only
- * arm64 and PowerPC), arm64 has a full barrier in
- * switch_to(), and PowerPC has
- * smp_mb__after_unlock_lock() before
- * finish_lock_switch().
+ * rq->curr, before returning to user-space.
+ *
+ * Here are the schemes providing that barrier on the
+ * various architectures:
+ * - mm ? switch_mm() : mmdrop() for x86, s390, sparc, PowerPC.
+ * switch_mm() rely on membarrier_arch_switch_mm() on PowerPC.
+ * - finish_lock_switch() for weakly-ordered
+ * architectures where spin_unlock is a full barrier,
+ * - switch_to() for arm64 (weakly-ordered, spin_unlock
+ * is a RELEASE barrier),
*/
++*switch_count;
@@ -4853,7 +4867,7 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
ret = sched_getaffinity(pid, mask);
if (ret == 0) {
- size_t retlen = min_t(size_t, len, cpumask_size());
+ unsigned int retlen = min(len, cpumask_size());
if (copy_to_user(user_mask_ptr, mask, retlen))
ret = -EFAULT;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 7b6535987500..5eb3ffc9be84 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -871,7 +871,7 @@ update_stats_wait_start(struct cfs_rq *cfs_rq, struct sched_entity *se)
likely(wait_start > prev_wait_start))
wait_start -= prev_wait_start;
- schedstat_set(se->statistics.wait_start, wait_start);
+ __schedstat_set(se->statistics.wait_start, wait_start);
}
static inline void
@@ -893,17 +893,17 @@ update_stats_wait_end(struct cfs_rq *cfs_rq, struct sched_entity *se)
* time stamp can be adjusted to accumulate wait time
* prior to migration.
*/
- schedstat_set(se->statistics.wait_start, delta);
+ __schedstat_set(se->statistics.wait_start, delta);
return;
}
trace_sched_stat_wait(p, delta);
}
- schedstat_set(se->statistics.wait_max,
+ __schedstat_set(se->statistics.wait_max,
max(schedstat_val(se->statistics.wait_max), delta));
- schedstat_inc(se->statistics.wait_count);
- schedstat_add(se->statistics.wait_sum, delta);
- schedstat_set(se->statistics.wait_start, 0);
+ __schedstat_inc(se->statistics.wait_count);
+ __schedstat_add(se->statistics.wait_sum, delta);
+ __schedstat_set(se->statistics.wait_start, 0);
}
static inline void
@@ -928,10 +928,10 @@ update_stats_enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
delta = 0;
if (unlikely(delta > schedstat_val(se->statistics.sleep_max)))
- schedstat_set(se->statistics.sleep_max, delta);
+ __schedstat_set(se->statistics.sleep_max, delta);
- schedstat_set(se->statistics.sleep_start, 0);
- schedstat_add(se->statistics.sum_sleep_runtime, delta);
+ __schedstat_set(se->statistics.sleep_start, 0);
+ __schedstat_add(se->statistics.sum_sleep_runtime, delta);
if (tsk) {
account_scheduler_latency(tsk, delta >> 10, 1);
@@ -945,15 +945,15 @@ update_stats_enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
delta = 0;
if (unlikely(delta > schedstat_val(se->statistics.block_max)))
- schedstat_set(se->statistics.block_max, delta);
+ __schedstat_set(se->statistics.block_max, delta);
- schedstat_set(se->statistics.block_start, 0);
- schedstat_add(se->statistics.sum_sleep_runtime, delta);
+ __schedstat_set(se->statistics.block_start, 0);
+ __schedstat_add(se->statistics.sum_sleep_runtime, delta);
if (tsk) {
if (tsk->in_iowait) {
- schedstat_add(se->statistics.iowait_sum, delta);
- schedstat_inc(se->statistics.iowait_count);
+ __schedstat_add(se->statistics.iowait_sum, delta);
+ __schedstat_inc(se->statistics.iowait_count);
trace_sched_stat_iowait(tsk, delta);
}
@@ -1012,10 +1012,10 @@ update_stats_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
struct task_struct *tsk = task_of(se);
if (tsk->state & TASK_INTERRUPTIBLE)
- schedstat_set(se->statistics.sleep_start,
+ __schedstat_set(se->statistics.sleep_start,
rq_clock(rq_of(cfs_rq)));
if (tsk->state & TASK_UNINTERRUPTIBLE)
- schedstat_set(se->statistics.block_start,
+ __schedstat_set(se->statistics.block_start,
rq_clock(rq_of(cfs_rq)));
}
}
@@ -5692,27 +5692,31 @@ static int wake_wide(struct task_struct *p)
* scheduling latency of the CPUs. This seems to work
* for the overloaded case.
*/
-
-static bool
-wake_affine_idle(struct sched_domain *sd, struct task_struct *p,
- int this_cpu, int prev_cpu, int sync)
+static int
+wake_affine_idle(int this_cpu, int prev_cpu, int sync)
{
/*
* If this_cpu is idle, it implies the wakeup is from interrupt
* context. Only allow the move if cache is shared. Otherwise an
* interrupt intensive workload could force all tasks onto one
* node depending on the IO topology or IRQ affinity settings.
+ *
+ * If the prev_cpu is idle and cache affine then avoid a migration.
+ * There is no guarantee that the cache hot data from an interrupt
+ * is more important than cache hot data on the prev_cpu and from
+ * a cpufreq perspective, it's better to have higher utilisation
+ * on one CPU.
*/
if (idle_cpu(this_cpu) && cpus_share_cache(this_cpu, prev_cpu))
- return true;
+ return idle_cpu(prev_cpu) ? prev_cpu : this_cpu;
if (sync && cpu_rq(this_cpu)->nr_running == 1)
- return true;
+ return this_cpu;
- return false;
+ return nr_cpumask_bits;
}
-static bool
+static int
wake_affine_weight(struct sched_domain *sd, struct task_struct *p,
int this_cpu, int prev_cpu, int sync)
{
@@ -5726,7 +5730,7 @@ wake_affine_weight(struct sched_domain *sd, struct task_struct *p,
unsigned long current_load = task_h_load(current);
if (current_load > this_eff_load)
- return true;
+ return this_cpu;
this_eff_load -= current_load;
}
@@ -5743,28 +5747,28 @@ wake_affine_weight(struct sched_domain *sd, struct task_struct *p,
prev_eff_load *= 100 + (sd->imbalance_pct - 100) / 2;
prev_eff_load *= capacity_of(this_cpu);
- return this_eff_load <= prev_eff_load;
+ return this_eff_load <= prev_eff_load ? this_cpu : nr_cpumask_bits;
}
static int wake_affine(struct sched_domain *sd, struct task_struct *p,
int prev_cpu, int sync)
{
int this_cpu = smp_processor_id();
- bool affine = false;
+ int target = nr_cpumask_bits;
- if (sched_feat(WA_IDLE) && !affine)
- affine = wake_affine_idle(sd, p, this_cpu, prev_cpu, sync);
+ if (sched_feat(WA_IDLE))
+ target = wake_affine_idle(this_cpu, prev_cpu, sync);
- if (sched_feat(WA_WEIGHT) && !affine)
- affine = wake_affine_weight(sd, p, this_cpu, prev_cpu, sync);
+ if (sched_feat(WA_WEIGHT) && target == nr_cpumask_bits)
+ target = wake_affine_weight(sd, p, this_cpu, prev_cpu, sync);
schedstat_inc(p->se.statistics.nr_wakeups_affine_attempts);
- if (affine) {
- schedstat_inc(sd->ttwu_move_affine);
- schedstat_inc(p->se.statistics.nr_wakeups_affine);
- }
+ if (target == nr_cpumask_bits)
+ return prev_cpu;
- return affine;
+ schedstat_inc(sd->ttwu_move_affine);
+ schedstat_inc(p->se.statistics.nr_wakeups_affine);
+ return target;
}
static inline unsigned long task_util(struct task_struct *p);
@@ -6193,7 +6197,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
static int select_idle_sibling(struct task_struct *p, int prev, int target)
{
struct sched_domain *sd;
- int i;
+ int i, recent_used_cpu;
if (idle_cpu(target))
return target;
@@ -6204,6 +6208,21 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
if (prev != target && cpus_share_cache(prev, target) && idle_cpu(prev))
return prev;
+ /* Check a recently used CPU as a potential idle candidate */
+ recent_used_cpu = p->recent_used_cpu;
+ if (recent_used_cpu != prev &&
+ recent_used_cpu != target &&
+ cpus_share_cache(recent_used_cpu, target) &&
+ idle_cpu(recent_used_cpu) &&
+ cpumask_test_cpu(p->recent_used_cpu, &p->cpus_allowed)) {
+ /*
+ * Replace recent_used_cpu with prev as it is a potential
+ * candidate for the next wake.
+ */
+ p->recent_used_cpu = prev;
+ return recent_used_cpu;
+ }
+
sd = rcu_dereference(per_cpu(sd_llc, target));
if (!sd)
return target;
@@ -6357,8 +6376,7 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f
if (cpu == prev_cpu)
goto pick_cpu;
- if (wake_affine(affine_sd, p, prev_cpu, sync))
- new_cpu = cpu;
+ new_cpu = wake_affine(affine_sd, p, prev_cpu, sync);
}
if (sd && !(sd_flag & SD_BALANCE_FORK)) {
@@ -6372,9 +6390,12 @@ select_task_rq_fair(struct task_struct *p, int prev_cpu, int sd_flag, int wake_f
if (!sd) {
pick_cpu:
- if (sd_flag & SD_BALANCE_WAKE) /* XXX always ? */
+ if (sd_flag & SD_BALANCE_WAKE) { /* XXX always ? */
new_cpu = select_idle_sibling(p, prev_cpu, new_cpu);
+ if (want_affine)
+ current->recent_used_cpu = cpu;
+ }
} else {
new_cpu = find_idlest_cpu(sd, p, cpu, prev_cpu, sd_flag);
}
diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c
index 9bcbacba82a8..5d0762633639 100644
--- a/kernel/sched/membarrier.c
+++ b/kernel/sched/membarrier.c
@@ -26,24 +26,110 @@
* Bitmask made from a "or" of all commands within enum membarrier_cmd,
* except MEMBARRIER_CMD_QUERY.
*/
+#ifdef CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE
+#define MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK \
+ (MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE \
+ | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE)
+#else
+#define MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK 0
+#endif
+
#define MEMBARRIER_CMD_BITMASK \
- (MEMBARRIER_CMD_SHARED | MEMBARRIER_CMD_PRIVATE_EXPEDITED \
- | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED)
+ (MEMBARRIER_CMD_GLOBAL | MEMBARRIER_CMD_GLOBAL_EXPEDITED \
+ | MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED \
+ | MEMBARRIER_CMD_PRIVATE_EXPEDITED \
+ | MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED \
+ | MEMBARRIER_PRIVATE_EXPEDITED_SYNC_CORE_BITMASK)
static void ipi_mb(void *info)
{
smp_mb(); /* IPIs should be serializing but paranoid. */
}
-static int membarrier_private_expedited(void)
+static int membarrier_global_expedited(void)
{
int cpu;
bool fallback = false;
cpumask_var_t tmpmask;
- if (!(atomic_read(&current->mm->membarrier_state)
- & MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY))
- return -EPERM;
+ if (num_online_cpus() == 1)
+ return 0;
+
+ /*
+ * Matches memory barriers around rq->curr modification in
+ * scheduler.
+ */
+ smp_mb(); /* system call entry is not a mb. */
+
+ /*
+ * Expedited membarrier commands guarantee that they won't
+ * block, hence the GFP_NOWAIT allocation flag and fallback
+ * implementation.
+ */
+ if (!zalloc_cpumask_var(&tmpmask, GFP_NOWAIT)) {
+ /* Fallback for OOM. */
+ fallback = true;
+ }
+
+ cpus_read_lock();
+ for_each_online_cpu(cpu) {
+ struct task_struct *p;
+
+ /*
+ * Skipping the current CPU is OK even through we can be
+ * migrated at any point. The current CPU, at the point
+ * where we read raw_smp_processor_id(), is ensured to
+ * be in program order with respect to the caller
+ * thread. Therefore, we can skip this CPU from the
+ * iteration.
+ */
+ if (cpu == raw_smp_processor_id())
+ continue;
+ rcu_read_lock();
+ p = task_rcu_dereference(&cpu_rq(cpu)->curr);
+ if (p && p->mm && (atomic_read(&p->mm->membarrier_state) &
+ MEMBARRIER_STATE_GLOBAL_EXPEDITED)) {
+ if (!fallback)
+ __cpumask_set_cpu(cpu, tmpmask);
+ else
+ smp_call_function_single(cpu, ipi_mb, NULL, 1);
+ }
+ rcu_read_unlock();
+ }
+ if (!fallback) {
+ preempt_disable();
+ smp_call_function_many(tmpmask, ipi_mb, NULL, 1);
+ preempt_enable();
+ free_cpumask_var(tmpmask);
+ }
+ cpus_read_unlock();
+
+ /*
+ * Memory barrier on the caller thread _after_ we finished
+ * waiting for the last IPI. Matches memory barriers around
+ * rq->curr modification in scheduler.
+ */
+ smp_mb(); /* exit from system call is not a mb */
+ return 0;
+}
+
+static int membarrier_private_expedited(int flags)
+{
+ int cpu;
+ bool fallback = false;
+ cpumask_var_t tmpmask;
+
+ if (flags & MEMBARRIER_FLAG_SYNC_CORE) {
+ if (!IS_ENABLED(CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE))
+ return -EINVAL;
+ if (!(atomic_read(&current->mm->membarrier_state) &
+ MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY))
+ return -EPERM;
+ } else {
+ if (!(atomic_read(&current->mm->membarrier_state) &
+ MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY))
+ return -EPERM;
+ }
if (num_online_cpus() == 1)
return 0;
@@ -105,21 +191,69 @@ static int membarrier_private_expedited(void)
return 0;
}
-static void membarrier_register_private_expedited(void)
+static int membarrier_register_global_expedited(void)
{
struct task_struct *p = current;
struct mm_struct *mm = p->mm;
+ if (atomic_read(&mm->membarrier_state) &
+ MEMBARRIER_STATE_GLOBAL_EXPEDITED_READY)
+ return 0;
+ atomic_or(MEMBARRIER_STATE_GLOBAL_EXPEDITED, &mm->membarrier_state);
+ if (atomic_read(&mm->mm_users) == 1 && get_nr_threads(p) == 1) {
+ /*
+ * For single mm user, single threaded process, we can
+ * simply issue a memory barrier after setting
+ * MEMBARRIER_STATE_GLOBAL_EXPEDITED to guarantee that
+ * no memory access following registration is reordered
+ * before registration.
+ */
+ smp_mb();
+ } else {
+ /*
+ * For multi-mm user threads, we need to ensure all
+ * future scheduler executions will observe the new
+ * thread flag state for this mm.
+ */
+ synchronize_sched();
+ }
+ atomic_or(MEMBARRIER_STATE_GLOBAL_EXPEDITED_READY,
+ &mm->membarrier_state);
+ return 0;
+}
+
+static int membarrier_register_private_expedited(int flags)
+{
+ struct task_struct *p = current;
+ struct mm_struct *mm = p->mm;
+ int state = MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY;
+
+ if (flags & MEMBARRIER_FLAG_SYNC_CORE) {
+ if (!IS_ENABLED(CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE))
+ return -EINVAL;
+ state = MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE_READY;
+ }
+
/*
* We need to consider threads belonging to different thread
* groups, which use the same mm. (CLONE_VM but not
* CLONE_THREAD).
*/
- if (atomic_read(&mm->membarrier_state)
- & MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY)
- return;
- atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED_READY,
- &mm->membarrier_state);
+ if (atomic_read(&mm->membarrier_state) & state)
+ return 0;
+ atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED, &mm->membarrier_state);
+ if (flags & MEMBARRIER_FLAG_SYNC_CORE)
+ atomic_or(MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE,
+ &mm->membarrier_state);
+ if (!(atomic_read(&mm->mm_users) == 1 && get_nr_threads(p) == 1)) {
+ /*
+ * Ensure all future scheduler executions will observe the
+ * new thread flag state for this process.
+ */
+ synchronize_sched();
+ }
+ atomic_or(state, &mm->membarrier_state);
+ return 0;
}
/**
@@ -159,21 +293,28 @@ SYSCALL_DEFINE2(membarrier, int, cmd, int, flags)
int cmd_mask = MEMBARRIER_CMD_BITMASK;
if (tick_nohz_full_enabled())
- cmd_mask &= ~MEMBARRIER_CMD_SHARED;
+ cmd_mask &= ~MEMBARRIER_CMD_GLOBAL;
return cmd_mask;
}
- case MEMBARRIER_CMD_SHARED:
- /* MEMBARRIER_CMD_SHARED is not compatible with nohz_full. */
+ case MEMBARRIER_CMD_GLOBAL:
+ /* MEMBARRIER_CMD_GLOBAL is not compatible with nohz_full. */
if (tick_nohz_full_enabled())
return -EINVAL;
if (num_online_cpus() > 1)
synchronize_sched();
return 0;
+ case MEMBARRIER_CMD_GLOBAL_EXPEDITED:
+ return membarrier_global_expedited();
+ case MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED:
+ return membarrier_register_global_expedited();
case MEMBARRIER_CMD_PRIVATE_EXPEDITED:
- return membarrier_private_expedited();
+ return membarrier_private_expedited(0);
case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED:
- membarrier_register_private_expedited();
- return 0;
+ return membarrier_register_private_expedited(0);
+ case MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE:
+ return membarrier_private_expedited(MEMBARRIER_FLAG_SYNC_CORE);
+ case MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE:
+ return membarrier_register_private_expedited(MEMBARRIER_FLAG_SYNC_CORE);
default:
return -EINVAL;
}
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 862a513adca3..663b2355a3aa 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -950,12 +950,13 @@ static void update_curr_rt(struct rq *rq)
{
struct task_struct *curr = rq->curr;
struct sched_rt_entity *rt_se = &curr->rt;
+ u64 now = rq_clock_task(rq);
u64 delta_exec;
if (curr->sched_class != &rt_sched_class)
return;
- delta_exec = rq_clock_task(rq) - curr->se.exec_start;
+ delta_exec = now - curr->se.exec_start;
if (unlikely((s64)delta_exec <= 0))
return;
@@ -968,7 +969,7 @@ static void update_curr_rt(struct rq *rq)
curr->se.sum_exec_runtime += delta_exec;
account_group_exec_runtime(curr, delta_exec);
- curr->se.exec_start = rq_clock_task(rq);
+ curr->se.exec_start = now;
cgroup_account_cputime(curr, delta_exec);
sched_rt_avg_update(rq, delta_exec);
@@ -1907,9 +1908,8 @@ static void push_rt_tasks(struct rq *rq)
* the rt_loop_next will cause the iterator to perform another scan.
*
*/
-static int rto_next_cpu(struct rq *rq)
+static int rto_next_cpu(struct root_domain *rd)
{
- struct root_domain *rd = rq->rd;
int next;
int cpu;
@@ -1985,19 +1985,24 @@ static void tell_cpu_to_push(struct rq *rq)
* Otherwise it is finishing up and an ipi needs to be sent.
*/
if (rq->rd->rto_cpu < 0)
- cpu = rto_next_cpu(rq);
+ cpu = rto_next_cpu(rq->rd);
raw_spin_unlock(&rq->rd->rto_lock);
rto_start_unlock(&rq->rd->rto_loop_start);
- if (cpu >= 0)
+ if (cpu >= 0) {
+ /* Make sure the rd does not get freed while pushing */
+ sched_get_rd(rq->rd);
irq_work_queue_on(&rq->rd->rto_push_work, cpu);
+ }
}
/* Called from hardirq context */
void rto_push_irq_work_func(struct irq_work *work)
{
+ struct root_domain *rd =
+ container_of(work, struct root_domain, rto_push_work);
struct rq *rq;
int cpu;
@@ -2013,18 +2018,20 @@ void rto_push_irq_work_func(struct irq_work *work)
raw_spin_unlock(&rq->lock);
}
- raw_spin_lock(&rq->rd->rto_lock);
+ raw_spin_lock(&rd->rto_lock);
/* Pass the IPI to the next rt overloaded queue */
- cpu = rto_next_cpu(rq);
+ cpu = rto_next_cpu(rd);
- raw_spin_unlock(&rq->rd->rto_lock);
+ raw_spin_unlock(&rd->rto_lock);
- if (cpu < 0)
+ if (cpu < 0) {
+ sched_put_rd(rd);
return;
+ }
/* Try the next RT overloaded CPU */
- irq_work_queue_on(&rq->rd->rto_push_work, cpu);
+ irq_work_queue_on(&rd->rto_push_work, cpu);
}
#endif /* HAVE_RT_PUSH_IPI */
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 2e95505e23c6..fb5fc458547f 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -691,6 +691,8 @@ extern struct mutex sched_domains_mutex;
extern void init_defrootdomain(void);
extern int sched_init_domains(const struct cpumask *cpu_map);
extern void rq_attach_root(struct rq *rq, struct root_domain *rd);
+extern void sched_get_rd(struct root_domain *rd);
+extern void sched_put_rd(struct root_domain *rd);
#ifdef HAVE_RT_PUSH_IPI
extern void rto_push_irq_work_func(struct irq_work *work);
diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h
index baf500d12b7c..8e7b58de61e7 100644
--- a/kernel/sched/stats.h
+++ b/kernel/sched/stats.h
@@ -31,8 +31,11 @@ rq_sched_info_dequeued(struct rq *rq, unsigned long long delta)
rq->rq_sched_info.run_delay += delta;
}
#define schedstat_enabled() static_branch_unlikely(&sched_schedstats)
+#define __schedstat_inc(var) do { var++; } while (0)
#define schedstat_inc(var) do { if (schedstat_enabled()) { var++; } } while (0)
+#define __schedstat_add(var, amt) do { var += (amt); } while (0)
#define schedstat_add(var, amt) do { if (schedstat_enabled()) { var += (amt); } } while (0)
+#define __schedstat_set(var, val) do { var = (val); } while (0)
#define schedstat_set(var, val) do { if (schedstat_enabled()) { var = (val); } } while (0)
#define schedstat_val(var) (var)
#define schedstat_val_or_zero(var) ((schedstat_enabled()) ? (var) : 0)
@@ -48,8 +51,11 @@ static inline void
rq_sched_info_depart(struct rq *rq, unsigned long long delta)
{}
#define schedstat_enabled() 0
+#define __schedstat_inc(var) do { } while (0)
#define schedstat_inc(var) do { } while (0)
+#define __schedstat_add(var, amt) do { } while (0)
#define schedstat_add(var, amt) do { } while (0)
+#define __schedstat_set(var, val) do { } while (0)
#define schedstat_set(var, val) do { } while (0)
#define schedstat_val(var) 0
#define schedstat_val_or_zero(var) 0
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index 034cbed7f88b..519b024f4e94 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -259,6 +259,19 @@ void rq_attach_root(struct rq *rq, struct root_domain *rd)
call_rcu_sched(&old_rd->rcu, free_rootdomain);
}
+void sched_get_rd(struct root_domain *rd)
+{
+ atomic_inc(&rd->refcount);
+}
+
+void sched_put_rd(struct root_domain *rd)
+{
+ if (!atomic_dec_and_test(&rd->refcount))
+ return;
+
+ call_rcu_sched(&rd->rcu, free_rootdomain);
+}
+
static int init_rootdomain(struct root_domain *rd)
{
if (!zalloc_cpumask_var(&rd->span, GFP_KERNEL))
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 2fb4e27c636a..f98f28c12020 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -218,6 +218,8 @@ static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
static int proc_dostring_coredump(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos);
#endif
+static int proc_dopipe_max_size(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos);
#ifdef CONFIG_MAGIC_SYSRQ
/* Note: sysrq code uses it's own private copy */
@@ -1812,8 +1814,7 @@ static struct ctl_table fs_table[] = {
.data = &pipe_max_size,
.maxlen = sizeof(pipe_max_size),
.mode = 0644,
- .proc_handler = &pipe_proc_fn,
- .extra1 = &pipe_min_size,
+ .proc_handler = proc_dopipe_max_size,
},
{
.procname = "pipe-user-pages-hard",
@@ -2615,29 +2616,17 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
do_proc_douintvec_minmax_conv, &param);
}
-struct do_proc_dopipe_max_size_conv_param {
- unsigned int *min;
-};
-
static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
unsigned int *valp,
int write, void *data)
{
- struct do_proc_dopipe_max_size_conv_param *param = data;
-
if (write) {
unsigned int val;
- if (*lvalp > UINT_MAX)
- return -EINVAL;
-
val = round_pipe_size(*lvalp);
if (val == 0)
return -EINVAL;
- if (param->min && *param->min > val)
- return -ERANGE;
-
*valp = val;
} else {
unsigned int val = *valp;
@@ -2647,14 +2636,11 @@ static int do_proc_dopipe_max_size_conv(unsigned long *lvalp,
return 0;
}
-int proc_dopipe_max_size(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
+static int proc_dopipe_max_size(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos)
{
- struct do_proc_dopipe_max_size_conv_param param = {
- .min = (unsigned int *) table->extra1,
- };
return do_proc_douintvec(table, write, buffer, lenp, ppos,
- do_proc_dopipe_max_size_conv, &param);
+ do_proc_dopipe_max_size_conv, NULL);
}
static void validate_coredump_safety(void)
@@ -3160,12 +3146,6 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
return -ENOSYS;
}
-int proc_dopipe_max_size(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
-{
- return -ENOSYS;
-}
-
int proc_dointvec_jiffies(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
@@ -3209,7 +3189,6 @@ EXPORT_SYMBOL(proc_douintvec);
EXPORT_SYMBOL(proc_dointvec_jiffies);
EXPORT_SYMBOL(proc_dointvec_minmax);
EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
-EXPORT_SYMBOL_GPL(proc_dopipe_max_size);
EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
EXPORT_SYMBOL(proc_dostring);
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 4559e914452b..4e62a4a8fa91 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -194,11 +194,7 @@ static int fill_stats_for_pid(pid_t pid, struct taskstats *stats)
{
struct task_struct *tsk;
- rcu_read_lock();
- tsk = find_task_by_vpid(pid);
- if (tsk)
- get_task_struct(tsk);
- rcu_read_unlock();
+ tsk = find_get_task_by_vpid(pid);
if (!tsk)
return -ESRCH;
fill_stats(current_user_ns(), task_active_pid_ns(current), tsk, stats);
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
index ae0c8a411fe7..23788100e214 100644
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -37,7 +37,6 @@
#include <linux/hrtimer.h>
#include <linux/notifier.h>
#include <linux/syscalls.h>
-#include <linux/kallsyms.h>
#include <linux/interrupt.h>
#include <linux/tick.h>
#include <linux/seq_file.h>
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 64d7c19d3167..b66c264d4194 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -217,7 +217,7 @@ config ENABLE_MUST_CHECK
config FRAME_WARN
int "Warn for stack frames larger than (needs gcc 4.4)"
range 0 8192
- default 0 if KASAN
+ default 3072 if KASAN_EXTRA
default 2048 if GCC_PLUGIN_LATENT_ENTROPY
default 1280 if (!64BIT && PARISC)
default 1024 if (!64BIT && !PARISC)
@@ -1641,7 +1641,10 @@ config DMA_API_DEBUG
If unsure, say N.
-menu "Runtime Testing"
+menuconfig RUNTIME_TESTING_MENU
+ bool "Runtime Testing"
+
+if RUNTIME_TESTING_MENU
config LKDTM
tristate "Linux Kernel Dump Test Tool Module"
@@ -1841,7 +1844,7 @@ config TEST_BPF
If unsure, say N.
-config TEST_FIND_BIT
+config FIND_BIT_BENCHMARK
tristate "Test find_bit functions"
default n
help
@@ -1929,7 +1932,7 @@ config TEST_DEBUG_VIRTUAL
If unsure, say N.
-endmenu # runtime tests
+endif # RUNTIME_TESTING_MENU
config MEMTEST
bool "Memtest"
diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan
index bd38aab05929..3d35d062970d 100644
--- a/lib/Kconfig.kasan
+++ b/lib/Kconfig.kasan
@@ -20,6 +20,17 @@ config KASAN
Currently CONFIG_KASAN doesn't work with CONFIG_DEBUG_SLAB
(the resulting kernel does not boot).
+config KASAN_EXTRA
+ bool "KAsan: extra checks"
+ depends on KASAN && DEBUG_KERNEL && !COMPILE_TEST
+ help
+ This enables further checks in the kernel address sanitizer, for now
+ it only includes the address-use-after-scope check that can lead
+ to excessive kernel stack usage, frame size warnings and longer
+ compile time.
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 has more
+
+
choice
prompt "Instrumentation type"
depends on KASAN
diff --git a/lib/Makefile b/lib/Makefile
index 7adb066692b3..a90d4fcd748f 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -46,8 +46,8 @@ obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o
obj-y += hexdump.o
obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
obj-y += kstrtox.o
+obj-$(CONFIG_FIND_BIT_BENCHMARK) += find_bit_benchmark.o
obj-$(CONFIG_TEST_BPF) += test_bpf.o
-obj-$(CONFIG_TEST_FIND_BIT) += test_find_bit.o
obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o
obj-$(CONFIG_TEST_HASH) += test_hash.o test_siphash.o
diff --git a/lib/bitmap.c b/lib/bitmap.c
index d8f0c094b18e..9e498c77ed0e 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -1106,111 +1106,80 @@ int bitmap_allocate_region(unsigned long *bitmap, unsigned int pos, int order)
EXPORT_SYMBOL(bitmap_allocate_region);
/**
- * bitmap_from_u32array - copy the contents of a u32 array of bits to bitmap
- * @bitmap: array of unsigned longs, the destination bitmap, non NULL
- * @nbits: number of bits in @bitmap
- * @buf: array of u32 (in host byte order), the source bitmap, non NULL
- * @nwords: number of u32 words in @buf
- *
- * copy min(nbits, 32*nwords) bits from @buf to @bitmap, remaining
- * bits between nword and nbits in @bitmap (if any) are cleared. In
- * last word of @bitmap, the bits beyond nbits (if any) are kept
- * unchanged.
+ * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order.
+ * @dst: destination buffer
+ * @src: bitmap to copy
+ * @nbits: number of bits in the bitmap
*
- * Return the number of bits effectively copied.
+ * Require nbits % BITS_PER_LONG == 0.
*/
-unsigned int
-bitmap_from_u32array(unsigned long *bitmap, unsigned int nbits,
- const u32 *buf, unsigned int nwords)
+#ifdef __BIG_ENDIAN
+void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits)
{
- unsigned int dst_idx, src_idx;
-
- for (src_idx = dst_idx = 0; dst_idx < BITS_TO_LONGS(nbits); ++dst_idx) {
- unsigned long part = 0;
-
- if (src_idx < nwords)
- part = buf[src_idx++];
-
-#if BITS_PER_LONG == 64
- if (src_idx < nwords)
- part |= ((unsigned long) buf[src_idx++]) << 32;
-#endif
-
- if (dst_idx < nbits/BITS_PER_LONG)
- bitmap[dst_idx] = part;
- else {
- unsigned long mask = BITMAP_LAST_WORD_MASK(nbits);
+ unsigned int i;
- bitmap[dst_idx] = (bitmap[dst_idx] & ~mask)
- | (part & mask);
- }
+ for (i = 0; i < nbits/BITS_PER_LONG; i++) {
+ if (BITS_PER_LONG == 64)
+ dst[i] = cpu_to_le64(src[i]);
+ else
+ dst[i] = cpu_to_le32(src[i]);
}
-
- return min_t(unsigned int, nbits, 32*nwords);
}
-EXPORT_SYMBOL(bitmap_from_u32array);
+EXPORT_SYMBOL(bitmap_copy_le);
+#endif
+#if BITS_PER_LONG == 64
/**
- * bitmap_to_u32array - copy the contents of bitmap to a u32 array of bits
- * @buf: array of u32 (in host byte order), the dest bitmap, non NULL
- * @nwords: number of u32 words in @buf
- * @bitmap: array of unsigned longs, the source bitmap, non NULL
+ * bitmap_from_arr32 - copy the contents of u32 array of bits to bitmap
+ * @bitmap: array of unsigned longs, the destination bitmap
+ * @buf: array of u32 (in host byte order), the source bitmap
* @nbits: number of bits in @bitmap
- *
- * copy min(nbits, 32*nwords) bits from @bitmap to @buf. Remaining
- * bits after nbits in @buf (if any) are cleared.
- *
- * Return the number of bits effectively copied.
*/
-unsigned int
-bitmap_to_u32array(u32 *buf, unsigned int nwords,
- const unsigned long *bitmap, unsigned int nbits)
+void bitmap_from_arr32(unsigned long *bitmap, const u32 *buf,
+ unsigned int nbits)
{
- unsigned int dst_idx = 0, src_idx = 0;
-
- while (dst_idx < nwords) {
- unsigned long part = 0;
-
- if (src_idx < BITS_TO_LONGS(nbits)) {
- part = bitmap[src_idx];
- if (src_idx >= nbits/BITS_PER_LONG)
- part &= BITMAP_LAST_WORD_MASK(nbits);
- src_idx++;
- }
+ unsigned int i, halfwords;
- buf[dst_idx++] = part & 0xffffffffUL;
+ if (!nbits)
+ return;
-#if BITS_PER_LONG == 64
- if (dst_idx < nwords) {
- part >>= 32;
- buf[dst_idx++] = part & 0xffffffffUL;
- }
-#endif
+ halfwords = DIV_ROUND_UP(nbits, 32);
+ for (i = 0; i < halfwords; i++) {
+ bitmap[i/2] = (unsigned long) buf[i];
+ if (++i < halfwords)
+ bitmap[i/2] |= ((unsigned long) buf[i]) << 32;
}
- return min_t(unsigned int, nbits, 32*nwords);
+ /* Clear tail bits in last word beyond nbits. */
+ if (nbits % BITS_PER_LONG)
+ bitmap[(halfwords - 1) / 2] &= BITMAP_LAST_WORD_MASK(nbits);
}
-EXPORT_SYMBOL(bitmap_to_u32array);
+EXPORT_SYMBOL(bitmap_from_arr32);
/**
- * bitmap_copy_le - copy a bitmap, putting the bits into little-endian order.
- * @dst: destination buffer
- * @src: bitmap to copy
- * @nbits: number of bits in the bitmap
- *
- * Require nbits % BITS_PER_LONG == 0.
+ * bitmap_to_arr32 - copy the contents of bitmap to a u32 array of bits
+ * @buf: array of u32 (in host byte order), the dest bitmap
+ * @bitmap: array of unsigned longs, the source bitmap
+ * @nbits: number of bits in @bitmap
*/
-#ifdef __BIG_ENDIAN
-void bitmap_copy_le(unsigned long *dst, const unsigned long *src, unsigned int nbits)
+void bitmap_to_arr32(u32 *buf, const unsigned long *bitmap, unsigned int nbits)
{
- unsigned int i;
+ unsigned int i, halfwords;
- for (i = 0; i < nbits/BITS_PER_LONG; i++) {
- if (BITS_PER_LONG == 64)
- dst[i] = cpu_to_le64(src[i]);
- else
- dst[i] = cpu_to_le32(src[i]);
+ if (!nbits)
+ return;
+
+ halfwords = DIV_ROUND_UP(nbits, 32);
+ for (i = 0; i < halfwords; i++) {
+ buf[i] = (u32) (bitmap[i/2] & UINT_MAX);
+ if (++i < halfwords)
+ buf[i] = (u32) (bitmap[i/2] >> 32);
}
+
+ /* Clear tail bits in last element of array beyond nbits. */
+ if (nbits % BITS_PER_LONG)
+ buf[halfwords - 1] &= (u32) (UINT_MAX >> ((-nbits) & 31));
}
-EXPORT_SYMBOL(bitmap_copy_le);
+EXPORT_SYMBOL(bitmap_to_arr32);
+
#endif
diff --git a/lib/cpumask.c b/lib/cpumask.c
index 35fe142ebb5e..beca6244671a 100644
--- a/lib/cpumask.c
+++ b/lib/cpumask.c
@@ -33,10 +33,11 @@ EXPORT_SYMBOL(cpumask_next);
int cpumask_next_and(int n, const struct cpumask *src1p,
const struct cpumask *src2p)
{
- while ((n = cpumask_next(n, src1p)) < nr_cpu_ids)
- if (cpumask_test_cpu(n, src2p))
- break;
- return n;
+ /* -1 is a legal arg here. */
+ if (n != -1)
+ cpumask_check(n);
+ return find_next_and_bit(cpumask_bits(src1p), cpumask_bits(src2p),
+ nr_cpumask_bits, n + 1);
}
EXPORT_SYMBOL(cpumask_next_and);
diff --git a/lib/find_bit.c b/lib/find_bit.c
index 6ed74f78380c..ee3df93ba69a 100644
--- a/lib/find_bit.c
+++ b/lib/find_bit.c
@@ -21,22 +21,29 @@
#include <linux/export.h>
#include <linux/kernel.h>
-#if !defined(find_next_bit) || !defined(find_next_zero_bit)
+#if !defined(find_next_bit) || !defined(find_next_zero_bit) || \
+ !defined(find_next_and_bit)
/*
- * This is a common helper function for find_next_bit and
- * find_next_zero_bit. The difference is the "invert" argument, which
- * is XORed with each fetched word before searching it for one bits.
+ * This is a common helper function for find_next_bit, find_next_zero_bit, and
+ * find_next_and_bit. The differences are:
+ * - The "invert" argument, which is XORed with each fetched word before
+ * searching it for one bits.
+ * - The optional "addr2", which is anded with "addr1" if present.
*/
-static unsigned long _find_next_bit(const unsigned long *addr,
- unsigned long nbits, unsigned long start, unsigned long invert)
+static inline unsigned long _find_next_bit(const unsigned long *addr1,
+ const unsigned long *addr2, unsigned long nbits,
+ unsigned long start, unsigned long invert)
{
unsigned long tmp;
if (unlikely(start >= nbits))
return nbits;
- tmp = addr[start / BITS_PER_LONG] ^ invert;
+ tmp = addr1[start / BITS_PER_LONG];
+ if (addr2)
+ tmp &= addr2[start / BITS_PER_LONG];
+ tmp ^= invert;
/* Handle 1st word. */
tmp &= BITMAP_FIRST_WORD_MASK(start);
@@ -47,7 +54,10 @@ static unsigned long _find_next_bit(const unsigned long *addr,
if (start >= nbits)
return nbits;
- tmp = addr[start / BITS_PER_LONG] ^ invert;
+ tmp = addr1[start / BITS_PER_LONG];
+ if (addr2)
+ tmp &= addr2[start / BITS_PER_LONG];
+ tmp ^= invert;
}
return min(start + __ffs(tmp), nbits);
@@ -61,7 +71,7 @@ static unsigned long _find_next_bit(const unsigned long *addr,
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
- return _find_next_bit(addr, size, offset, 0UL);
+ return _find_next_bit(addr, NULL, size, offset, 0UL);
}
EXPORT_SYMBOL(find_next_bit);
#endif
@@ -70,11 +80,21 @@ EXPORT_SYMBOL(find_next_bit);
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
- return _find_next_bit(addr, size, offset, ~0UL);
+ return _find_next_bit(addr, NULL, size, offset, ~0UL);
}
EXPORT_SYMBOL(find_next_zero_bit);
#endif
+#if !defined(find_next_and_bit)
+unsigned long find_next_and_bit(const unsigned long *addr1,
+ const unsigned long *addr2, unsigned long size,
+ unsigned long offset)
+{
+ return _find_next_bit(addr1, addr2, size, offset, 0UL);
+}
+EXPORT_SYMBOL(find_next_and_bit);
+#endif
+
#ifndef find_first_bit
/*
* Find the first set bit in a memory region.
@@ -146,15 +166,19 @@ static inline unsigned long ext2_swab(const unsigned long y)
}
#if !defined(find_next_bit_le) || !defined(find_next_zero_bit_le)
-static unsigned long _find_next_bit_le(const unsigned long *addr,
- unsigned long nbits, unsigned long start, unsigned long invert)
+static inline unsigned long _find_next_bit_le(const unsigned long *addr1,
+ const unsigned long *addr2, unsigned long nbits,
+ unsigned long start, unsigned long invert)
{
unsigned long tmp;
if (unlikely(start >= nbits))
return nbits;
- tmp = addr[start / BITS_PER_LONG] ^ invert;
+ tmp = addr1[start / BITS_PER_LONG];
+ if (addr2)
+ tmp &= addr2[start / BITS_PER_LONG];
+ tmp ^= invert;
/* Handle 1st word. */
tmp &= ext2_swab(BITMAP_FIRST_WORD_MASK(start));
@@ -165,7 +189,10 @@ static unsigned long _find_next_bit_le(const unsigned long *addr,
if (start >= nbits)
return nbits;
- tmp = addr[start / BITS_PER_LONG] ^ invert;
+ tmp = addr1[start / BITS_PER_LONG];
+ if (addr2)
+ tmp &= addr2[start / BITS_PER_LONG];
+ tmp ^= invert;
}
return min(start + __ffs(ext2_swab(tmp)), nbits);
@@ -176,7 +203,7 @@ static unsigned long _find_next_bit_le(const unsigned long *addr,
unsigned long find_next_zero_bit_le(const void *addr, unsigned
long size, unsigned long offset)
{
- return _find_next_bit_le(addr, size, offset, ~0UL);
+ return _find_next_bit_le(addr, NULL, size, offset, ~0UL);
}
EXPORT_SYMBOL(find_next_zero_bit_le);
#endif
@@ -185,7 +212,7 @@ EXPORT_SYMBOL(find_next_zero_bit_le);
unsigned long find_next_bit_le(const void *addr, unsigned
long size, unsigned long offset)
{
- return _find_next_bit_le(addr, size, offset, 0UL);
+ return _find_next_bit_le(addr, NULL, size, offset, 0UL);
}
EXPORT_SYMBOL(find_next_bit_le);
#endif
diff --git a/lib/test_find_bit.c b/lib/find_bit_benchmark.c
index f4394a36f9aa..5985a25e6cbc 100644
--- a/lib/test_find_bit.c
+++ b/lib/find_bit_benchmark.c
@@ -35,6 +35,7 @@
#define SPARSE 500
static DECLARE_BITMAP(bitmap, BITMAP_LEN) __initdata;
+static DECLARE_BITMAP(bitmap2, BITMAP_LEN) __initdata;
/*
* This is Schlemiel the Painter's algorithm. It should be called after
@@ -43,16 +44,15 @@ static DECLARE_BITMAP(bitmap, BITMAP_LEN) __initdata;
static int __init test_find_first_bit(void *bitmap, unsigned long len)
{
unsigned long i, cnt;
- cycles_t cycles;
+ ktime_t time;
- cycles = get_cycles();
+ time = ktime_get();
for (cnt = i = 0; i < len; cnt++) {
i = find_first_bit(bitmap, len);
__clear_bit(i, bitmap);
}
- cycles = get_cycles() - cycles;
- pr_err("find_first_bit:\t\t%llu cycles,\t%ld iterations\n",
- (u64)cycles, cnt);
+ time = ktime_get() - time;
+ pr_err("find_first_bit: %18llu ns, %6ld iterations\n", time, cnt);
return 0;
}
@@ -60,14 +60,13 @@ static int __init test_find_first_bit(void *bitmap, unsigned long len)
static int __init test_find_next_bit(const void *bitmap, unsigned long len)
{
unsigned long i, cnt;
- cycles_t cycles;
+ ktime_t time;
- cycles = get_cycles();
+ time = ktime_get();
for (cnt = i = 0; i < BITMAP_LEN; cnt++)
i = find_next_bit(bitmap, BITMAP_LEN, i) + 1;
- cycles = get_cycles() - cycles;
- pr_err("find_next_bit:\t\t%llu cycles,\t%ld iterations\n",
- (u64)cycles, cnt);
+ time = ktime_get() - time;
+ pr_err("find_next_bit: %18llu ns, %6ld iterations\n", time, cnt);
return 0;
}
@@ -75,14 +74,13 @@ static int __init test_find_next_bit(const void *bitmap, unsigned long len)
static int __init test_find_next_zero_bit(const void *bitmap, unsigned long len)
{
unsigned long i, cnt;
- cycles_t cycles;
+ ktime_t time;
- cycles = get_cycles();
+ time = ktime_get();
for (cnt = i = 0; i < BITMAP_LEN; cnt++)
i = find_next_zero_bit(bitmap, len, i) + 1;
- cycles = get_cycles() - cycles;
- pr_err("find_next_zero_bit:\t%llu cycles,\t%ld iterations\n",
- (u64)cycles, cnt);
+ time = ktime_get() - time;
+ pr_err("find_next_zero_bit: %18llu ns, %6ld iterations\n", time, cnt);
return 0;
}
@@ -90,9 +88,9 @@ static int __init test_find_next_zero_bit(const void *bitmap, unsigned long len)
static int __init test_find_last_bit(const void *bitmap, unsigned long len)
{
unsigned long l, cnt = 0;
- cycles_t cycles;
+ ktime_t time;
- cycles = get_cycles();
+ time = ktime_get();
do {
cnt++;
l = find_last_bit(bitmap, len);
@@ -100,9 +98,24 @@ static int __init test_find_last_bit(const void *bitmap, unsigned long len)
break;
len = l;
} while (len);
+ time = ktime_get() - time;
+ pr_err("find_last_bit: %18llu ns, %6ld iterations\n", time, cnt);
+
+ return 0;
+}
+
+static int __init test_find_next_and_bit(const void *bitmap,
+ const void *bitmap2, unsigned long len)
+{
+ unsigned long i, cnt;
+ cycles_t cycles;
+
+ cycles = get_cycles();
+ for (cnt = i = 0; i < BITMAP_LEN; cnt++)
+ i = find_next_and_bit(bitmap, bitmap2, BITMAP_LEN, i+1);
cycles = get_cycles() - cycles;
- pr_err("find_last_bit:\t\t%llu cycles,\t%ld iterations\n",
- (u64)cycles, cnt);
+ pr_err("find_next_and_bit:\t\t%llu cycles, %ld iterations\n",
+ (u64)cycles, cnt);
return 0;
}
@@ -114,31 +127,36 @@ static int __init find_bit_test(void)
pr_err("\nStart testing find_bit() with random-filled bitmap\n");
get_random_bytes(bitmap, sizeof(bitmap));
+ get_random_bytes(bitmap2, sizeof(bitmap2));
test_find_next_bit(bitmap, BITMAP_LEN);
test_find_next_zero_bit(bitmap, BITMAP_LEN);
test_find_last_bit(bitmap, BITMAP_LEN);
test_find_first_bit(bitmap, BITMAP_LEN);
+ test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN);
pr_err("\nStart testing find_bit() with sparse bitmap\n");
bitmap_zero(bitmap, BITMAP_LEN);
+ bitmap_zero(bitmap2, BITMAP_LEN);
- while (nbits--)
+ while (nbits--) {
__set_bit(prandom_u32() % BITMAP_LEN, bitmap);
+ __set_bit(prandom_u32() % BITMAP_LEN, bitmap2);
+ }
test_find_next_bit(bitmap, BITMAP_LEN);
test_find_next_zero_bit(bitmap, BITMAP_LEN);
test_find_last_bit(bitmap, BITMAP_LEN);
test_find_first_bit(bitmap, BITMAP_LEN);
+ test_find_next_and_bit(bitmap, bitmap2, BITMAP_LEN);
- return 0;
+ /*
+ * Everything is OK. Return error just to let user run benchmark
+ * again without annoying rmmod.
+ */
+ return -EINVAL;
}
module_init(find_bit_test);
-static void __exit test_find_bit_cleanup(void)
-{
-}
-module_exit(test_find_bit_cleanup);
-
MODULE_LICENSE("GPL");
diff --git a/lib/pci_iomap.c b/lib/pci_iomap.c
index c10fba461454..2d3eb1cb73b8 100644
--- a/lib/pci_iomap.c
+++ b/lib/pci_iomap.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Implement the default iomap interfaces
*
diff --git a/lib/stackdepot.c b/lib/stackdepot.c
index f87d138e9672..e513459a5601 100644
--- a/lib/stackdepot.c
+++ b/lib/stackdepot.c
@@ -163,6 +163,21 @@ static inline u32 hash_stack(unsigned long *entries, unsigned int size)
STACK_HASH_SEED);
}
+/* Use our own, non-instrumented version of memcmp().
+ *
+ * We actually don't care about the order, just the equality.
+ */
+static inline
+int stackdepot_memcmp(const unsigned long *u1, const unsigned long *u2,
+ unsigned int n)
+{
+ for ( ; n-- ; u1++, u2++) {
+ if (*u1 != *u2)
+ return 1;
+ }
+ return 0;
+}
+
/* Find a stack that is equal to the one stored in entries in the hash */
static inline struct stack_record *find_stack(struct stack_record *bucket,
unsigned long *entries, int size,
@@ -173,10 +188,8 @@ static inline struct stack_record *find_stack(struct stack_record *bucket,
for (found = bucket; found; found = found->next) {
if (found->hash == hash &&
found->size == size &&
- !memcmp(entries, found->entries,
- size * sizeof(unsigned long))) {
+ !stackdepot_memcmp(entries, found->entries, size))
return found;
- }
}
return NULL;
}
diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c
index aa1f2669bdd5..b3f235baa05d 100644
--- a/lib/test_bitmap.c
+++ b/lib/test_bitmap.c
@@ -23,7 +23,7 @@ __check_eq_uint(const char *srcfile, unsigned int line,
const unsigned int exp_uint, unsigned int x)
{
if (exp_uint != x) {
- pr_warn("[%s:%u] expected %u, got %u\n",
+ pr_err("[%s:%u] expected %u, got %u\n",
srcfile, line, exp_uint, x);
return false;
}
@@ -33,19 +33,13 @@ __check_eq_uint(const char *srcfile, unsigned int line,
static bool __init
__check_eq_bitmap(const char *srcfile, unsigned int line,
- const unsigned long *exp_bmap, unsigned int exp_nbits,
- const unsigned long *bmap, unsigned int nbits)
+ const unsigned long *exp_bmap, const unsigned long *bmap,
+ unsigned int nbits)
{
- if (exp_nbits != nbits) {
- pr_warn("[%s:%u] bitmap length mismatch: expected %u, got %u\n",
- srcfile, line, exp_nbits, nbits);
- return false;
- }
-
if (!bitmap_equal(exp_bmap, bmap, nbits)) {
pr_warn("[%s:%u] bitmaps contents differ: expected \"%*pbl\", got \"%*pbl\"\n",
srcfile, line,
- exp_nbits, exp_bmap, nbits, bmap);
+ nbits, exp_bmap, nbits, bmap);
return false;
}
return true;
@@ -69,6 +63,10 @@ __check_eq_pbl(const char *srcfile, unsigned int line,
static bool __init
__check_eq_u32_array(const char *srcfile, unsigned int line,
const u32 *exp_arr, unsigned int exp_len,
+ const u32 *arr, unsigned int len) __used;
+static bool __init
+__check_eq_u32_array(const char *srcfile, unsigned int line,
+ const u32 *exp_arr, unsigned int exp_len,
const u32 *arr, unsigned int len)
{
if (exp_len != len) {
@@ -107,7 +105,65 @@ __check_eq_u32_array(const char *srcfile, unsigned int line,
#define expect_eq_pbl(...) __expect_eq(pbl, ##__VA_ARGS__)
#define expect_eq_u32_array(...) __expect_eq(u32_array, ##__VA_ARGS__)
-static void __init test_zero_fill_copy(void)
+static void __init test_zero_clear(void)
+{
+ DECLARE_BITMAP(bmap, 1024);
+
+ /* Known way to set all bits */
+ memset(bmap, 0xff, 128);
+
+ expect_eq_pbl("0-22", bmap, 23);
+ expect_eq_pbl("0-1023", bmap, 1024);
+
+ /* single-word bitmaps */
+ bitmap_clear(bmap, 0, 9);
+ expect_eq_pbl("9-1023", bmap, 1024);
+
+ bitmap_zero(bmap, 35);
+ expect_eq_pbl("64-1023", bmap, 1024);
+
+ /* cross boundaries operations */
+ bitmap_clear(bmap, 79, 19);
+ expect_eq_pbl("64-78,98-1023", bmap, 1024);
+
+ bitmap_zero(bmap, 115);
+ expect_eq_pbl("128-1023", bmap, 1024);
+
+ /* Zeroing entire area */
+ bitmap_zero(bmap, 1024);
+ expect_eq_pbl("", bmap, 1024);
+}
+
+static void __init test_fill_set(void)
+{
+ DECLARE_BITMAP(bmap, 1024);
+
+ /* Known way to clear all bits */
+ memset(bmap, 0x00, 128);
+
+ expect_eq_pbl("", bmap, 23);
+ expect_eq_pbl("", bmap, 1024);
+
+ /* single-word bitmaps */
+ bitmap_set(bmap, 0, 9);
+ expect_eq_pbl("0-8", bmap, 1024);
+
+ bitmap_fill(bmap, 35);
+ expect_eq_pbl("0-63", bmap, 1024);
+
+ /* cross boundaries operations */
+ bitmap_set(bmap, 79, 19);
+ expect_eq_pbl("0-63,79-97", bmap, 1024);
+
+ bitmap_fill(bmap, 115);
+ expect_eq_pbl("0-127", bmap, 1024);
+
+ /* Zeroing entire area */
+ bitmap_fill(bmap, 1024);
+ expect_eq_pbl("0-1023", bmap, 1024);
+}
+
+static void __init test_copy(void)
{
DECLARE_BITMAP(bmap1, 1024);
DECLARE_BITMAP(bmap2, 1024);
@@ -116,36 +172,20 @@ static void __init test_zero_fill_copy(void)
bitmap_zero(bmap2, 1024);
/* single-word bitmaps */
- expect_eq_pbl("", bmap1, 23);
-
- bitmap_fill(bmap1, 19);
- expect_eq_pbl("0-18", bmap1, 1024);
-
+ bitmap_set(bmap1, 0, 19);
bitmap_copy(bmap2, bmap1, 23);
expect_eq_pbl("0-18", bmap2, 1024);
- bitmap_fill(bmap2, 23);
- expect_eq_pbl("0-22", bmap2, 1024);
-
+ bitmap_set(bmap2, 0, 23);
bitmap_copy(bmap2, bmap1, 23);
expect_eq_pbl("0-18", bmap2, 1024);
- bitmap_zero(bmap1, 23);
- expect_eq_pbl("", bmap1, 1024);
-
/* multi-word bitmaps */
- bitmap_zero(bmap1, 1024);
- expect_eq_pbl("", bmap1, 1024);
-
- bitmap_fill(bmap1, 109);
- expect_eq_pbl("0-108", bmap1, 1024);
-
+ bitmap_set(bmap1, 0, 109);
bitmap_copy(bmap2, bmap1, 1024);
expect_eq_pbl("0-108", bmap2, 1024);
bitmap_fill(bmap2, 1024);
- expect_eq_pbl("0-1023", bmap2, 1024);
-
bitmap_copy(bmap2, bmap1, 1024);
expect_eq_pbl("0-108", bmap2, 1024);
@@ -160,9 +200,6 @@ static void __init test_zero_fill_copy(void)
bitmap_fill(bmap2, 1024);
bitmap_copy(bmap2, bmap1, 97); /* ... but aligned on word length */
expect_eq_pbl("0-108,128-1023", bmap2, 1024);
-
- bitmap_zero(bmap2, 97); /* ... but 0-padded til word length */
- expect_eq_pbl("128-1023", bmap2, 1024);
}
#define PARSE_TIME 0x1
@@ -255,171 +292,29 @@ static void __init test_bitmap_parselist(void)
}
}
-static void __init test_bitmap_u32_array_conversions(void)
+static void __init test_bitmap_arr32(void)
{
- DECLARE_BITMAP(bmap1, 1024);
- DECLARE_BITMAP(bmap2, 1024);
- u32 exp_arr[32], arr[32];
- unsigned nbits;
-
- for (nbits = 0 ; nbits < 257 ; ++nbits) {
- const unsigned int used_u32s = DIV_ROUND_UP(nbits, 32);
- unsigned int i, rv;
-
- bitmap_zero(bmap1, nbits);
- bitmap_set(bmap1, nbits, 1024 - nbits); /* garbage */
-
- memset(arr, 0xff, sizeof(arr));
- rv = bitmap_to_u32array(arr, used_u32s, bmap1, nbits);
- expect_eq_uint(nbits, rv);
-
- memset(exp_arr, 0xff, sizeof(exp_arr));
- memset(exp_arr, 0, used_u32s*sizeof(*exp_arr));
- expect_eq_u32_array(exp_arr, 32, arr, 32);
-
- bitmap_fill(bmap2, 1024);
- rv = bitmap_from_u32array(bmap2, nbits, arr, used_u32s);
- expect_eq_uint(nbits, rv);
- expect_eq_bitmap(bmap1, 1024, bmap2, 1024);
-
- for (i = 0 ; i < nbits ; ++i) {
- /*
- * test conversion bitmap -> u32[]
- */
-
- bitmap_zero(bmap1, 1024);
- __set_bit(i, bmap1);
- bitmap_set(bmap1, nbits, 1024 - nbits); /* garbage */
-
- memset(arr, 0xff, sizeof(arr));
- rv = bitmap_to_u32array(arr, used_u32s, bmap1, nbits);
- expect_eq_uint(nbits, rv);
-
- /* 1st used u32 words contain expected bit set, the
- * remaining words are left unchanged (0xff)
- */
- memset(exp_arr, 0xff, sizeof(exp_arr));
- memset(exp_arr, 0, used_u32s*sizeof(*exp_arr));
- exp_arr[i/32] = (1U<<(i%32));
- expect_eq_u32_array(exp_arr, 32, arr, 32);
-
-
- /* same, with longer array to fill
- */
- memset(arr, 0xff, sizeof(arr));
- rv = bitmap_to_u32array(arr, 32, bmap1, nbits);
- expect_eq_uint(nbits, rv);
-
- /* 1st used u32 words contain expected bit set, the
- * remaining words are all 0s
- */
- memset(exp_arr, 0, sizeof(exp_arr));
- exp_arr[i/32] = (1U<<(i%32));
- expect_eq_u32_array(exp_arr, 32, arr, 32);
-
- /*
- * test conversion u32[] -> bitmap
- */
-
- /* the 1st nbits of bmap2 are identical to
- * bmap1, the remaining bits of bmap2 are left
- * unchanged (all 1s)
- */
- bitmap_fill(bmap2, 1024);
- rv = bitmap_from_u32array(bmap2, nbits,
- exp_arr, used_u32s);
- expect_eq_uint(nbits, rv);
-
- expect_eq_bitmap(bmap1, 1024, bmap2, 1024);
-
- /* same, with more bits to fill
- */
- memset(arr, 0xff, sizeof(arr)); /* garbage */
- memset(arr, 0, used_u32s*sizeof(u32));
- arr[i/32] = (1U<<(i%32));
-
- bitmap_fill(bmap2, 1024);
- rv = bitmap_from_u32array(bmap2, 1024, arr, used_u32s);
- expect_eq_uint(used_u32s*32, rv);
-
- /* the 1st nbits of bmap2 are identical to
- * bmap1, the remaining bits of bmap2 are cleared
- */
- bitmap_zero(bmap1, 1024);
- __set_bit(i, bmap1);
- expect_eq_bitmap(bmap1, 1024, bmap2, 1024);
-
-
- /*
- * test short conversion bitmap -> u32[] (1
- * word too short)
- */
- if (used_u32s > 1) {
- bitmap_zero(bmap1, 1024);
- __set_bit(i, bmap1);
- bitmap_set(bmap1, nbits,
- 1024 - nbits); /* garbage */
- memset(arr, 0xff, sizeof(arr));
-
- rv = bitmap_to_u32array(arr, used_u32s - 1,
- bmap1, nbits);
- expect_eq_uint((used_u32s - 1)*32, rv);
-
- /* 1st used u32 words contain expected
- * bit set, the remaining words are
- * left unchanged (0xff)
- */
- memset(exp_arr, 0xff, sizeof(exp_arr));
- memset(exp_arr, 0,
- (used_u32s-1)*sizeof(*exp_arr));
- if ((i/32) < (used_u32s - 1))
- exp_arr[i/32] = (1U<<(i%32));
- expect_eq_u32_array(exp_arr, 32, arr, 32);
- }
-
- /*
- * test short conversion u32[] -> bitmap (3
- * bits too short)
- */
- if (nbits > 3) {
- memset(arr, 0xff, sizeof(arr)); /* garbage */
- memset(arr, 0, used_u32s*sizeof(*arr));
- arr[i/32] = (1U<<(i%32));
-
- bitmap_zero(bmap1, 1024);
- rv = bitmap_from_u32array(bmap1, nbits - 3,
- arr, used_u32s);
- expect_eq_uint(nbits - 3, rv);
-
- /* we are expecting the bit < nbits -
- * 3 (none otherwise), and the rest of
- * bmap1 unchanged (0-filled)
- */
- bitmap_zero(bmap2, 1024);
- if (i < nbits - 3)
- __set_bit(i, bmap2);
- expect_eq_bitmap(bmap2, 1024, bmap1, 1024);
-
- /* do the same with bmap1 initially
- * 1-filled
- */
-
- bitmap_fill(bmap1, 1024);
- rv = bitmap_from_u32array(bmap1, nbits - 3,
- arr, used_u32s);
- expect_eq_uint(nbits - 3, rv);
-
- /* we are expecting the bit < nbits -
- * 3 (none otherwise), and the rest of
- * bmap1 unchanged (1-filled)
- */
- bitmap_zero(bmap2, 1024);
- if (i < nbits - 3)
- __set_bit(i, bmap2);
- bitmap_set(bmap2, nbits-3, 1024 - nbits + 3);
- expect_eq_bitmap(bmap2, 1024, bmap1, 1024);
- }
- }
+ unsigned int nbits, next_bit, len = sizeof(exp) * 8;
+ u32 arr[sizeof(exp) / 4];
+ DECLARE_BITMAP(bmap2, len);
+
+ memset(arr, 0xa5, sizeof(arr));
+
+ for (nbits = 0; nbits < len; ++nbits) {
+ bitmap_to_arr32(arr, exp, nbits);
+ bitmap_from_arr32(bmap2, arr, nbits);
+ expect_eq_bitmap(bmap2, exp, nbits);
+
+ next_bit = find_next_bit(bmap2,
+ round_up(nbits, BITS_PER_LONG), nbits);
+ if (next_bit < round_up(nbits, BITS_PER_LONG))
+ pr_err("bitmap_copy_arr32(nbits == %d:"
+ " tail is not safely cleared: %d\n",
+ nbits, next_bit);
+
+ if (nbits < len - 32)
+ expect_eq_uint(arr[DIV_ROUND_UP(nbits, 32)],
+ 0xa5a5a5a5);
}
}
@@ -453,8 +348,10 @@ static void noinline __init test_mem_optimisations(void)
static int __init test_bitmap_init(void)
{
- test_zero_fill_copy();
- test_bitmap_u32_array_conversions();
+ test_zero_clear();
+ test_fill_set();
+ test_copy();
+ test_bitmap_arr32();
test_bitmap_parselist();
test_mem_optimisations();
diff --git a/lib/test_kasan.c b/lib/test_kasan.c
index ef1a3ac1397e..98854a64b014 100644
--- a/lib/test_kasan.c
+++ b/lib/test_kasan.c
@@ -94,6 +94,37 @@ static noinline void __init kmalloc_pagealloc_oob_right(void)
ptr[size] = 0;
kfree(ptr);
}
+
+static noinline void __init kmalloc_pagealloc_uaf(void)
+{
+ char *ptr;
+ size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
+
+ pr_info("kmalloc pagealloc allocation: use-after-free\n");
+ ptr = kmalloc(size, GFP_KERNEL);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ kfree(ptr);
+ ptr[0] = 0;
+}
+
+static noinline void __init kmalloc_pagealloc_invalid_free(void)
+{
+ char *ptr;
+ size_t size = KMALLOC_MAX_CACHE_SIZE + 10;
+
+ pr_info("kmalloc pagealloc allocation: invalid-free\n");
+ ptr = kmalloc(size, GFP_KERNEL);
+ if (!ptr) {
+ pr_err("Allocation failed\n");
+ return;
+ }
+
+ kfree(ptr + 1);
+}
#endif
static noinline void __init kmalloc_large_oob_right(void)
@@ -388,7 +419,7 @@ static noinline void __init kasan_stack_oob(void)
static noinline void __init ksize_unpoisons_memory(void)
{
char *ptr;
- size_t size = 123, real_size = size;
+ size_t size = 123, real_size;
pr_info("ksize() unpoisons the whole allocated chunk\n");
ptr = kmalloc(size, GFP_KERNEL);
@@ -472,6 +503,74 @@ static noinline void __init use_after_scope_test(void)
p[1023] = 1;
}
+static noinline void __init kasan_alloca_oob_left(void)
+{
+ volatile int i = 10;
+ char alloca_array[i];
+ char *p = alloca_array - 1;
+
+ pr_info("out-of-bounds to left on alloca\n");
+ *(volatile char *)p;
+}
+
+static noinline void __init kasan_alloca_oob_right(void)
+{
+ volatile int i = 10;
+ char alloca_array[i];
+ char *p = alloca_array + i;
+
+ pr_info("out-of-bounds to right on alloca\n");
+ *(volatile char *)p;
+}
+
+static noinline void __init kmem_cache_double_free(void)
+{
+ char *p;
+ size_t size = 200;
+ struct kmem_cache *cache;
+
+ cache = kmem_cache_create("test_cache", size, 0, 0, NULL);
+ if (!cache) {
+ pr_err("Cache allocation failed\n");
+ return;
+ }
+ pr_info("double-free on heap object\n");
+ p = kmem_cache_alloc(cache, GFP_KERNEL);
+ if (!p) {
+ pr_err("Allocation failed\n");
+ kmem_cache_destroy(cache);
+ return;
+ }
+
+ kmem_cache_free(cache, p);
+ kmem_cache_free(cache, p);
+ kmem_cache_destroy(cache);
+}
+
+static noinline void __init kmem_cache_invalid_free(void)
+{
+ char *p;
+ size_t size = 200;
+ struct kmem_cache *cache;
+
+ cache = kmem_cache_create("test_cache", size, 0, SLAB_TYPESAFE_BY_RCU,
+ NULL);
+ if (!cache) {
+ pr_err("Cache allocation failed\n");
+ return;
+ }
+ pr_info("invalid-free of heap object\n");
+ p = kmem_cache_alloc(cache, GFP_KERNEL);
+ if (!p) {
+ pr_err("Allocation failed\n");
+ kmem_cache_destroy(cache);
+ return;
+ }
+
+ kmem_cache_free(cache, p + 1);
+ kmem_cache_destroy(cache);
+}
+
static int __init kmalloc_tests_init(void)
{
/*
@@ -485,6 +584,8 @@ static int __init kmalloc_tests_init(void)
kmalloc_node_oob_right();
#ifdef CONFIG_SLUB
kmalloc_pagealloc_oob_right();
+ kmalloc_pagealloc_uaf();
+ kmalloc_pagealloc_invalid_free();
#endif
kmalloc_large_oob_right();
kmalloc_oob_krealloc_more();
@@ -502,9 +603,13 @@ static int __init kmalloc_tests_init(void)
memcg_accounted_kmem_cache();
kasan_stack_oob();
kasan_global_oob();
+ kasan_alloca_oob_left();
+ kasan_alloca_oob_right();
ksize_unpoisons_memory();
copy_user_test();
use_after_scope_test();
+ kmem_cache_double_free();
+ kmem_cache_invalid_free();
kasan_restore_multi_shot(multishot);
diff --git a/lib/test_sort.c b/lib/test_sort.c
index d389c1cc2f6c..385c0ed5202f 100644
--- a/lib/test_sort.c
+++ b/lib/test_sort.c
@@ -39,5 +39,11 @@ exit:
return err;
}
+static void __exit test_sort_exit(void)
+{
+}
+
module_init(test_sort_init);
+module_exit(test_sort_exit);
+
MODULE_LICENSE("GPL");
diff --git a/lib/ubsan.c b/lib/ubsan.c
index fb0409df1bcf..59fee96c29a0 100644
--- a/lib/ubsan.c
+++ b/lib/ubsan.c
@@ -141,11 +141,6 @@ static void val_to_string(char *str, size_t size, struct type_descriptor *type,
}
}
-static bool location_is_valid(struct source_location *loc)
-{
- return loc->file_name != NULL;
-}
-
static DEFINE_SPINLOCK(report_lock);
static void ubsan_prologue(struct source_location *location,
@@ -265,14 +260,14 @@ void __ubsan_handle_divrem_overflow(struct overflow_data *data,
}
EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
-static void handle_null_ptr_deref(struct type_mismatch_data *data)
+static void handle_null_ptr_deref(struct type_mismatch_data_common *data)
{
unsigned long flags;
- if (suppress_report(&data->location))
+ if (suppress_report(data->location))
return;
- ubsan_prologue(&data->location, &flags);
+ ubsan_prologue(data->location, &flags);
pr_err("%s null pointer of type %s\n",
type_check_kinds[data->type_check_kind],
@@ -281,15 +276,15 @@ static void handle_null_ptr_deref(struct type_mismatch_data *data)
ubsan_epilogue(&flags);
}
-static void handle_missaligned_access(struct type_mismatch_data *data,
+static void handle_misaligned_access(struct type_mismatch_data_common *data,
unsigned long ptr)
{
unsigned long flags;
- if (suppress_report(&data->location))
+ if (suppress_report(data->location))
return;
- ubsan_prologue(&data->location, &flags);
+ ubsan_prologue(data->location, &flags);
pr_err("%s misaligned address %p for type %s\n",
type_check_kinds[data->type_check_kind],
@@ -299,15 +294,15 @@ static void handle_missaligned_access(struct type_mismatch_data *data,
ubsan_epilogue(&flags);
}
-static void handle_object_size_mismatch(struct type_mismatch_data *data,
+static void handle_object_size_mismatch(struct type_mismatch_data_common *data,
unsigned long ptr)
{
unsigned long flags;
- if (suppress_report(&data->location))
+ if (suppress_report(data->location))
return;
- ubsan_prologue(&data->location, &flags);
+ ubsan_prologue(data->location, &flags);
pr_err("%s address %p with insufficient space\n",
type_check_kinds[data->type_check_kind],
(void *) ptr);
@@ -315,37 +310,46 @@ static void handle_object_size_mismatch(struct type_mismatch_data *data,
ubsan_epilogue(&flags);
}
-void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
+static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data,
unsigned long ptr)
{
if (!ptr)
handle_null_ptr_deref(data);
else if (data->alignment && !IS_ALIGNED(ptr, data->alignment))
- handle_missaligned_access(data, ptr);
+ handle_misaligned_access(data, ptr);
else
handle_object_size_mismatch(data, ptr);
}
-EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
-void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
+void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
+ unsigned long ptr)
{
- unsigned long flags;
-
- if (suppress_report(&data->location))
- return;
-
- ubsan_prologue(&data->location, &flags);
+ struct type_mismatch_data_common common_data = {
+ .location = &data->location,
+ .type = data->type,
+ .alignment = data->alignment,
+ .type_check_kind = data->type_check_kind
+ };
+
+ ubsan_type_mismatch_common(&common_data, ptr);
+}
+EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
- pr_err("null pointer returned from function declared to never return null\n");
+void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
+ unsigned long ptr)
+{
- if (location_is_valid(&data->attr_location))
- print_source_location("returns_nonnull attribute specified in",
- &data->attr_location);
+ struct type_mismatch_data_common common_data = {
+ .location = &data->location,
+ .type = data->type,
+ .alignment = 1UL << data->log_alignment,
+ .type_check_kind = data->type_check_kind
+ };
- ubsan_epilogue(&flags);
+ ubsan_type_mismatch_common(&common_data, ptr);
}
-EXPORT_SYMBOL(__ubsan_handle_nonnull_return);
+EXPORT_SYMBOL(__ubsan_handle_type_mismatch_v1);
void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
unsigned long bound)
diff --git a/lib/ubsan.h b/lib/ubsan.h
index 88f23557edbe..f4d8d0bd4016 100644
--- a/lib/ubsan.h
+++ b/lib/ubsan.h
@@ -37,15 +37,24 @@ struct type_mismatch_data {
unsigned char type_check_kind;
};
-struct nonnull_arg_data {
+struct type_mismatch_data_v1 {
struct source_location location;
- struct source_location attr_location;
- int arg_index;
+ struct type_descriptor *type;
+ unsigned char log_alignment;
+ unsigned char type_check_kind;
+};
+
+struct type_mismatch_data_common {
+ struct source_location *location;
+ struct type_descriptor *type;
+ unsigned long alignment;
+ unsigned char type_check_kind;
};
-struct nonnull_return_data {
+struct nonnull_arg_data {
struct source_location location;
struct source_location attr_location;
+ int arg_index;
};
struct vla_bound_data {
diff --git a/mm/bootmem.c b/mm/bootmem.c
index 6aef64254203..9e197987b67d 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -410,7 +410,7 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
/**
* free_bootmem - mark a page range as usable
- * @addr: starting physical address of the range
+ * @physaddr: starting physical address of the range
* @size: size of the range in bytes
*
* Partial pages will be considered reserved and left as they are.
diff --git a/mm/gup.c b/mm/gup.c
index 9e17d8db2d6b..1b46e6e74881 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1394,7 +1394,6 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
VM_BUG_ON_PAGE(compound_head(page) != head, page);
- put_dev_pagemap(pgmap);
SetPageReferenced(page);
pages[*nr] = page;
(*nr)++;
@@ -1404,6 +1403,8 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
ret = 1;
pte_unmap:
+ if (pgmap)
+ put_dev_pagemap(pgmap);
pte_unmap(ptem);
return ret;
}
@@ -1443,10 +1444,12 @@ static int __gup_device_huge(unsigned long pfn, unsigned long addr,
SetPageReferenced(page);
pages[*nr] = page;
get_page(page);
- put_dev_pagemap(pgmap);
(*nr)++;
pfn++;
} while (addr += PAGE_SIZE, addr != end);
+
+ if (pgmap)
+ put_dev_pagemap(pgmap);
return 1;
}
diff --git a/mm/hmm.c b/mm/hmm.c
index 979211c7ccc8..320545b98ff5 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -836,10 +836,10 @@ static void hmm_devmem_release(struct device *dev, void *data)
mem_hotplug_begin();
if (resource->desc == IORES_DESC_DEVICE_PRIVATE_MEMORY)
- __remove_pages(zone, start_pfn, npages);
+ __remove_pages(zone, start_pfn, npages, NULL);
else
arch_remove_memory(start_pfn << PAGE_SHIFT,
- npages << PAGE_SHIFT);
+ npages << PAGE_SHIFT, NULL);
mem_hotplug_done();
hmm_devmem_radix_release(resource);
@@ -880,7 +880,7 @@ static int hmm_devmem_pages_create(struct hmm_devmem *devmem)
else
devmem->pagemap.type = MEMORY_DEVICE_PRIVATE;
- devmem->pagemap.res = devmem->resource;
+ devmem->pagemap.res = *devmem->resource;
devmem->pagemap.page_fault = hmm_devmem_fault;
devmem->pagemap.page_free = hmm_devmem_free;
devmem->pagemap.dev = devmem->device;
@@ -929,17 +929,18 @@ static int hmm_devmem_pages_create(struct hmm_devmem *devmem)
* want the linear mapping and thus use arch_add_memory().
*/
if (devmem->pagemap.type == MEMORY_DEVICE_PUBLIC)
- ret = arch_add_memory(nid, align_start, align_size, false);
+ ret = arch_add_memory(nid, align_start, align_size, NULL,
+ false);
else
ret = add_pages(nid, align_start >> PAGE_SHIFT,
- align_size >> PAGE_SHIFT, false);
+ align_size >> PAGE_SHIFT, NULL, false);
if (ret) {
mem_hotplug_done();
goto error_add_memory;
}
move_pfn_range_to_zone(&NODE_DATA(nid)->node_zones[ZONE_DEVICE],
align_start >> PAGE_SHIFT,
- align_size >> PAGE_SHIFT);
+ align_size >> PAGE_SHIFT, NULL);
mem_hotplug_done();
for (pfn = devmem->pfn_first; pfn < devmem->pfn_last; pfn++) {
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c
index 405bba487df5..e13d911251e7 100644
--- a/mm/kasan/kasan.c
+++ b/mm/kasan/kasan.c
@@ -5,7 +5,7 @@
* Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
*
* Some code borrowed from https://github.com/xairy/kasan-prototype by
- * Andrey Konovalov <adech.fo@gmail.com>
+ * Andrey Konovalov <andreyknvl@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
@@ -489,21 +489,17 @@ void kasan_slab_alloc(struct kmem_cache *cache, void *object, gfp_t flags)
kasan_kmalloc(cache, object, cache->object_size, flags);
}
-static void kasan_poison_slab_free(struct kmem_cache *cache, void *object)
-{
- unsigned long size = cache->object_size;
- unsigned long rounded_up_size = round_up(size, KASAN_SHADOW_SCALE_SIZE);
-
- /* RCU slabs could be legally used after free within the RCU period */
- if (unlikely(cache->flags & SLAB_TYPESAFE_BY_RCU))
- return;
-
- kasan_poison_shadow(object, rounded_up_size, KASAN_KMALLOC_FREE);
-}
-
-bool kasan_slab_free(struct kmem_cache *cache, void *object)
+static bool __kasan_slab_free(struct kmem_cache *cache, void *object,
+ unsigned long ip, bool quarantine)
{
s8 shadow_byte;
+ unsigned long rounded_up_size;
+
+ if (unlikely(nearest_obj(cache, virt_to_head_page(object), object) !=
+ object)) {
+ kasan_report_invalid_free(object, ip);
+ return true;
+ }
/* RCU slabs could be legally used after free within the RCU period */
if (unlikely(cache->flags & SLAB_TYPESAFE_BY_RCU))
@@ -511,14 +507,14 @@ bool kasan_slab_free(struct kmem_cache *cache, void *object)
shadow_byte = READ_ONCE(*(s8 *)kasan_mem_to_shadow(object));
if (shadow_byte < 0 || shadow_byte >= KASAN_SHADOW_SCALE_SIZE) {
- kasan_report_double_free(cache, object,
- __builtin_return_address(1));
+ kasan_report_invalid_free(object, ip);
return true;
}
- kasan_poison_slab_free(cache, object);
+ rounded_up_size = round_up(cache->object_size, KASAN_SHADOW_SCALE_SIZE);
+ kasan_poison_shadow(object, rounded_up_size, KASAN_KMALLOC_FREE);
- if (unlikely(!(cache->flags & SLAB_KASAN)))
+ if (!quarantine || unlikely(!(cache->flags & SLAB_KASAN)))
return false;
set_track(&get_alloc_info(cache, object)->free_track, GFP_NOWAIT);
@@ -526,6 +522,11 @@ bool kasan_slab_free(struct kmem_cache *cache, void *object)
return true;
}
+bool kasan_slab_free(struct kmem_cache *cache, void *object, unsigned long ip)
+{
+ return __kasan_slab_free(cache, object, ip, true);
+}
+
void kasan_kmalloc(struct kmem_cache *cache, const void *object, size_t size,
gfp_t flags)
{
@@ -589,25 +590,29 @@ void kasan_krealloc(const void *object, size_t size, gfp_t flags)
kasan_kmalloc(page->slab_cache, object, size, flags);
}
-void kasan_poison_kfree(void *ptr)
+void kasan_poison_kfree(void *ptr, unsigned long ip)
{
struct page *page;
page = virt_to_head_page(ptr);
- if (unlikely(!PageSlab(page)))
+ if (unlikely(!PageSlab(page))) {
+ if (ptr != page_address(page)) {
+ kasan_report_invalid_free(ptr, ip);
+ return;
+ }
kasan_poison_shadow(ptr, PAGE_SIZE << compound_order(page),
KASAN_FREE_PAGE);
- else
- kasan_poison_slab_free(page->slab_cache, ptr);
+ } else {
+ __kasan_slab_free(page->slab_cache, ptr, ip, false);
+ }
}
-void kasan_kfree_large(const void *ptr)
+void kasan_kfree_large(void *ptr, unsigned long ip)
{
- struct page *page = virt_to_page(ptr);
-
- kasan_poison_shadow(ptr, PAGE_SIZE << compound_order(page),
- KASAN_FREE_PAGE);
+ if (ptr != page_address(virt_to_head_page(ptr)))
+ kasan_report_invalid_free(ptr, ip);
+ /* The object will be poisoned by page_alloc. */
}
int kasan_module_alloc(void *addr, size_t size)
@@ -736,6 +741,55 @@ void __asan_unpoison_stack_memory(const void *addr, size_t size)
}
EXPORT_SYMBOL(__asan_unpoison_stack_memory);
+/* Emitted by compiler to poison alloca()ed objects. */
+void __asan_alloca_poison(unsigned long addr, size_t size)
+{
+ size_t rounded_up_size = round_up(size, KASAN_SHADOW_SCALE_SIZE);
+ size_t padding_size = round_up(size, KASAN_ALLOCA_REDZONE_SIZE) -
+ rounded_up_size;
+ size_t rounded_down_size = round_down(size, KASAN_SHADOW_SCALE_SIZE);
+
+ const void *left_redzone = (const void *)(addr -
+ KASAN_ALLOCA_REDZONE_SIZE);
+ const void *right_redzone = (const void *)(addr + rounded_up_size);
+
+ WARN_ON(!IS_ALIGNED(addr, KASAN_ALLOCA_REDZONE_SIZE));
+
+ kasan_unpoison_shadow((const void *)(addr + rounded_down_size),
+ size - rounded_down_size);
+ kasan_poison_shadow(left_redzone, KASAN_ALLOCA_REDZONE_SIZE,
+ KASAN_ALLOCA_LEFT);
+ kasan_poison_shadow(right_redzone,
+ padding_size + KASAN_ALLOCA_REDZONE_SIZE,
+ KASAN_ALLOCA_RIGHT);
+}
+EXPORT_SYMBOL(__asan_alloca_poison);
+
+/* Emitted by compiler to unpoison alloca()ed areas when the stack unwinds. */
+void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom)
+{
+ if (unlikely(!stack_top || stack_top > stack_bottom))
+ return;
+
+ kasan_unpoison_shadow(stack_top, stack_bottom - stack_top);
+}
+EXPORT_SYMBOL(__asan_allocas_unpoison);
+
+/* Emitted by the compiler to [un]poison local variables. */
+#define DEFINE_ASAN_SET_SHADOW(byte) \
+ void __asan_set_shadow_##byte(const void *addr, size_t size) \
+ { \
+ __memset((void *)addr, 0x##byte, size); \
+ } \
+ EXPORT_SYMBOL(__asan_set_shadow_##byte)
+
+DEFINE_ASAN_SET_SHADOW(00);
+DEFINE_ASAN_SET_SHADOW(f1);
+DEFINE_ASAN_SET_SHADOW(f2);
+DEFINE_ASAN_SET_SHADOW(f3);
+DEFINE_ASAN_SET_SHADOW(f5);
+DEFINE_ASAN_SET_SHADOW(f8);
+
#ifdef CONFIG_MEMORY_HOTPLUG
static int __meminit kasan_mem_notifier(struct notifier_block *nb,
unsigned long action, void *data)
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index c70851a9a6a4..c12dcfde2ebd 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -24,6 +24,14 @@
#define KASAN_STACK_PARTIAL 0xF4
#define KASAN_USE_AFTER_SCOPE 0xF8
+/*
+ * alloca redzone shadow values
+ */
+#define KASAN_ALLOCA_LEFT 0xCA
+#define KASAN_ALLOCA_RIGHT 0xCB
+
+#define KASAN_ALLOCA_REDZONE_SIZE 32
+
/* Don't break randconfig/all*config builds */
#ifndef KASAN_ABI_VERSION
#define KASAN_ABI_VERSION 1
@@ -99,8 +107,7 @@ static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
void kasan_report(unsigned long addr, size_t size,
bool is_write, unsigned long ip);
-void kasan_report_double_free(struct kmem_cache *cache, void *object,
- void *ip);
+void kasan_report_invalid_free(void *object, unsigned long ip);
#if defined(CONFIG_SLAB) || defined(CONFIG_SLUB)
void quarantine_put(struct kasan_free_meta *info, struct kmem_cache *cache);
@@ -113,4 +120,48 @@ static inline void quarantine_reduce(void) { }
static inline void quarantine_remove_cache(struct kmem_cache *cache) { }
#endif
+/*
+ * Exported functions for interfaces called from assembly or from generated
+ * code. Declarations here to avoid warning about missing declarations.
+ */
+asmlinkage void kasan_unpoison_task_stack_below(const void *watermark);
+void __asan_register_globals(struct kasan_global *globals, size_t size);
+void __asan_unregister_globals(struct kasan_global *globals, size_t size);
+void __asan_loadN(unsigned long addr, size_t size);
+void __asan_storeN(unsigned long addr, size_t size);
+void __asan_handle_no_return(void);
+void __asan_poison_stack_memory(const void *addr, size_t size);
+void __asan_unpoison_stack_memory(const void *addr, size_t size);
+void __asan_alloca_poison(unsigned long addr, size_t size);
+void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom);
+
+void __asan_load1(unsigned long addr);
+void __asan_store1(unsigned long addr);
+void __asan_load2(unsigned long addr);
+void __asan_store2(unsigned long addr);
+void __asan_load4(unsigned long addr);
+void __asan_store4(unsigned long addr);
+void __asan_load8(unsigned long addr);
+void __asan_store8(unsigned long addr);
+void __asan_load16(unsigned long addr);
+void __asan_store16(unsigned long addr);
+
+void __asan_load1_noabort(unsigned long addr);
+void __asan_store1_noabort(unsigned long addr);
+void __asan_load2_noabort(unsigned long addr);
+void __asan_store2_noabort(unsigned long addr);
+void __asan_load4_noabort(unsigned long addr);
+void __asan_store4_noabort(unsigned long addr);
+void __asan_load8_noabort(unsigned long addr);
+void __asan_store8_noabort(unsigned long addr);
+void __asan_load16_noabort(unsigned long addr);
+void __asan_store16_noabort(unsigned long addr);
+
+void __asan_set_shadow_00(const void *addr, size_t size);
+void __asan_set_shadow_f1(const void *addr, size_t size);
+void __asan_set_shadow_f2(const void *addr, size_t size);
+void __asan_set_shadow_f3(const void *addr, size_t size);
+void __asan_set_shadow_f5(const void *addr, size_t size);
+void __asan_set_shadow_f8(const void *addr, size_t size);
+
#endif
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 410c8235e671..5c169aa688fd 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -5,7 +5,7 @@
* Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
*
* Some code borrowed from https://github.com/xairy/kasan-prototype by
- * Andrey Konovalov <adech.fo@gmail.com>
+ * Andrey Konovalov <andreyknvl@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
@@ -102,6 +102,10 @@ static const char *get_shadow_bug_type(struct kasan_access_info *info)
case KASAN_USE_AFTER_SCOPE:
bug_type = "use-after-scope";
break;
+ case KASAN_ALLOCA_LEFT:
+ case KASAN_ALLOCA_RIGHT:
+ bug_type = "alloca-out-of-bounds";
+ break;
}
return bug_type;
@@ -322,13 +326,12 @@ static void print_shadow_for_address(const void *addr)
}
}
-void kasan_report_double_free(struct kmem_cache *cache, void *object,
- void *ip)
+void kasan_report_invalid_free(void *object, unsigned long ip)
{
unsigned long flags;
kasan_start_report(&flags);
- pr_err("BUG: KASAN: double-free or invalid-free in %pS\n", ip);
+ pr_err("BUG: KASAN: double-free or invalid-free in %pS\n", (void *)ip);
pr_err("\n");
print_address_description(object);
pr_err("\n");
diff --git a/mm/ksm.c b/mm/ksm.c
index c406f75957ad..293721f5da70 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -2302,7 +2302,7 @@ next_mm:
/**
* ksm_do_scan - the ksm scanner main worker function.
- * @scan_npages - number of pages we want to scan before we return.
+ * @scan_npages: number of pages we want to scan before we return.
*/
static void ksm_do_scan(unsigned int scan_npages)
{
diff --git a/mm/maccess.c b/mm/maccess.c
index 78f9274dd49d..ec00be51a24f 100644
--- a/mm/maccess.c
+++ b/mm/maccess.c
@@ -70,7 +70,7 @@ EXPORT_SYMBOL_GPL(probe_kernel_write);
* strncpy_from_unsafe: - Copy a NUL terminated string from unsafe address.
* @dst: Destination address, in kernel space. This buffer must be at
* least @count bytes long.
- * @src: Unsafe address.
+ * @unsafe_addr: Unsafe address.
* @count: Maximum number of bytes to copy, including the trailing NUL.
*
* Copies a NUL-terminated string from unsafe address to kernel buffer.
diff --git a/mm/memblock.c b/mm/memblock.c
index 46aacdfa4f4d..5a9ca2a1751b 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -1654,7 +1654,7 @@ bool __init_memblock memblock_is_memory(phys_addr_t addr)
return memblock_search(&memblock.memory, addr) != -1;
}
-int __init_memblock memblock_is_map_memory(phys_addr_t addr)
+bool __init_memblock memblock_is_map_memory(phys_addr_t addr)
{
int i = memblock_search(&memblock.memory, addr);
@@ -1690,13 +1690,13 @@ int __init_memblock memblock_search_pfn_nid(unsigned long pfn,
* RETURNS:
* 0 if false, non-zero if true
*/
-int __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t size)
+bool __init_memblock memblock_is_region_memory(phys_addr_t base, phys_addr_t size)
{
int idx = memblock_search(&memblock.memory, base);
phys_addr_t end = base + memblock_cap_size(base, &size);
if (idx == -1)
- return 0;
+ return false;
return (memblock.memory.regions[idx].base +
memblock.memory.regions[idx].size) >= end;
}
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 0937f2c52c7d..13b35ffa021e 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -917,7 +917,7 @@ int mem_cgroup_scan_tasks(struct mem_cgroup *memcg,
/**
* mem_cgroup_page_lruvec - return lruvec for isolating/putting an LRU page
* @page: the page
- * @zone: zone of the page
+ * @pgdat: pgdat of the page
*
* This function is only safe when following the LRU page isolation
* and putback protocol: the LRU lock must be held, and the page must
@@ -5818,8 +5818,8 @@ bool mem_cgroup_charge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
/**
* mem_cgroup_uncharge_skmem - uncharge socket memory
- * @memcg - memcg to uncharge
- * @nr_pages - number of pages to uncharge
+ * @memcg: memcg to uncharge
+ * @nr_pages: number of pages to uncharge
*/
void mem_cgroup_uncharge_skmem(struct mem_cgroup *memcg, unsigned int nr_pages)
{
diff --git a/mm/memory.c b/mm/memory.c
index 53373b7a1512..dd8de96f5547 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -59,7 +59,6 @@
#include <linux/writeback.h>
#include <linux/memcontrol.h>
#include <linux/mmu_notifier.h>
-#include <linux/kallsyms.h>
#include <linux/swapops.h>
#include <linux/elf.h>
#include <linux/gfp.h>
@@ -767,9 +766,6 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
dump_page(page, "bad pte");
pr_alert("addr:%p vm_flags:%08lx anon_vma:%p mapping:%p index:%lx\n",
(void *)addr, vma->vm_flags, vma->anon_vma, mapping, index);
- /*
- * Choose text because data symbols depend on CONFIG_KALLSYMS_ALL=y
- */
pr_alert("file:%pD fault:%pf mmap:%pf readpage:%pf\n",
vma->vm_file,
vma->vm_ops ? vma->vm_ops->fault : NULL,
@@ -1904,12 +1900,26 @@ int vm_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr,
}
EXPORT_SYMBOL(vm_insert_pfn_prot);
+static bool vm_mixed_ok(struct vm_area_struct *vma, pfn_t pfn)
+{
+ /* these checks mirror the abort conditions in vm_normal_page */
+ if (vma->vm_flags & VM_MIXEDMAP)
+ return true;
+ if (pfn_t_devmap(pfn))
+ return true;
+ if (pfn_t_special(pfn))
+ return true;
+ if (is_zero_pfn(pfn_t_to_pfn(pfn)))
+ return true;
+ return false;
+}
+
static int __vm_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
pfn_t pfn, bool mkwrite)
{
pgprot_t pgprot = vma->vm_page_prot;
- BUG_ON(!(vma->vm_flags & VM_MIXEDMAP));
+ BUG_ON(!vm_mixed_ok(vma, pfn));
if (addr < vma->vm_start || addr >= vma->vm_end)
return -EFAULT;
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 9bbd6982d4e4..b2bd52ff7605 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -247,7 +247,7 @@ void __init register_page_bootmem_info_node(struct pglist_data *pgdat)
#endif /* CONFIG_HAVE_BOOTMEM_INFO_NODE */
static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
- bool want_memblock)
+ struct vmem_altmap *altmap, bool want_memblock)
{
int ret;
int i;
@@ -255,7 +255,7 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
if (pfn_valid(phys_start_pfn))
return -EEXIST;
- ret = sparse_add_one_section(NODE_DATA(nid), phys_start_pfn);
+ ret = sparse_add_one_section(NODE_DATA(nid), phys_start_pfn, altmap);
if (ret < 0)
return ret;
@@ -289,18 +289,17 @@ static int __meminit __add_section(int nid, unsigned long phys_start_pfn,
* add the new pages.
*/
int __ref __add_pages(int nid, unsigned long phys_start_pfn,
- unsigned long nr_pages, bool want_memblock)
+ unsigned long nr_pages, struct vmem_altmap *altmap,
+ bool want_memblock)
{
unsigned long i;
int err = 0;
int start_sec, end_sec;
- struct vmem_altmap *altmap;
/* during initialize mem_map, align hot-added range to section */
start_sec = pfn_to_section_nr(phys_start_pfn);
end_sec = pfn_to_section_nr(phys_start_pfn + nr_pages - 1);
- altmap = to_vmem_altmap((unsigned long) pfn_to_page(phys_start_pfn));
if (altmap) {
/*
* Validate altmap is within bounds of the total request
@@ -315,7 +314,8 @@ int __ref __add_pages(int nid, unsigned long phys_start_pfn,
}
for (i = start_sec; i <= end_sec; i++) {
- err = __add_section(nid, section_nr_to_pfn(i), want_memblock);
+ err = __add_section(nid, section_nr_to_pfn(i), altmap,
+ want_memblock);
/*
* EEXIST is finally dealt with by ioresource collision
@@ -331,7 +331,6 @@ int __ref __add_pages(int nid, unsigned long phys_start_pfn,
out:
return err;
}
-EXPORT_SYMBOL_GPL(__add_pages);
#ifdef CONFIG_MEMORY_HOTREMOVE
/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
@@ -534,7 +533,7 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn)
}
static int __remove_section(struct zone *zone, struct mem_section *ms,
- unsigned long map_offset)
+ unsigned long map_offset, struct vmem_altmap *altmap)
{
unsigned long start_pfn;
int scn_nr;
@@ -551,7 +550,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms,
start_pfn = section_nr_to_pfn((unsigned long)scn_nr);
__remove_zone(zone, start_pfn);
- sparse_remove_one_section(zone, ms, map_offset);
+ sparse_remove_one_section(zone, ms, map_offset, altmap);
return 0;
}
@@ -567,7 +566,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms,
* calling offline_pages().
*/
int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
- unsigned long nr_pages)
+ unsigned long nr_pages, struct vmem_altmap *altmap)
{
unsigned long i;
unsigned long map_offset = 0;
@@ -575,10 +574,6 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
/* In the ZONE_DEVICE case device driver owns the memory region */
if (is_dev_zone(zone)) {
- struct page *page = pfn_to_page(phys_start_pfn);
- struct vmem_altmap *altmap;
-
- altmap = to_vmem_altmap((unsigned long) page);
if (altmap)
map_offset = vmem_altmap_offset(altmap);
} else {
@@ -609,7 +604,8 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
for (i = 0; i < sections_to_remove; i++) {
unsigned long pfn = phys_start_pfn + i*PAGES_PER_SECTION;
- ret = __remove_section(zone, __pfn_to_section(pfn), map_offset);
+ ret = __remove_section(zone, __pfn_to_section(pfn), map_offset,
+ altmap);
map_offset = 0;
if (ret)
break;
@@ -799,8 +795,8 @@ static void __meminit resize_pgdat_range(struct pglist_data *pgdat, unsigned lon
pgdat->node_spanned_pages = max(start_pfn + nr_pages, old_end_pfn) - pgdat->node_start_pfn;
}
-void __ref move_pfn_range_to_zone(struct zone *zone,
- unsigned long start_pfn, unsigned long nr_pages)
+void __ref move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
+ unsigned long nr_pages, struct vmem_altmap *altmap)
{
struct pglist_data *pgdat = zone->zone_pgdat;
int nid = pgdat->node_id;
@@ -825,7 +821,8 @@ void __ref move_pfn_range_to_zone(struct zone *zone,
* expects the zone spans the pfn range. All the pages in the range
* are reserved so nobody should be touching them so we should be safe
*/
- memmap_init_zone(nr_pages, nid, zone_idx(zone), start_pfn, MEMMAP_HOTPLUG);
+ memmap_init_zone(nr_pages, nid, zone_idx(zone), start_pfn,
+ MEMMAP_HOTPLUG, altmap);
set_zone_contiguous(zone);
}
@@ -897,7 +894,7 @@ static struct zone * __meminit move_pfn_range(int online_type, int nid,
struct zone *zone;
zone = zone_for_pfn_range(online_type, nid, start_pfn, nr_pages);
- move_pfn_range_to_zone(zone, start_pfn, nr_pages);
+ move_pfn_range_to_zone(zone, start_pfn, nr_pages, NULL);
return zone;
}
@@ -1146,7 +1143,7 @@ int __ref add_memory_resource(int nid, struct resource *res, bool online)
}
/* call arch's memory hotadd */
- ret = arch_add_memory(nid, start, size, true);
+ ret = arch_add_memory(nid, start, size, NULL, true);
if (ret < 0)
goto error;
@@ -1888,7 +1885,7 @@ void __ref remove_memory(int nid, u64 start, u64 size)
memblock_free(start, size);
memblock_remove(start, size);
- arch_remove_memory(start, size);
+ arch_remove_memory(start, size, NULL);
try_offline_node(nid);
diff --git a/mm/mempool.c b/mm/mempool.c
index 7d8c5a0010a2..5c9dce34719b 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -103,10 +103,10 @@ static inline void poison_element(mempool_t *pool, void *element)
}
#endif /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */
-static void kasan_poison_element(mempool_t *pool, void *element)
+static __always_inline void kasan_poison_element(mempool_t *pool, void *element)
{
if (pool->alloc == mempool_alloc_slab || pool->alloc == mempool_kmalloc)
- kasan_poison_kfree(element);
+ kasan_poison_kfree(element, _RET_IP_);
if (pool->alloc == mempool_alloc_pages)
kasan_free_pages(element, (unsigned long)pool->pool_data);
}
@@ -119,7 +119,7 @@ static void kasan_unpoison_element(mempool_t *pool, void *element, gfp_t flags)
kasan_alloc_pages(element, (unsigned long)pool->pool_data);
}
-static void add_element(mempool_t *pool, void *element)
+static __always_inline void add_element(mempool_t *pool, void *element)
{
BUG_ON(pool->curr_nr >= pool->min_nr);
poison_element(pool, element);
diff --git a/mm/mlock.c b/mm/mlock.c
index f7f54fd2e13f..79398200e423 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -157,7 +157,7 @@ static void __munlock_isolation_failed(struct page *page)
/**
* munlock_vma_page - munlock a vma page
- * @page - page to be unlocked, either a normal page or THP page head
+ * @page: page to be unlocked, either a normal page or THP page head
*
* returns the size of the page as a page mask (0 for normal page,
* HPAGE_PMD_NR - 1 for THP head page)
diff --git a/mm/nommu.c b/mm/nommu.c
index 4b9864b17cb0..ebb6e618dade 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1836,7 +1836,7 @@ int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
}
/**
- * @access_remote_vm - access another process' address space
+ * access_remote_vm - access another process' address space
* @mm: the mm_struct of the target address space
* @addr: start address to access
* @buf: source or destination buffer
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c7dd9c86e353..81e18ceef579 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5321,9 +5321,9 @@ void __ref build_all_zonelists(pg_data_t *pgdat)
* done. Non-atomic initialization, single-pass.
*/
void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
- unsigned long start_pfn, enum memmap_context context)
+ unsigned long start_pfn, enum memmap_context context,
+ struct vmem_altmap *altmap)
{
- struct vmem_altmap *altmap = to_vmem_altmap(__pfn_to_phys(start_pfn));
unsigned long end_pfn = start_pfn + size;
pg_data_t *pgdat = NODE_DATA(nid);
unsigned long pfn;
@@ -5429,7 +5429,7 @@ static void __meminit zone_init_free_lists(struct zone *zone)
#ifndef __HAVE_ARCH_MEMMAP_INIT
#define memmap_init(size, nid, zone, start_pfn) \
- memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY)
+ memmap_init_zone((size), (nid), (zone), (start_pfn), MEMMAP_EARLY, NULL)
#endif
static int zone_batchsize(struct zone *zone)
diff --git a/mm/pagewalk.c b/mm/pagewalk.c
index 23a3e415ac2c..8d2da5dec1e0 100644
--- a/mm/pagewalk.c
+++ b/mm/pagewalk.c
@@ -265,6 +265,7 @@ static int __walk_page_range(unsigned long start, unsigned long end,
* pte_entry(), and/or hugetlb_entry(). If you don't set up for some of these
* callbacks, the associated entries/pages are just ignored.
* The return values of these callbacks are commonly defined like below:
+ *
* - 0 : succeeded to handle the current entry, and if you don't reach the
* end address yet, continue to walk.
* - >0 : succeeded to handle the current entry, and return to the caller
diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c
index 8973cd231ece..a447092d4635 100644
--- a/mm/process_vm_access.c
+++ b/mm/process_vm_access.c
@@ -25,7 +25,7 @@
/**
* process_vm_rw_pages - read/write pages from task specified
* @pages: array of pointers to pages we want to copy
- * @start_offset: offset in page to start copying from/to
+ * @offset: offset in page to start copying from/to
* @len: number of bytes to copy
* @iter: where to copy to/from locally
* @vm_write: 0 means copy from, 1 means copy to
@@ -147,6 +147,7 @@ static int process_vm_rw_single_vec(unsigned long addr,
* @riovcnt: size of rvec array
* @flags: currently unused
* @vm_write: 0 if reading from other process, 1 if writing to other process
+ *
* Returns the number of bytes read/written or error code. May
* return less bytes than expected if an error occurs during the copying
* process.
@@ -197,11 +198,7 @@ static ssize_t process_vm_rw_core(pid_t pid, struct iov_iter *iter,
}
/* Get process information */
- rcu_read_lock();
- task = find_task_by_vpid(pid);
- if (task)
- get_task_struct(task);
- rcu_read_unlock();
+ task = find_get_task_by_vpid(pid);
if (!task) {
rc = -ESRCH;
goto free_proc_pages;
@@ -253,6 +250,7 @@ free_proc_pages:
* @riovcnt: size of rvec array
* @flags: currently unused
* @vm_write: 0 if reading from other process, 1 if writing to other process
+ *
* Returns the number of bytes read/written or error code. May
* return less bytes than expected if an error occurs during the copying
* process.
diff --git a/mm/slab.c b/mm/slab.c
index cd86f15071ad..324446621b3e 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3478,11 +3478,11 @@ free_done:
* Release an obj back to its cache. If the obj has a constructed state, it must
* be in this state _before_ it is released. Called with disabled ints.
*/
-static inline void __cache_free(struct kmem_cache *cachep, void *objp,
- unsigned long caller)
+static __always_inline void __cache_free(struct kmem_cache *cachep, void *objp,
+ unsigned long caller)
{
/* Put the object into the quarantine, don't touch it for now. */
- if (kasan_slab_free(cachep, objp))
+ if (kasan_slab_free(cachep, objp, _RET_IP_))
return;
___cache_free(cachep, objp, caller);
diff --git a/mm/slub.c b/mm/slub.c
index cc71176c6eef..e381728a3751 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1356,13 +1356,13 @@ static inline void kmalloc_large_node_hook(void *ptr, size_t size, gfp_t flags)
kasan_kmalloc_large(ptr, size, flags);
}
-static inline void kfree_hook(const void *x)
+static __always_inline void kfree_hook(void *x)
{
kmemleak_free(x);
- kasan_kfree_large(x);
+ kasan_kfree_large(x, _RET_IP_);
}
-static inline void *slab_free_hook(struct kmem_cache *s, void *x)
+static __always_inline void *slab_free_hook(struct kmem_cache *s, void *x)
{
void *freeptr;
@@ -1390,7 +1390,7 @@ static inline void *slab_free_hook(struct kmem_cache *s, void *x)
* kasan_slab_free() may put x into memory quarantine, delaying its
* reuse. In this case the object's freelist pointer is changed.
*/
- kasan_slab_free(s, x);
+ kasan_slab_free(s, x, _RET_IP_);
return freeptr;
}
@@ -3910,7 +3910,7 @@ void kfree(const void *x)
page = virt_to_head_page(x);
if (unlikely(!PageSlab(page))) {
BUG_ON(!PageCompound(page));
- kfree_hook(x);
+ kfree_hook(object);
__free_pages(page, compound_order(page));
return;
}
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
index 17acf01791fa..bd0276d5f66b 100644
--- a/mm/sparse-vmemmap.c
+++ b/mm/sparse-vmemmap.c
@@ -74,7 +74,7 @@ void * __meminit vmemmap_alloc_block(unsigned long size, int node)
}
/* need to make sure size is all the same during early stage */
-static void * __meminit alloc_block_buf(unsigned long size, int node)
+void * __meminit vmemmap_alloc_block_buf(unsigned long size, int node)
{
void *ptr;
@@ -107,33 +107,16 @@ static unsigned long __meminit vmem_altmap_nr_free(struct vmem_altmap *altmap)
}
/**
- * vmem_altmap_alloc - allocate pages from the vmem_altmap reservation
- * @altmap - reserved page pool for the allocation
- * @nr_pfns - size (in pages) of the allocation
+ * altmap_alloc_block_buf - allocate pages from the device page map
+ * @altmap: device page map
+ * @size: size (in bytes) of the allocation
*
- * Allocations are aligned to the size of the request
+ * Allocations are aligned to the size of the request.
*/
-static unsigned long __meminit vmem_altmap_alloc(struct vmem_altmap *altmap,
- unsigned long nr_pfns)
-{
- unsigned long pfn = vmem_altmap_next_pfn(altmap);
- unsigned long nr_align;
-
- nr_align = 1UL << find_first_bit(&nr_pfns, BITS_PER_LONG);
- nr_align = ALIGN(pfn, nr_align) - pfn;
-
- if (nr_pfns + nr_align > vmem_altmap_nr_free(altmap))
- return ULONG_MAX;
- altmap->alloc += nr_pfns;
- altmap->align += nr_align;
- return pfn + nr_align;
-}
-
-static void * __meminit altmap_alloc_block_buf(unsigned long size,
+void * __meminit altmap_alloc_block_buf(unsigned long size,
struct vmem_altmap *altmap)
{
- unsigned long pfn, nr_pfns;
- void *ptr;
+ unsigned long pfn, nr_pfns, nr_align;
if (size & ~PAGE_MASK) {
pr_warn_once("%s: allocations must be multiple of PAGE_SIZE (%ld)\n",
@@ -141,25 +124,20 @@ static void * __meminit altmap_alloc_block_buf(unsigned long size,
return NULL;
}
+ pfn = vmem_altmap_next_pfn(altmap);
nr_pfns = size >> PAGE_SHIFT;
- pfn = vmem_altmap_alloc(altmap, nr_pfns);
- if (pfn < ULONG_MAX)
- ptr = __va(__pfn_to_phys(pfn));
- else
- ptr = NULL;
- pr_debug("%s: pfn: %#lx alloc: %ld align: %ld nr: %#lx\n",
- __func__, pfn, altmap->alloc, altmap->align, nr_pfns);
+ nr_align = 1UL << find_first_bit(&nr_pfns, BITS_PER_LONG);
+ nr_align = ALIGN(pfn, nr_align) - pfn;
+ if (nr_pfns + nr_align > vmem_altmap_nr_free(altmap))
+ return NULL;
- return ptr;
-}
+ altmap->alloc += nr_pfns;
+ altmap->align += nr_align;
+ pfn += nr_align;
-/* need to make sure size is all the same during early stage */
-void * __meminit __vmemmap_alloc_block_buf(unsigned long size, int node,
- struct vmem_altmap *altmap)
-{
- if (altmap)
- return altmap_alloc_block_buf(size, altmap);
- return alloc_block_buf(size, node);
+ pr_debug("%s: pfn: %#lx alloc: %ld align: %ld nr: %#lx\n",
+ __func__, pfn, altmap->alloc, altmap->align, nr_pfns);
+ return __va(__pfn_to_phys(pfn));
}
void __meminit vmemmap_verify(pte_t *pte, int node,
@@ -178,7 +156,7 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node)
pte_t *pte = pte_offset_kernel(pmd, addr);
if (pte_none(*pte)) {
pte_t entry;
- void *p = alloc_block_buf(PAGE_SIZE, node);
+ void *p = vmemmap_alloc_block_buf(PAGE_SIZE, node);
if (!p)
return NULL;
entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL);
@@ -278,7 +256,8 @@ int __meminit vmemmap_populate_basepages(unsigned long start,
return 0;
}
-struct page * __meminit sparse_mem_map_populate(unsigned long pnum, int nid)
+struct page * __meminit sparse_mem_map_populate(unsigned long pnum, int nid,
+ struct vmem_altmap *altmap)
{
unsigned long start;
unsigned long end;
@@ -288,7 +267,7 @@ struct page * __meminit sparse_mem_map_populate(unsigned long pnum, int nid)
start = (unsigned long)map;
end = (unsigned long)(map + PAGES_PER_SECTION);
- if (vmemmap_populate(start, end, nid))
+ if (vmemmap_populate(start, end, nid, altmap))
return NULL;
return map;
@@ -318,7 +297,7 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
if (!present_section_nr(pnum))
continue;
- map_map[pnum] = sparse_mem_map_populate(pnum, nodeid);
+ map_map[pnum] = sparse_mem_map_populate(pnum, nodeid, NULL);
if (map_map[pnum])
continue;
ms = __nr_to_section(pnum);
diff --git a/mm/sparse.c b/mm/sparse.c
index 6b8b5e91ceef..7af5e7a92528 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -421,7 +421,8 @@ static void __init sparse_early_usemaps_alloc_node(void *data,
}
#ifndef CONFIG_SPARSEMEM_VMEMMAP
-struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid)
+struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid,
+ struct vmem_altmap *altmap)
{
struct page *map;
unsigned long size;
@@ -476,7 +477,7 @@ void __init sparse_mem_maps_populate_node(struct page **map_map,
if (!present_section_nr(pnum))
continue;
- map_map[pnum] = sparse_mem_map_populate(pnum, nodeid);
+ map_map[pnum] = sparse_mem_map_populate(pnum, nodeid, NULL);
if (map_map[pnum])
continue;
ms = __nr_to_section(pnum);
@@ -504,7 +505,7 @@ static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
struct mem_section *ms = __nr_to_section(pnum);
int nid = sparse_early_nid(ms);
- map = sparse_mem_map_populate(pnum, nid);
+ map = sparse_mem_map_populate(pnum, nid, NULL);
if (map)
return map;
@@ -682,17 +683,19 @@ void offline_mem_sections(unsigned long start_pfn, unsigned long end_pfn)
#endif
#ifdef CONFIG_SPARSEMEM_VMEMMAP
-static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid)
+static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
+ struct vmem_altmap *altmap)
{
/* This will make the necessary allocations eventually. */
- return sparse_mem_map_populate(pnum, nid);
+ return sparse_mem_map_populate(pnum, nid, altmap);
}
-static void __kfree_section_memmap(struct page *memmap)
+static void __kfree_section_memmap(struct page *memmap,
+ struct vmem_altmap *altmap)
{
unsigned long start = (unsigned long)memmap;
unsigned long end = (unsigned long)(memmap + PAGES_PER_SECTION);
- vmemmap_free(start, end);
+ vmemmap_free(start, end, altmap);
}
#ifdef CONFIG_MEMORY_HOTREMOVE
static void free_map_bootmem(struct page *memmap)
@@ -700,7 +703,7 @@ static void free_map_bootmem(struct page *memmap)
unsigned long start = (unsigned long)memmap;
unsigned long end = (unsigned long)(memmap + PAGES_PER_SECTION);
- vmemmap_free(start, end);
+ vmemmap_free(start, end, NULL);
}
#endif /* CONFIG_MEMORY_HOTREMOVE */
#else
@@ -725,12 +728,14 @@ got_map_ptr:
return ret;
}
-static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid)
+static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
+ struct vmem_altmap *altmap)
{
return __kmalloc_section_memmap();
}
-static void __kfree_section_memmap(struct page *memmap)
+static void __kfree_section_memmap(struct page *memmap,
+ struct vmem_altmap *altmap)
{
if (is_vmalloc_addr(memmap))
vfree(memmap);
@@ -777,7 +782,8 @@ static void free_map_bootmem(struct page *memmap)
* set. If this is <=0, then that means that the passed-in
* map was not consumed and must be freed.
*/
-int __meminit sparse_add_one_section(struct pglist_data *pgdat, unsigned long start_pfn)
+int __meminit sparse_add_one_section(struct pglist_data *pgdat,
+ unsigned long start_pfn, struct vmem_altmap *altmap)
{
unsigned long section_nr = pfn_to_section_nr(start_pfn);
struct mem_section *ms;
@@ -793,12 +799,12 @@ int __meminit sparse_add_one_section(struct pglist_data *pgdat, unsigned long st
ret = sparse_index_init(section_nr, pgdat->node_id);
if (ret < 0 && ret != -EEXIST)
return ret;
- memmap = kmalloc_section_memmap(section_nr, pgdat->node_id);
+ memmap = kmalloc_section_memmap(section_nr, pgdat->node_id, altmap);
if (!memmap)
return -ENOMEM;
usemap = __kmalloc_section_usemap();
if (!usemap) {
- __kfree_section_memmap(memmap);
+ __kfree_section_memmap(memmap, altmap);
return -ENOMEM;
}
@@ -820,7 +826,7 @@ out:
pgdat_resize_unlock(pgdat, &flags);
if (ret <= 0) {
kfree(usemap);
- __kfree_section_memmap(memmap);
+ __kfree_section_memmap(memmap, altmap);
}
return ret;
}
@@ -847,7 +853,8 @@ static inline void clear_hwpoisoned_pages(struct page *memmap, int nr_pages)
}
#endif
-static void free_section_usemap(struct page *memmap, unsigned long *usemap)
+static void free_section_usemap(struct page *memmap, unsigned long *usemap,
+ struct vmem_altmap *altmap)
{
struct page *usemap_page;
@@ -861,7 +868,7 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
if (PageSlab(usemap_page) || PageCompound(usemap_page)) {
kfree(usemap);
if (memmap)
- __kfree_section_memmap(memmap);
+ __kfree_section_memmap(memmap, altmap);
return;
}
@@ -875,7 +882,7 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
}
void sparse_remove_one_section(struct zone *zone, struct mem_section *ms,
- unsigned long map_offset)
+ unsigned long map_offset, struct vmem_altmap *altmap)
{
struct page *memmap = NULL;
unsigned long *usemap = NULL, flags;
@@ -893,7 +900,7 @@ void sparse_remove_one_section(struct zone *zone, struct mem_section *ms,
clear_hwpoisoned_pages(memmap + map_offset,
PAGES_PER_SECTION - map_offset);
- free_section_usemap(memmap, usemap);
+ free_section_usemap(memmap, usemap, altmap);
}
#endif /* CONFIG_MEMORY_HOTREMOVE */
#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/mm/swap.c b/mm/swap.c
index 10568b1548d4..567a7b96e41d 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -913,11 +913,11 @@ EXPORT_SYMBOL(__pagevec_lru_add);
* @pvec: Where the resulting entries are placed
* @mapping: The address_space to search
* @start: The starting entry index
- * @nr_entries: The maximum number of entries
+ * @nr_pages: The maximum number of pages
* @indices: The cache indices corresponding to the entries in @pvec
*
* pagevec_lookup_entries() will search for and return a group of up
- * to @nr_entries pages and shadow entries in the mapping. All
+ * to @nr_pages pages and shadow entries in the mapping. All
* entries are placed in @pvec. pagevec_lookup_entries() takes a
* reference against actual pages in @pvec.
*
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 81192701964d..39791b81ede7 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -16,7 +16,6 @@
#include <linux/userfaultfd_k.h>
#include <linux/mmu_notifier.h>
#include <linux/hugetlb.h>
-#include <linux/pagemap.h>
#include <linux/shmem_fs.h>
#include <asm/tlbflush.h>
#include "internal.h"
diff --git a/mm/vmscan.c b/mm/vmscan.c
index fdd3fc6be862..444749669187 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1595,6 +1595,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
* found will be decremented.
*
* Restrictions:
+ *
* (1) Must be called with an elevated refcount on the page. This is a
* fundamentnal difference from isolate_lru_pages (which is called
* without a stable reference).
diff --git a/mm/z3fold.c b/mm/z3fold.c
index 39e19125d6a0..d589d318727f 100644
--- a/mm/z3fold.c
+++ b/mm/z3fold.c
@@ -769,7 +769,7 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
/**
* z3fold_reclaim_page() - evicts allocations from a pool page and frees it
* @pool: pool from which a page will attempt to be evicted
- * @retires: number of pages on the LRU list for which eviction will
+ * @retries: number of pages on the LRU list for which eviction will
* be attempted before failing
*
* z3fold reclaim is different from normal system reclaim in that it is done
@@ -779,7 +779,7 @@ static void z3fold_free(struct z3fold_pool *pool, unsigned long handle)
* z3fold and the user, however.
*
* To avoid these, this is how z3fold_reclaim_page() should be called:
-
+ *
* The user detects a page should be reclaimed and calls z3fold_reclaim_page().
* z3fold_reclaim_page() will remove a z3fold page from the pool LRU list and
* call the user-defined eviction handler with the pool and handle as
diff --git a/mm/zbud.c b/mm/zbud.c
index b42322e50f63..28458f7d1e84 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -466,7 +466,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
/**
* zbud_reclaim_page() - evicts allocations from a pool page and frees it
* @pool: pool from which a page will attempt to be evicted
- * @retires: number of pages on the LRU list for which eviction will
+ * @retries: number of pages on the LRU list for which eviction will
* be attempted before failing
*
* zbud reclaim is different from normal system reclaim in that the reclaim is
@@ -476,7 +476,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
* the user, however.
*
* To avoid these, this is how zbud_reclaim_page() should be called:
-
+ *
* The user detects a page should be reclaimed and calls zbud_reclaim_page().
* zbud_reclaim_page() will remove a zbud page from the pool LRU list and call
* the user-defined eviction handler with the pool and handle as arguments.
diff --git a/mm/zpool.c b/mm/zpool.c
index e1e7aa6d1d06..f8cb83e7699b 100644
--- a/mm/zpool.c
+++ b/mm/zpool.c
@@ -101,7 +101,7 @@ static void zpool_put_driver(struct zpool_driver *driver)
/**
* zpool_has_pool() - Check if the pool driver is available
- * @type The type of the zpool to check (e.g. zbud, zsmalloc)
+ * @type: The type of the zpool to check (e.g. zbud, zsmalloc)
*
* This checks if the @type pool driver is available. This will try to load
* the requested module, if needed, but there is no guarantee the module will
@@ -136,10 +136,10 @@ EXPORT_SYMBOL(zpool_has_pool);
/**
* zpool_create_pool() - Create a new zpool
- * @type The type of the zpool to create (e.g. zbud, zsmalloc)
- * @name The name of the zpool (e.g. zram0, zswap)
- * @gfp The GFP flags to use when allocating the pool.
- * @ops The optional ops callback.
+ * @type: The type of the zpool to create (e.g. zbud, zsmalloc)
+ * @name: The name of the zpool (e.g. zram0, zswap)
+ * @gfp: The GFP flags to use when allocating the pool.
+ * @ops: The optional ops callback.
*
* This creates a new zpool of the specified type. The gfp flags will be
* used when allocating memory, if the implementation supports it. If the
@@ -201,7 +201,7 @@ struct zpool *zpool_create_pool(const char *type, const char *name, gfp_t gfp,
/**
* zpool_destroy_pool() - Destroy a zpool
- * @pool The zpool to destroy.
+ * @zpool: The zpool to destroy.
*
* Implementations must guarantee this to be thread-safe,
* however only when destroying different pools. The same
@@ -224,7 +224,7 @@ void zpool_destroy_pool(struct zpool *zpool)
/**
* zpool_get_type() - Get the type of the zpool
- * @pool The zpool to check
+ * @zpool: The zpool to check
*
* This returns the type of the pool.
*
@@ -239,10 +239,10 @@ const char *zpool_get_type(struct zpool *zpool)
/**
* zpool_malloc() - Allocate memory
- * @pool The zpool to allocate from.
- * @size The amount of memory to allocate.
- * @gfp The GFP flags to use when allocating memory.
- * @handle Pointer to the handle to set
+ * @zpool: The zpool to allocate from.
+ * @size: The amount of memory to allocate.
+ * @gfp: The GFP flags to use when allocating memory.
+ * @handle: Pointer to the handle to set
*
* This allocates the requested amount of memory from the pool.
* The gfp flags will be used when allocating memory, if the
@@ -261,8 +261,8 @@ int zpool_malloc(struct zpool *zpool, size_t size, gfp_t gfp,
/**
* zpool_free() - Free previously allocated memory
- * @pool The zpool that allocated the memory.
- * @handle The handle to the memory to free.
+ * @zpool: The zpool that allocated the memory.
+ * @handle: The handle to the memory to free.
*
* This frees previously allocated memory. This does not guarantee
* that the pool will actually free memory, only that the memory
@@ -280,9 +280,9 @@ void zpool_free(struct zpool *zpool, unsigned long handle)
/**
* zpool_shrink() - Shrink the pool size
- * @pool The zpool to shrink.
- * @pages The number of pages to shrink the pool.
- * @reclaimed The number of pages successfully evicted.
+ * @zpool: The zpool to shrink.
+ * @pages: The number of pages to shrink the pool.
+ * @reclaimed: The number of pages successfully evicted.
*
* This attempts to shrink the actual memory size of the pool
* by evicting currently used handle(s). If the pool was
@@ -304,11 +304,11 @@ int zpool_shrink(struct zpool *zpool, unsigned int pages,
/**
* zpool_map_handle() - Map a previously allocated handle into memory
- * @pool The zpool that the handle was allocated from
- * @handle The handle to map
- * @mm How the memory should be mapped
+ * @zpool: The zpool that the handle was allocated from
+ * @handle: The handle to map
+ * @mapmode: How the memory should be mapped
*
- * This maps a previously allocated handle into memory. The @mm
+ * This maps a previously allocated handle into memory. The @mapmode
* param indicates to the implementation how the memory will be
* used, i.e. read-only, write-only, read-write. If the
* implementation does not support it, the memory will be treated
@@ -332,8 +332,8 @@ void *zpool_map_handle(struct zpool *zpool, unsigned long handle,
/**
* zpool_unmap_handle() - Unmap a previously mapped handle
- * @pool The zpool that the handle was allocated from
- * @handle The handle to unmap
+ * @zpool: The zpool that the handle was allocated from
+ * @handle: The handle to unmap
*
* This unmaps a previously mapped handle. Any locks or other
* actions that the implementation took in zpool_map_handle()
@@ -347,7 +347,7 @@ void zpool_unmap_handle(struct zpool *zpool, unsigned long handle)
/**
* zpool_get_total_size() - The total size of the pool
- * @pool The zpool to check
+ * @zpool: The zpool to check
*
* This returns the total size in bytes of the pool.
*
diff --git a/net/bluetooth/hci_debugfs.c b/net/bluetooth/hci_debugfs.c
index 57403bd567d0..418b76e557b0 100644
--- a/net/bluetooth/hci_debugfs.c
+++ b/net/bluetooth/hci_debugfs.c
@@ -90,19 +90,6 @@ static int __name ## _show(struct seq_file *f, void *ptr) \
\
DEFINE_SHOW_ATTRIBUTE(__name)
-#define DEFINE_SHOW_ATTRIBUTE(__name) \
-static int __name ## _open(struct inode *inode, struct file *file) \
-{ \
- return single_open(file, __name ## _show, inode->i_private); \
-} \
- \
-static const struct file_operations __name ## _fops = { \
- .open = __name ## _open, \
- .read = seq_read, \
- .llseek = seq_lseek, \
- .release = single_release, \
-} \
-
static int features_show(struct seq_file *f, void *ptr)
{
struct hci_dev *hdev = f->private;
diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index a86e6687026e..2ced48662c1f 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -151,6 +151,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
{
u32 size = kattr->test.data_size_in;
u32 repeat = kattr->test.repeat;
+ struct netdev_rx_queue *rxqueue;
struct xdp_buff xdp = {};
u32 retval, duration;
void *data;
@@ -165,6 +166,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr,
xdp.data_meta = xdp.data;
xdp.data_end = xdp.data + size;
+ rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0);
+ xdp.rxq = &rxqueue->xdp_rxq;
+
retval = bpf_test_run(prog, &xdp, repeat, &duration);
if (xdp.data != data + XDP_PACKET_HEADROOM + NET_IP_ALIGN)
size = xdp.data_end - xdp.data;
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 107b122c8969..494e6a5d7306 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -616,18 +616,15 @@ static int load_link_ksettings_from_user(struct ethtool_link_ksettings *to,
return -EFAULT;
memcpy(&to->base, &link_usettings.base, sizeof(to->base));
- bitmap_from_u32array(to->link_modes.supported,
- __ETHTOOL_LINK_MODE_MASK_NBITS,
- link_usettings.link_modes.supported,
- __ETHTOOL_LINK_MODE_MASK_NU32);
- bitmap_from_u32array(to->link_modes.advertising,
- __ETHTOOL_LINK_MODE_MASK_NBITS,
- link_usettings.link_modes.advertising,
- __ETHTOOL_LINK_MODE_MASK_NU32);
- bitmap_from_u32array(to->link_modes.lp_advertising,
- __ETHTOOL_LINK_MODE_MASK_NBITS,
- link_usettings.link_modes.lp_advertising,
- __ETHTOOL_LINK_MODE_MASK_NU32);
+ bitmap_from_arr32(to->link_modes.supported,
+ link_usettings.link_modes.supported,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ bitmap_from_arr32(to->link_modes.advertising,
+ link_usettings.link_modes.advertising,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ bitmap_from_arr32(to->link_modes.lp_advertising,
+ link_usettings.link_modes.lp_advertising,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
return 0;
}
@@ -643,18 +640,15 @@ store_link_ksettings_for_user(void __user *to,
struct ethtool_link_usettings link_usettings;
memcpy(&link_usettings.base, &from->base, sizeof(link_usettings));
- bitmap_to_u32array(link_usettings.link_modes.supported,
- __ETHTOOL_LINK_MODE_MASK_NU32,
- from->link_modes.supported,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
- bitmap_to_u32array(link_usettings.link_modes.advertising,
- __ETHTOOL_LINK_MODE_MASK_NU32,
- from->link_modes.advertising,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
- bitmap_to_u32array(link_usettings.link_modes.lp_advertising,
- __ETHTOOL_LINK_MODE_MASK_NU32,
- from->link_modes.lp_advertising,
- __ETHTOOL_LINK_MODE_MASK_NBITS);
+ bitmap_to_arr32(link_usettings.link_modes.supported,
+ from->link_modes.supported,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ bitmap_to_arr32(link_usettings.link_modes.advertising,
+ from->link_modes.advertising,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
+ bitmap_to_arr32(link_usettings.link_modes.lp_advertising,
+ from->link_modes.lp_advertising,
+ __ETHTOOL_LINK_MODE_MASK_NBITS);
if (copy_to_user(to, &link_usettings, sizeof(link_usettings)))
return -EFAULT;
@@ -2358,10 +2352,8 @@ static int ethtool_get_per_queue_coalesce(struct net_device *dev,
useraddr += sizeof(*per_queue_opt);
- bitmap_from_u32array(queue_mask,
- MAX_NUM_QUEUE,
- per_queue_opt->queue_mask,
- DIV_ROUND_UP(MAX_NUM_QUEUE, 32));
+ bitmap_from_arr32(queue_mask, per_queue_opt->queue_mask,
+ MAX_NUM_QUEUE);
for_each_set_bit(bit, queue_mask, MAX_NUM_QUEUE) {
struct ethtool_coalesce coalesce = { .cmd = ETHTOOL_GCOALESCE };
@@ -2393,10 +2385,7 @@ static int ethtool_set_per_queue_coalesce(struct net_device *dev,
useraddr += sizeof(*per_queue_opt);
- bitmap_from_u32array(queue_mask,
- MAX_NUM_QUEUE,
- per_queue_opt->queue_mask,
- DIV_ROUND_UP(MAX_NUM_QUEUE, 32));
+ bitmap_from_arr32(queue_mask, per_queue_opt->queue_mask, MAX_NUM_QUEUE);
n_queue = bitmap_weight(queue_mask, MAX_NUM_QUEUE);
tmp = backup = kmalloc_array(n_queue, sizeof(*backup), GFP_KERNEL);
if (!backup)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 6ec670fbbbdd..45d97e9b2759 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -261,6 +261,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
struct ip_tunnel_net *itn;
struct ip_tunnel *tunnel;
const struct iphdr *iph;
+ struct erspan_md2 *md2;
int ver;
int len;
@@ -313,21 +314,14 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
return PACKET_REJECT;
md = ip_tunnel_info_opts(&tun_dst->u.tun_info);
- memcpy(md, pkt_md, sizeof(*md));
md->version = ver;
+ md2 = &md->u.md2;
+ memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
+ ERSPAN_V2_MDSIZE);
info = &tun_dst->u.tun_info;
info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
info->options_len = sizeof(*md);
- } else {
- tunnel->erspan_ver = ver;
- if (ver == 1) {
- tunnel->index = ntohl(pkt_md->u.index);
- } else {
- tunnel->dir = pkt_md->u.md2.dir;
- tunnel->hwid = get_hwid(&pkt_md->u.md2);
- }
-
}
skb_reset_mac_header(skb);
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 05f070e123e4..3c353125546d 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -505,6 +505,7 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
struct erspan_base_hdr *ershdr;
struct erspan_metadata *pkt_md;
const struct ipv6hdr *ipv6h;
+ struct erspan_md2 *md2;
struct ip6_tnl *tunnel;
u8 ver;
@@ -551,24 +552,16 @@ static int ip6erspan_rcv(struct sk_buff *skb, int gre_hdr_len,
info = &tun_dst->u.tun_info;
md = ip_tunnel_info_opts(info);
-
- memcpy(md, pkt_md, sizeof(*md));
md->version = ver;
+ md2 = &md->u.md2;
+ memcpy(md2, pkt_md, ver == 1 ? ERSPAN_V1_MDSIZE :
+ ERSPAN_V2_MDSIZE);
info->key.tun_flags |= TUNNEL_ERSPAN_OPT;
info->options_len = sizeof(*md);
ip6_tnl_rcv(tunnel, skb, tpi, tun_dst, log_ecn_error);
} else {
- tunnel->parms.erspan_ver = ver;
-
- if (ver == 1) {
- tunnel->parms.index = ntohl(pkt_md->u.index);
- } else {
- tunnel->parms.dir = pkt_md->u.md2.dir;
- tunnel->parms.hwid = get_hwid(&pkt_md->u.md2);
- }
-
ip6_tnl_rcv(tunnel, skb, tpi, NULL, log_ecn_error);
}
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 6a5d0e39bb87..9b9d2ff01b35 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -65,10 +65,10 @@
#include <net/ip6_checksum.h>
/* Ensure that we have struct in6_addr aligned on 32bit word. */
-static void *__mld2_query_bugs[] __attribute__((__unused__)) = {
- BUILD_BUG_ON_NULL(offsetof(struct mld2_query, mld2q_srcs) % 4),
- BUILD_BUG_ON_NULL(offsetof(struct mld2_report, mld2r_grec) % 4),
- BUILD_BUG_ON_NULL(offsetof(struct mld2_grec, grec_mca) % 4)
+static int __mld2_query_bugs[] __attribute__((__unused__)) = {
+ BUILD_BUG_ON_ZERO(offsetof(struct mld2_query, mld2q_srcs) % 4),
+ BUILD_BUG_ON_ZERO(offsetof(struct mld2_report, mld2r_grec) % 4),
+ BUILD_BUG_ON_ZERO(offsetof(struct mld2_grec, grec_mca) % 4)
};
static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
diff --git a/net/rds/ib.c b/net/rds/ib.c
index b2a5067b4afe..ff0c98096af1 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -345,7 +345,8 @@ static int rds_ib_laddr_check(struct net *net, __be32 addr)
/* Create a CMA ID and try to bind it. This catches both
* IB and iWARP capable NICs.
*/
- cm_id = rdma_create_id(&init_net, NULL, NULL, RDMA_PS_TCP, IB_QPT_RC);
+ cm_id = rdma_create_id(&init_net, rds_rdma_cm_event_handler,
+ NULL, RDMA_PS_TCP, IB_QPT_RC);
if (IS_ERR(cm_id))
return PTR_ERR(cm_id);
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index e3c5e390ec23..6311a548046b 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -398,10 +398,12 @@ static int u32_init(struct tcf_proto *tp)
static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n,
bool free_pf)
{
+ struct tc_u_hnode *ht = rtnl_dereference(n->ht_down);
+
tcf_exts_destroy(&n->exts);
tcf_exts_put_net(&n->exts);
- if (n->ht_down)
- n->ht_down->refcnt--;
+ if (ht && --ht->refcnt == 0)
+ kfree(ht);
#ifdef CONFIG_CLS_U32_PERF
if (free_pf)
free_percpu(n->pf);
@@ -659,16 +661,15 @@ static void u32_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
hlist_del(&tp_c->hnode);
- for (ht = rtnl_dereference(tp_c->hlist);
- ht;
- ht = rtnl_dereference(ht->next)) {
- ht->refcnt--;
- u32_clear_hnode(tp, ht, extack);
- }
-
while ((ht = rtnl_dereference(tp_c->hlist)) != NULL) {
+ u32_clear_hnode(tp, ht, extack);
RCU_INIT_POINTER(tp_c->hlist, ht->next);
- kfree_rcu(ht, rcu);
+
+ /* u32_destroy_key() will later free ht for us, if it's
+ * still referenced by some knode
+ */
+ if (--ht->refcnt == 0)
+ kfree_rcu(ht, rcu);
}
idr_destroy(&tp_c->handle_idr);
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 5d4c15bf66d2..e35d4f73d2df 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -326,8 +326,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
bdst = ip6_dst_lookup_flow(sk, fl6, final_p);
- if (!IS_ERR(bdst) &&
- ipv6_chk_addr(dev_net(bdst->dev),
+ if (IS_ERR(bdst))
+ continue;
+
+ if (ipv6_chk_addr(dev_net(bdst->dev),
&laddr->a.v6.sin6_addr, bdst->dev, 1)) {
if (!IS_ERR_OR_NULL(dst))
dst_release(dst);
@@ -336,8 +338,10 @@ static void sctp_v6_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
}
bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a);
- if (matchlen > bmatchlen)
+ if (matchlen > bmatchlen) {
+ dst_release(bdst);
continue;
+ }
if (!IS_ERR_OR_NULL(dst))
dst_release(dst);
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 6a38c2503649..91813e686c67 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -514,22 +514,20 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr,
if (IS_ERR(rt))
continue;
- if (!dst)
- dst = &rt->dst;
-
/* Ensure the src address belongs to the output
* interface.
*/
odev = __ip_dev_find(sock_net(sk), laddr->a.v4.sin_addr.s_addr,
false);
if (!odev || odev->ifindex != fl4->flowi4_oif) {
- if (&rt->dst != dst)
+ if (!dst)
+ dst = &rt->dst;
+ else
dst_release(&rt->dst);
continue;
}
- if (dst != &rt->dst)
- dst_release(dst);
+ dst_release(dst);
dst = &rt->dst;
break;
}
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 64335bb94f9f..ec3fc8d88e87 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -45,7 +45,7 @@ hostprogs-y += xdp_rxq_info
hostprogs-y += syscall_tp
# Libbpf dependencies
-LIBBPF := ../../tools/lib/bpf/bpf.o
+LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o
CGROUP_HELPERS := ../../tools/testing/selftests/bpf/cgroup_helpers.o
test_lru_dist-objs := test_lru_dist.o $(LIBBPF)
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 242631aa4ea2..69806d74fa53 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -695,105 +695,3 @@ struct ksym *ksym_search(long key)
return &syms[0];
}
-int set_link_xdp_fd(int ifindex, int fd, __u32 flags)
-{
- struct sockaddr_nl sa;
- int sock, seq = 0, len, ret = -1;
- char buf[4096];
- struct nlattr *nla, *nla_xdp;
- struct {
- struct nlmsghdr nh;
- struct ifinfomsg ifinfo;
- char attrbuf[64];
- } req;
- struct nlmsghdr *nh;
- struct nlmsgerr *err;
-
- memset(&sa, 0, sizeof(sa));
- sa.nl_family = AF_NETLINK;
-
- sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (sock < 0) {
- printf("open netlink socket: %s\n", strerror(errno));
- return -1;
- }
-
- if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
- printf("bind to netlink: %s\n", strerror(errno));
- goto cleanup;
- }
-
- memset(&req, 0, sizeof(req));
- req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
- req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- req.nh.nlmsg_type = RTM_SETLINK;
- req.nh.nlmsg_pid = 0;
- req.nh.nlmsg_seq = ++seq;
- req.ifinfo.ifi_family = AF_UNSPEC;
- req.ifinfo.ifi_index = ifindex;
-
- /* started nested attribute for XDP */
- nla = (struct nlattr *)(((char *)&req)
- + NLMSG_ALIGN(req.nh.nlmsg_len));
- nla->nla_type = NLA_F_NESTED | 43/*IFLA_XDP*/;
- nla->nla_len = NLA_HDRLEN;
-
- /* add XDP fd */
- nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
- nla_xdp->nla_type = 1/*IFLA_XDP_FD*/;
- nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
- memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
- nla->nla_len += nla_xdp->nla_len;
-
- /* if user passed in any flags, add those too */
- if (flags) {
- nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
- nla_xdp->nla_type = 3/*IFLA_XDP_FLAGS*/;
- nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
- memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
- nla->nla_len += nla_xdp->nla_len;
- }
-
- req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
-
- if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
- printf("send to netlink: %s\n", strerror(errno));
- goto cleanup;
- }
-
- len = recv(sock, buf, sizeof(buf), 0);
- if (len < 0) {
- printf("recv from netlink: %s\n", strerror(errno));
- goto cleanup;
- }
-
- for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
- nh = NLMSG_NEXT(nh, len)) {
- if (nh->nlmsg_pid != getpid()) {
- printf("Wrong pid %d, expected %d\n",
- nh->nlmsg_pid, getpid());
- goto cleanup;
- }
- if (nh->nlmsg_seq != seq) {
- printf("Wrong seq %d, expected %d\n",
- nh->nlmsg_seq, seq);
- goto cleanup;
- }
- switch (nh->nlmsg_type) {
- case NLMSG_ERROR:
- err = (struct nlmsgerr *)NLMSG_DATA(nh);
- if (!err->error)
- continue;
- printf("nlmsg error %s\n", strerror(-err->error));
- goto cleanup;
- case NLMSG_DONE:
- break;
- }
- }
-
- ret = 0;
-
-cleanup:
- close(sock);
- return ret;
-}
diff --git a/samples/bpf/bpf_load.h b/samples/bpf/bpf_load.h
index 7d57a4248893..453c200b389b 100644
--- a/samples/bpf/bpf_load.h
+++ b/samples/bpf/bpf_load.h
@@ -61,5 +61,5 @@ struct ksym {
int load_kallsyms(void);
struct ksym *ksym_search(long key);
-int set_link_xdp_fd(int ifindex, int fd, __u32 flags);
+int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
#endif
diff --git a/samples/bpf/tcbpf2_kern.c b/samples/bpf/tcbpf2_kern.c
index f6bbf8f50da3..efdc16d195ff 100644
--- a/samples/bpf/tcbpf2_kern.c
+++ b/samples/bpf/tcbpf2_kern.c
@@ -15,6 +15,7 @@
#include <uapi/linux/tcp.h>
#include <uapi/linux/filter.h>
#include <uapi/linux/pkt_cls.h>
+#include <uapi/linux/erspan.h>
#include <net/ipv6.h>
#include "bpf_helpers.h"
#include "bpf_endian.h"
@@ -35,24 +36,10 @@ struct geneve_opt {
u8 opt_data[8]; /* hard-coded to 8 byte */
};
-struct erspan_md2 {
- __be32 timestamp;
- __be16 sgt;
- __be16 flags;
-};
-
struct vxlan_metadata {
u32 gbp;
};
-struct erspan_metadata {
- union {
- __be32 index;
- struct erspan_md2 md2;
- } u;
- int version;
-};
-
SEC("gre_set_tunnel")
int _gre_set_tunnel(struct __sk_buff *skb)
{
@@ -156,13 +143,15 @@ int _erspan_set_tunnel(struct __sk_buff *skb)
__builtin_memset(&md, 0, sizeof(md));
#ifdef ERSPAN_V1
md.version = 1;
- md.u.index = htonl(123);
+ md.u.index = bpf_htonl(123);
#else
u8 direction = 1;
- u16 hwid = 7;
+ u8 hwid = 7;
md.version = 2;
- md.u.md2.flags = htons((direction << 3) | (hwid << 4));
+ md.u.md2.dir = direction;
+ md.u.md2.hwid = hwid & 0xf;
+ md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
#endif
ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
@@ -207,9 +196,9 @@ int _erspan_get_tunnel(struct __sk_buff *skb)
char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
bpf_trace_printk(fmt2, sizeof(fmt2),
- (ntohs(md.u.md2.flags) >> 3) & 0x1,
- (ntohs(md.u.md2.flags) >> 4) & 0x3f,
- bpf_ntohl(md.u.md2.timestamp));
+ md.u.md2.dir,
+ (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
+ bpf_ntohl(md.u.md2.timestamp));
#endif
return TC_ACT_OK;
@@ -242,10 +231,12 @@ int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
md.version = 1;
#else
u8 direction = 0;
- u16 hwid = 17;
+ u8 hwid = 17;
md.version = 2;
- md.u.md2.flags = htons((direction << 3) | (hwid << 4));
+ md.u.md2.dir = direction;
+ md.u.md2.hwid = hwid & 0xf;
+ md.u.md2.hwid_upper = (hwid >> 4) & 0x3;
#endif
ret = bpf_skb_set_tunnel_opt(skb, &md, sizeof(md));
@@ -290,9 +281,9 @@ int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
char fmt2[] = "\tdirection %d hwid %x timestamp %u\n";
bpf_trace_printk(fmt2, sizeof(fmt2),
- (ntohs(md.u.md2.flags) >> 3) & 0x1,
- (ntohs(md.u.md2.flags) >> 4) & 0x3f,
- bpf_ntohl(md.u.md2.timestamp));
+ md.u.md2.dir,
+ (md.u.md2.hwid_upper << 4) + md.u.md2.hwid,
+ bpf_ntohl(md.u.md2.timestamp));
#endif
return TC_ACT_OK;
diff --git a/samples/bpf/test_tunnel_bpf.sh b/samples/bpf/test_tunnel_bpf.sh
index ae7f7c38309b..43ce049996ee 100755
--- a/samples/bpf/test_tunnel_bpf.sh
+++ b/samples/bpf/test_tunnel_bpf.sh
@@ -68,7 +68,7 @@ function add_erspan_tunnel {
ip netns exec at_ns0 \
ip link add dev $DEV_NS type $TYPE seq key 2 \
local 172.16.1.100 remote 172.16.1.200 \
- erspan_ver 2 erspan_dir 1 erspan_hwid 3
+ erspan_ver 2 erspan_dir egress erspan_hwid 3
fi
ip netns exec at_ns0 ip link set dev $DEV_NS up
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
@@ -97,7 +97,7 @@ function add_ip6erspan_tunnel {
ip netns exec at_ns0 \
ip link add dev $DEV_NS type $TYPE seq key 2 \
local ::11 remote ::22 \
- erspan_ver 2 erspan_dir 1 erspan_hwid 7
+ erspan_ver 2 erspan_dir egress erspan_hwid 7
fi
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
ip netns exec at_ns0 ip link set dev $DEV_NS up
diff --git a/samples/bpf/xdp1_user.c b/samples/bpf/xdp1_user.c
index fdaefe91801d..b901ee2b3336 100644
--- a/samples/bpf/xdp1_user.c
+++ b/samples/bpf/xdp1_user.c
@@ -25,7 +25,7 @@ static __u32 xdp_flags;
static void int_exit(int sig)
{
- set_link_xdp_fd(ifindex, -1, xdp_flags);
+ bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
exit(0);
}
@@ -116,7 +116,7 @@ int main(int argc, char **argv)
signal(SIGINT, int_exit);
signal(SIGTERM, int_exit);
- if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
printf("link set xdp fd failed\n");
return 1;
}
diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c
index 35fec9fecb57..23744a8aaf21 100644
--- a/samples/bpf/xdp_redirect_cpu_user.c
+++ b/samples/bpf/xdp_redirect_cpu_user.c
@@ -26,7 +26,7 @@ static const char *__doc__ =
/* Wanted to get rid of bpf_load.h and fake-"libbpf.h" (and instead
* use bpf/libbpf.h), but cannot as (currently) needed for XDP
- * attaching to a device via set_link_xdp_fd()
+ * attaching to a device via bpf_set_link_xdp_fd()
*/
#include "libbpf.h"
#include "bpf_load.h"
@@ -67,7 +67,7 @@ static void int_exit(int sig)
"Interrupted: Removing XDP program on ifindex:%d device:%s\n",
ifindex, ifname);
if (ifindex > -1)
- set_link_xdp_fd(ifindex, -1, xdp_flags);
+ bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
exit(EXIT_OK);
}
@@ -682,7 +682,7 @@ int main(int argc, char **argv)
/* Remove XDP program when program is interrupted */
signal(SIGINT, int_exit);
- if (set_link_xdp_fd(ifindex, prog_fd[prog_num], xdp_flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex, prog_fd[prog_num], xdp_flags) < 0) {
fprintf(stderr, "link set xdp fd failed\n");
return EXIT_FAIL_XDP;
}
diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c
index 978a532f0748..7eae07d7293e 100644
--- a/samples/bpf/xdp_redirect_map_user.c
+++ b/samples/bpf/xdp_redirect_map_user.c
@@ -34,9 +34,9 @@ static __u32 xdp_flags;
static void int_exit(int sig)
{
- set_link_xdp_fd(ifindex_in, -1, xdp_flags);
+ bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
if (ifindex_out_xdp_dummy_attached)
- set_link_xdp_fd(ifindex_out, -1, xdp_flags);
+ bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
exit(0);
}
@@ -120,13 +120,13 @@ int main(int argc, char **argv)
return 1;
}
- if (set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
printf("ERROR: link set xdp fd failed on %d\n", ifindex_in);
return 1;
}
/* Loading dummy XDP prog on out-device */
- if (set_link_xdp_fd(ifindex_out, prog_fd[1],
+ if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1],
(xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
printf("WARN: link set xdp fd failed on %d\n", ifindex_out);
ifindex_out_xdp_dummy_attached = false;
diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c
index 4475d837bf2c..d54e91eb6cbf 100644
--- a/samples/bpf/xdp_redirect_user.c
+++ b/samples/bpf/xdp_redirect_user.c
@@ -33,9 +33,9 @@ static __u32 xdp_flags;
static void int_exit(int sig)
{
- set_link_xdp_fd(ifindex_in, -1, xdp_flags);
+ bpf_set_link_xdp_fd(ifindex_in, -1, xdp_flags);
if (ifindex_out_xdp_dummy_attached)
- set_link_xdp_fd(ifindex_out, -1, xdp_flags);
+ bpf_set_link_xdp_fd(ifindex_out, -1, xdp_flags);
exit(0);
}
@@ -114,13 +114,13 @@ int main(int argc, char **argv)
return 1;
}
- if (set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex_in, prog_fd[0], xdp_flags) < 0) {
printf("ERROR: link set xdp fd failed on %d\n", ifindex_in);
return 1;
}
/* Loading dummy XDP prog on out-device */
- if (set_link_xdp_fd(ifindex_out, prog_fd[1],
+ if (bpf_set_link_xdp_fd(ifindex_out, prog_fd[1],
(xdp_flags | XDP_FLAGS_UPDATE_IF_NOEXIST)) < 0) {
printf("WARN: link set xdp fd failed on %d\n", ifindex_out);
ifindex_out_xdp_dummy_attached = false;
diff --git a/samples/bpf/xdp_router_ipv4_user.c b/samples/bpf/xdp_router_ipv4_user.c
index 916462112d55..6296741c1fbd 100644
--- a/samples/bpf/xdp_router_ipv4_user.c
+++ b/samples/bpf/xdp_router_ipv4_user.c
@@ -37,7 +37,7 @@ static void int_exit(int sig)
int i = 0;
for (i = 0; i < total_ifindex; i++)
- set_link_xdp_fd(ifindex_list[i], -1, flags);
+ bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
exit(0);
}
@@ -49,7 +49,7 @@ static void close_and_exit(int sig)
close(sock_arp);
for (i = 0; i < total_ifindex; i++)
- set_link_xdp_fd(ifindex_list[i], -1, flags);
+ bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
exit(0);
}
@@ -183,7 +183,7 @@ static void read_route(struct nlmsghdr *nh, int nll)
int i = 0;
for (i = 0; i < total_ifindex; i++)
- set_link_xdp_fd(ifindex_list[i], -1, flags);
+ bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
exit(0);
}
assert(bpf_map_update_elem(map_fd[4], &route.iface, &route.iface, 0) == 0);
@@ -633,12 +633,12 @@ int main(int ac, char **argv)
}
}
for (i = 0; i < total_ifindex; i++) {
- if (set_link_xdp_fd(ifindex_list[i], prog_fd[0], flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex_list[i], prog_fd[0], flags) < 0) {
printf("link set xdp fd failed\n");
int recovery_index = i;
for (i = 0; i < recovery_index; i++)
- set_link_xdp_fd(ifindex_list[i], -1, flags);
+ bpf_set_link_xdp_fd(ifindex_list[i], -1, flags);
return 1;
}
diff --git a/samples/bpf/xdp_rxq_info_user.c b/samples/bpf/xdp_rxq_info_user.c
index 32430e8b3a6a..478d95412de4 100644
--- a/samples/bpf/xdp_rxq_info_user.c
+++ b/samples/bpf/xdp_rxq_info_user.c
@@ -56,7 +56,7 @@ static void int_exit(int sig)
"Interrupted: Removing XDP program on ifindex:%d device:%s\n",
ifindex, ifname);
if (ifindex > -1)
- set_link_xdp_fd(ifindex, -1, xdp_flags);
+ bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
exit(EXIT_OK);
}
@@ -521,7 +521,7 @@ int main(int argc, char **argv)
/* Remove XDP program when program is interrupted */
signal(SIGINT, int_exit);
- if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
fprintf(stderr, "link set xdp fd failed\n");
return EXIT_FAIL_XDP;
}
diff --git a/samples/bpf/xdp_tx_iptunnel_user.c b/samples/bpf/xdp_tx_iptunnel_user.c
index 715cd12eaca5..f0a787268a87 100644
--- a/samples/bpf/xdp_tx_iptunnel_user.c
+++ b/samples/bpf/xdp_tx_iptunnel_user.c
@@ -30,7 +30,7 @@ static __u32 xdp_flags = 0;
static void int_exit(int sig)
{
if (ifindex > -1)
- set_link_xdp_fd(ifindex, -1, xdp_flags);
+ bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
exit(0);
}
@@ -254,14 +254,14 @@ int main(int argc, char **argv)
}
}
- if (set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
+ if (bpf_set_link_xdp_fd(ifindex, prog_fd[0], xdp_flags) < 0) {
printf("link set xdp fd failed\n");
return 1;
}
poll_stats(kill_after_s);
- set_link_xdp_fd(ifindex, -1, xdp_flags);
+ bpf_set_link_xdp_fd(ifindex, -1, xdp_flags);
return 0;
}
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan
index 1ce7115aa499..69552a39951d 100644
--- a/scripts/Makefile.kasan
+++ b/scripts/Makefile.kasan
@@ -10,10 +10,7 @@ KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET)
CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address
-CFLAGS_KASAN := $(call cc-option, -fsanitize=kernel-address \
- -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET) \
- --param asan-stack=1 --param asan-globals=1 \
- --param asan-instrumentation-with-call-threshold=$(call_threshold))
+cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1)))
ifeq ($(call cc-option, $(CFLAGS_KASAN_MINIMAL) -Werror),)
ifneq ($(CONFIG_COMPILE_TEST),y)
@@ -21,14 +18,30 @@ ifeq ($(call cc-option, $(CFLAGS_KASAN_MINIMAL) -Werror),)
-fsanitize=kernel-address is not supported by compiler)
endif
else
- ifeq ($(CFLAGS_KASAN),)
- ifneq ($(CONFIG_COMPILE_TEST),y)
- $(warning CONFIG_KASAN: compiler does not support all options.\
- Trying minimal configuration)
- endif
- CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL)
- endif
+ # -fasan-shadow-offset fails without -fsanitize
+ CFLAGS_KASAN_SHADOW := $(call cc-option, -fsanitize=kernel-address \
+ -fasan-shadow-offset=$(KASAN_SHADOW_OFFSET), \
+ $(call cc-option, -fsanitize=kernel-address \
+ -mllvm -asan-mapping-offset=$(KASAN_SHADOW_OFFSET)))
+
+ ifeq ($(strip $(CFLAGS_KASAN_SHADOW)),)
+ CFLAGS_KASAN := $(CFLAGS_KASAN_MINIMAL)
+ else
+ # Now add all the compiler specific options that are valid standalone
+ CFLAGS_KASAN := $(CFLAGS_KASAN_SHADOW) \
+ $(call cc-param,asan-globals=1) \
+ $(call cc-param,asan-instrumentation-with-call-threshold=$(call_threshold)) \
+ $(call cc-param,asan-stack=1) \
+ $(call cc-param,asan-use-after-scope=1) \
+ $(call cc-param,asan-instrument-allocas=1)
+ endif
+
endif
+ifdef CONFIG_KASAN_EXTRA
CFLAGS_KASAN += $(call cc-option, -fsanitize-address-use-after-scope)
endif
+
+CFLAGS_KASAN_NOSANITIZE := -fno-builtin
+
+endif
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 5fdc1a19b02c..5589bae34af6 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -121,7 +121,7 @@ endif
ifeq ($(CONFIG_KASAN),y)
_c_flags += $(if $(patsubst n%,, \
$(KASAN_SANITIZE_$(basetarget).o)$(KASAN_SANITIZE)y), \
- $(CFLAGS_KASAN))
+ $(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE))
endif
ifeq ($(CONFIG_UBSAN),y)
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index 8fd4d44fbcd1..b593b36ccff8 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -7,7 +7,6 @@ ifdef CONFIG_UBSAN
CFLAGS_UBSAN += $(call cc-option, -fsanitize=signed-integer-overflow)
CFLAGS_UBSAN += $(call cc-option, -fsanitize=bounds)
CFLAGS_UBSAN += $(call cc-option, -fsanitize=object-size)
- CFLAGS_UBSAN += $(call cc-option, -fsanitize=returns-nonnull-attribute)
CFLAGS_UBSAN += $(call cc-option, -fsanitize=bool)
CFLAGS_UBSAN += $(call cc-option, -fsanitize=enum)
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index e954df2b2077..3d4040322ae1 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -566,6 +566,7 @@ foreach my $entry (@mode_permission_funcs) {
$mode_perms_search .= '|' if ($mode_perms_search ne "");
$mode_perms_search .= $entry->[0];
}
+$mode_perms_search = "(?:${mode_perms_search})";
our $mode_perms_world_writable = qr{
S_IWUGO |
@@ -600,6 +601,37 @@ foreach my $entry (keys %mode_permission_string_types) {
$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
$mode_perms_string_search .= $entry;
}
+our $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
+our $multi_mode_perms_string_search = qr{
+ ${single_mode_perms_string_search}
+ (?:\s*\|\s*${single_mode_perms_string_search})*
+}x;
+
+sub perms_to_octal {
+ my ($string) = @_;
+
+ return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
+
+ my $val = "";
+ my $oval = "";
+ my $to = 0;
+ my $curpos = 0;
+ my $lastpos = 0;
+ while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
+ $curpos = pos($string);
+ my $match = $2;
+ my $omatch = $1;
+ last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
+ $lastpos = $curpos;
+ $to |= $mode_permission_string_types{$match};
+ $val .= '\s*\|\s*' if ($val ne "");
+ $val .= $match;
+ $oval .= $omatch;
+ }
+ $oval =~ s/^\s*\|\s*//;
+ $oval =~ s/\s*\|\s*$//;
+ return sprintf("%04o", $to);
+}
our $allowed_asm_includes = qr{(?x:
irq|
@@ -2875,6 +2907,7 @@ sub process {
# logging functions like pr_info that end in a string
# lines with a single string
# #defines that are a single string
+# lines with an RFC3986 like URL
#
# There are 3 different line length message types:
# LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length
@@ -2906,6 +2939,10 @@ sub process {
$line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
$msg_type = "";
+ # URL ($rawline is used in case the URL is in a comment)
+ } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
+ $msg_type = "";
+
# Otherwise set the alternate message types
# a comment starts before $max_line_length
@@ -2983,7 +3020,7 @@ sub process {
# check indentation starts on a tab stop
if ($^V && $^V ge 5.10.0 &&
- $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) {
+ $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
my $indent = length($1);
if ($indent % 8) {
if (WARN("TABSTOP",
@@ -3882,10 +3919,12 @@ sub process {
# function brace can't be on same line, except for #defines of do while,
# or if closed on same line
- if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and
- !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) {
+ if ($^V && $^V ge 5.10.0 &&
+ $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
+ $sline !~ /\#\s*define\b.*do\s*\{/ &&
+ $sline !~ /}/) {
if (ERROR("OPEN_BRACE",
- "open brace '{' following function declarations go on the next line\n" . $herecurr) &&
+ "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
$fix) {
fix_delete_line($fixlinenr, $rawline);
my $fixed_line = $rawline;
@@ -4489,7 +4528,9 @@ sub process {
}
# check for unnecessary parentheses around comparisons in if uses
- if ($^V && $^V ge 5.10.0 && defined($stat) &&
+# when !drivers/staging or command-line uses --strict
+ if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
+ $^V && $^V ge 5.10.0 && defined($stat) &&
$stat =~ /(^.\s*if\s*($balanced_parens))/) {
my $if_stat = $1;
my $test = substr($2, 1, -1);
@@ -5307,7 +5348,7 @@ sub process {
}
# check for line continuations in quoted strings with odd counts of "
- if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
+ if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
WARN("LINE_CONTINUATIONS",
"Avoid line continuations in quoted strings\n" . $herecurr);
}
@@ -6269,8 +6310,69 @@ sub process {
"Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
}
+# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
+# and whether or not function naming is typical and if
+# DEVICE_ATTR permissions uses are unusual too
+ if ($^V && $^V ge 5.10.0 &&
+ defined $stat &&
+ $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
+ my $var = $1;
+ my $perms = $2;
+ my $show = $3;
+ my $store = $4;
+ my $octal_perms = perms_to_octal($perms);
+ if ($show =~ /^${var}_show$/ &&
+ $store =~ /^${var}_store$/ &&
+ $octal_perms eq "0644") {
+ if (WARN("DEVICE_ATTR_RW",
+ "Use DEVICE_ATTR_RW\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
+ }
+ } elsif ($show =~ /^${var}_show$/ &&
+ $store =~ /^NULL$/ &&
+ $octal_perms eq "0444") {
+ if (WARN("DEVICE_ATTR_RO",
+ "Use DEVICE_ATTR_RO\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
+ }
+ } elsif ($show =~ /^NULL$/ &&
+ $store =~ /^${var}_store$/ &&
+ $octal_perms eq "0200") {
+ if (WARN("DEVICE_ATTR_WO",
+ "Use DEVICE_ATTR_WO\n" . $herecurr) &&
+ $fix) {
+ $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
+ }
+ } elsif ($octal_perms eq "0644" ||
+ $octal_perms eq "0444" ||
+ $octal_perms eq "0200") {
+ my $newshow = "$show";
+ $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
+ my $newstore = $store;
+ $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
+ my $rename = "";
+ if ($show ne $newshow) {
+ $rename .= " '$show' to '$newshow'";
+ }
+ if ($store ne $newstore) {
+ $rename .= " '$store' to '$newstore'";
+ }
+ WARN("DEVICE_ATTR_FUNCTIONS",
+ "Consider renaming function(s)$rename\n" . $herecurr);
+ } else {
+ WARN("DEVICE_ATTR_PERMS",
+ "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
+ }
+ }
+
# Mode permission misuses where it seems decimal should be octal
# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
+# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
+# specific definition of not visible in sysfs.
+# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
+# use the default permissions
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
$line =~ /$mode_perms_search/) {
@@ -6294,8 +6396,9 @@ sub process {
if ($stat =~ /$test/) {
my $val = $1;
$val = $6 if ($skip_args ne "");
- if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
- ($val =~ /^$Octal$/ && length($val) ne 4)) {
+ if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
+ (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
+ ($val =~ /^$Octal$/ && length($val) ne 4))) {
ERROR("NON_OCTAL_PERMISSIONS",
"Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
}
@@ -6308,30 +6411,13 @@ sub process {
}
# check for uses of S_<PERMS> that could be octal for readability
- if ($line =~ /\b$mode_perms_string_search\b/) {
- my $val = "";
- my $oval = "";
- my $to = 0;
- my $curpos = 0;
- my $lastpos = 0;
- while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
- $curpos = pos($line);
- my $match = $2;
- my $omatch = $1;
- last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
- $lastpos = $curpos;
- $to |= $mode_permission_string_types{$match};
- $val .= '\s*\|\s*' if ($val ne "");
- $val .= $match;
- $oval .= $omatch;
- }
- $oval =~ s/^\s*\|\s*//;
- $oval =~ s/\s*\|\s*$//;
- my $octal = sprintf("%04o", $to);
+ if ($line =~ /\b($multi_mode_perms_string_search)\b/) {
+ my $oval = $1;
+ my $octal = perms_to_octal($oval);
if (WARN("SYMBOLIC_PERMS",
"Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
$fix) {
- $fixed[$fixlinenr] =~ s/$val/$octal/;
+ $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
}
}
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 6510536c06df..9917f928d0fd 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1685,7 +1685,7 @@ static void extable_mismatch_handler(const char* modname, struct elf_info *elf,
static void check_section_mismatch(const char *modname, struct elf_info *elf,
Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
{
- const char *tosec = sec_name(elf, get_secindex(elf, sym));;
+ const char *tosec = sec_name(elf, get_secindex(elf, sym));
const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
if (mismatch) {
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 061425dd6400..2cfb0c714967 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -135,7 +135,7 @@ static void ima_check_last_writer(struct integrity_iint_cache *iint,
update = test_and_clear_bit(IMA_UPDATE_XATTR,
&iint->atomic_flags);
if (!IS_I_VERSION(inode) ||
- inode_cmp_iversion(inode, iint->version) ||
+ !inode_eq_iversion(inode, iint->version) ||
(iint->flags & IMA_NEW_FILE)) {
iint->flags &= ~(IMA_DONE_MASK | IMA_NEW_FILE);
iint->measured_pcrs = 0;
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index 8298e094f4f7..ffda91a4a1aa 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -250,15 +250,10 @@ int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
} else {
struct task_struct *tracer;
- rcu_read_lock();
- tracer = find_task_by_vpid(arg2);
- if (tracer)
- get_task_struct(tracer);
- else
+ tracer = find_get_task_by_vpid(arg2);
+ if (!tracer) {
rc = -EINVAL;
- rcu_read_unlock();
-
- if (tracer) {
+ } else {
rc = yama_ptracer_add(tracer, myself);
put_task_struct(tracer);
}
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index d7469cdd90dc..98f93e79c654 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -110,16 +110,15 @@ static const struct snd_soc_dapm_route intercon[] = {
static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct device *dev = rtd->dev;
int ret;
- printk(KERN_DEBUG
- "at91sam9g20ek_wm8731 "
- ": at91sam9g20ek_wm8731_init() called\n");
+ dev_dbg(dev, "%s called\n", __func__);
ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_MCLK,
- MCLK_RATE, SND_SOC_CLOCK_IN);
+ MCLK_RATE, SND_SOC_CLOCK_IN);
if (ret < 0) {
- printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret);
+ dev_err(dev, "Failed to set WM8731 SYSCLK: %d\n", ret);
return ret;
}
@@ -179,21 +178,21 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
*/
mclk = clk_get(NULL, "pck0");
if (IS_ERR(mclk)) {
- printk(KERN_ERR "ASoC: Failed to get MCLK\n");
+ dev_err(&pdev->dev, "Failed to get MCLK\n");
ret = PTR_ERR(mclk);
goto err;
}
pllb = clk_get(NULL, "pllb");
if (IS_ERR(pllb)) {
- printk(KERN_ERR "ASoC: Failed to get PLLB\n");
+ dev_err(&pdev->dev, "Failed to get PLLB\n");
ret = PTR_ERR(pllb);
goto err_mclk;
}
ret = clk_set_parent(mclk, pllb);
clk_put(pllb);
if (ret != 0) {
- printk(KERN_ERR "ASoC: Failed to set MCLK parent\n");
+ dev_err(&pdev->dev, "Failed to set MCLK parent\n");
goto err_mclk;
}
@@ -236,7 +235,7 @@ static int at91sam9g20ek_audio_probe(struct platform_device *pdev)
ret = snd_soc_register_card(card);
if (ret) {
- printk(KERN_ERR "ASoC: snd_soc_register_card() failed\n");
+ dev_err(&pdev->dev, "snd_soc_register_card() failed\n");
}
return ret;
diff --git a/sound/soc/atmel/sam9x5_wm8731.c b/sound/soc/atmel/sam9x5_wm8731.c
index ccdf547f4d8c..e6c303ab869d 100644
--- a/sound/soc/atmel/sam9x5_wm8731.c
+++ b/sound/soc/atmel/sam9x5_wm8731.c
@@ -49,13 +49,13 @@ static int sam9x5_wm8731_init(struct snd_soc_pcm_runtime *rtd)
struct device *dev = rtd->dev;
int ret;
- dev_dbg(dev, "ASoC: %s called\n", __func__);
+ dev_dbg(dev, "%s called\n", __func__);
/* set the codec system clock for DAC and ADC */
ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL,
MCLK_RATE, SND_SOC_CLOCK_IN);
if (ret < 0) {
- dev_err(dev, "ASoC: Failed to set WM8731 SYSCLK: %d\n", ret);
+ dev_err(dev, "Failed to set WM8731 SYSCLK: %d\n", ret);
return ret;
}
@@ -146,8 +146,7 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
ret = atmel_ssc_set_audio(priv->ssc_id);
if (ret != 0) {
- dev_err(&pdev->dev,
- "ASoC: Failed to set SSC %d for audio: %d\n",
+ dev_err(&pdev->dev, "Failed to set SSC %d for audio: %d\n",
ret, priv->ssc_id);
goto out;
}
@@ -157,12 +156,11 @@ static int sam9x5_wm8731_driver_probe(struct platform_device *pdev)
ret = snd_soc_register_card(card);
if (ret) {
- dev_err(&pdev->dev,
- "ASoC: Platform device allocation failed\n");
+ dev_err(&pdev->dev, "Platform device allocation failed\n");
goto out_put_audio;
}
- dev_dbg(&pdev->dev, "ASoC: %s ok\n", __func__);
+ dev_dbg(&pdev->dev, "%s ok\n", __func__);
return ret;
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index b95bb8b52e51..3d1cf4784e87 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -15,6 +15,7 @@
*/
#include <linux/clk.h>
+#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/of_device.h>
@@ -95,6 +96,9 @@ struct ak4613_priv {
struct mutex lock;
const struct ak4613_interface *iface;
struct snd_pcm_hw_constraint_list constraint;
+ struct work_struct dummy_write_work;
+ struct snd_soc_component *component;
+ unsigned int rate;
unsigned int sysclk;
unsigned int fmt;
@@ -392,6 +396,7 @@ static int ak4613_dai_hw_params(struct snd_pcm_substream *substream,
default:
return -EINVAL;
}
+ priv->rate = rate;
/*
* FIXME
@@ -467,11 +472,83 @@ static int ak4613_set_bias_level(struct snd_soc_codec *codec,
return 0;
}
+static void ak4613_dummy_write(struct work_struct *work)
+{
+ struct ak4613_priv *priv = container_of(work,
+ struct ak4613_priv,
+ dummy_write_work);
+ struct snd_soc_component *component = priv->component;
+ unsigned int mgmt1;
+ unsigned int mgmt3;
+
+ /*
+ * PW_MGMT1 / PW_MGMT3 needs dummy write at least after 5 LR clocks
+ *
+ * Note
+ *
+ * To avoid extra delay, we want to avoid preemption here,
+ * but we can't. Because it uses I2C access which is using IRQ
+ * and sleep. Thus, delay might be more than 5 LR clocks
+ * see also
+ * ak4613_dai_trigger()
+ */
+ udelay(5000000 / priv->rate);
+
+ snd_soc_component_read(component, PW_MGMT1, &mgmt1);
+ snd_soc_component_read(component, PW_MGMT3, &mgmt3);
+
+ snd_soc_component_write(component, PW_MGMT1, mgmt1);
+ snd_soc_component_write(component, PW_MGMT3, mgmt3);
+}
+
+static int ak4613_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct ak4613_priv *priv = snd_soc_codec_get_drvdata(codec);
+
+ /*
+ * FIXME
+ *
+ * PW_MGMT1 / PW_MGMT3 needs dummy write at least after 5 LR clocks
+ * from Power Down Release. Otherwise, Playback volume will be 0dB.
+ * To avoid complex multiple delay/dummy_write method from
+ * ak4613_set_bias_level() / SND_SOC_DAPM_DAC_E("DACx", ...),
+ * call it once here.
+ *
+ * But, unfortunately, we can't "write" here because here is atomic
+ * context (It uses I2C access for writing).
+ * Thus, use schedule_work() to switching to normal context
+ * immediately.
+ *
+ * Note
+ *
+ * Calling ak4613_dummy_write() function might be delayed.
+ * In such case, ak4613 volume might be temporarily 0dB when
+ * beggining of playback.
+ * see also
+ * ak4613_dummy_write()
+ */
+
+ if ((cmd != SNDRV_PCM_TRIGGER_START) &&
+ (cmd != SNDRV_PCM_TRIGGER_RESUME))
+ return 0;
+
+ if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
+ return 0;
+
+ priv->component = &codec->component;
+ schedule_work(&priv->dummy_write_work);
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops ak4613_dai_ops = {
.startup = ak4613_dai_startup,
.shutdown = ak4613_dai_shutdown,
.set_sysclk = ak4613_dai_set_sysclk,
.set_fmt = ak4613_dai_set_fmt,
+ .trigger = ak4613_dai_trigger,
.hw_params = ak4613_dai_hw_params,
};
@@ -590,6 +667,7 @@ static int ak4613_i2c_probe(struct i2c_client *i2c,
priv->iface = NULL;
priv->cnt = 0;
priv->sysclk = 0;
+ INIT_WORK(&priv->dummy_write_work, ak4613_dummy_write);
mutex_init(&priv->lock);
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index c88f974ebe3e..cf83c423394d 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -113,7 +113,7 @@ static int dmic_dev_probe(struct platform_device *pdev)
if (pdev->dev.of_node) {
err = of_property_read_u32(pdev->dev.of_node, "num-channels", &chans);
- if (err && (err != -ENOENT))
+ if (err && (err != -EINVAL))
return err;
if (!err) {
diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c
index 31b0864583e8..562e88765129 100644
--- a/sound/soc/codecs/max98373.c
+++ b/sound/soc/codecs/max98373.c
@@ -1,5 +1,5 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (c) 2017, Maxim Integrated */
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017, Maxim Integrated
#include <linux/acpi.h>
#include <linux/i2c.h>
diff --git a/sound/soc/codecs/max98373.h b/sound/soc/codecs/max98373.h
index d0b359d0cf8c..f6a37aa02f26 100644
--- a/sound/soc/codecs/max98373.h
+++ b/sound/soc/codecs/max98373.h
@@ -1,5 +1,6 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (c) 2017, Maxim Integrated */
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2017, Maxim Integrated
+
#ifndef _MAX98373_H
#define _MAX98373_H
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c
index 633cdcfc933d..e1ab5537d27a 100644
--- a/sound/soc/codecs/sgtl5000.c
+++ b/sound/soc/codecs/sgtl5000.c
@@ -1392,7 +1392,7 @@ static int sgtl5000_i2c_probe(struct i2c_client *client,
ana_pwr |= SGTL5000_LINEREG_D_POWERUP;
dev_info(&client->dev,
- "Using internal LDO instead of VDDD: check ER1\n");
+ "Using internal LDO instead of VDDD: check ER1 erratum\n");
} else {
/* using external LDO for VDDD
* Clear startup powerup and simple powerup
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 8798182959c1..e4d7f397d361 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -2195,6 +2195,8 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec)
static const struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
.probe = twl4030_soc_probe,
.remove = twl4030_soc_remove,
+ .read = twl4030_read,
+ .write = twl4030_write,
.set_bias_level = twl4030_set_bias_level,
.idle_bias_off = true,
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 3b895b4b451c..573a523ed0b3 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -1158,6 +1158,8 @@ static int twl6040_remove(struct snd_soc_codec *codec)
static const struct snd_soc_codec_driver soc_codec_dev_twl6040 = {
.probe = twl6040_probe,
.remove = twl6040_remove,
+ .read = twl6040_read,
+ .write = twl6040_write,
.set_bias_level = twl6040_set_bias_level,
.suspend_bias_off = true,
.ignore_pmdown_time = true,
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index f2c9e8c5970a..ceb105cbd461 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -97,6 +97,9 @@ config SND_SST_ATOM_HIFI2_PLATFORM
codec, then enable this option by saying Y or m. This is a
recommended option
+config SND_SOC_INTEL_SKYLAKE_SSP_CLK
+ tristate
+
config SND_SOC_INTEL_SKYLAKE
tristate "SKL/BXT/KBL/GLK/CNL... Platforms"
depends on PCI && ACPI
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig
index d4e103615f51..fefb1ee9fec6 100644
--- a/sound/soc/intel/boards/Kconfig
+++ b/sound/soc/intel/boards/Kconfig
@@ -235,6 +235,7 @@ config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH
select SND_SOC_MAX98927
select SND_SOC_DMIC
select SND_SOC_HDAC_HDMI
+ select SND_SOC_INTEL_SKYLAKE_SSP_CLK
help
This adds support for ASoC Onboard Codec I2S machine driver. This will
create an alsa sound card for RT5663 + MAX98927.
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c
index bf7014ca486f..f5df6bca3156 100644
--- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
@@ -28,6 +28,9 @@
#include "../../codecs/rt5663.h"
#include "../../codecs/hdac_hdmi.h"
#include "../skylake/skl.h"
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
#define KBL_REALTEK_CODEC_DAI "rt5663-aif"
#define KBL_MAXIM_CODEC_DAI "max98927-aif1"
@@ -48,6 +51,8 @@ struct kbl_hdmi_pcm {
struct kbl_rt5663_private {
struct snd_soc_jack kabylake_headset;
struct list_head hdmi_pcm_list;
+ struct clk *mclk;
+ struct clk *sclk;
};
enum {
@@ -69,6 +74,61 @@ static const struct snd_kcontrol_new kabylake_controls[] = {
SOC_DAPM_PIN_SWITCH("Right Spk"),
};
+static int platform_clock_control(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_dapm_context *dapm = w->dapm;
+ struct snd_soc_card *card = dapm->card;
+ struct kbl_rt5663_private *priv = snd_soc_card_get_drvdata(card);
+ int ret = 0;
+
+ /*
+ * MCLK/SCLK need to be ON early for a successful synchronization of
+ * codec internal clock. And the clocks are turned off during
+ * POST_PMD after the stream is stopped.
+ */
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Enable MCLK */
+ ret = clk_set_rate(priv->mclk, 24000000);
+ if (ret < 0) {
+ dev_err(card->dev, "Can't set rate for mclk, err: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(priv->mclk);
+ if (ret < 0) {
+ dev_err(card->dev, "Can't enable mclk, err: %d\n", ret);
+ return ret;
+ }
+
+ /* Enable SCLK */
+ ret = clk_set_rate(priv->sclk, 3072000);
+ if (ret < 0) {
+ dev_err(card->dev, "Can't set rate for sclk, err: %d\n",
+ ret);
+ clk_disable_unprepare(priv->mclk);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(priv->sclk);
+ if (ret < 0) {
+ dev_err(card->dev, "Can't enable sclk, err: %d\n", ret);
+ clk_disable_unprepare(priv->mclk);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ clk_disable_unprepare(priv->mclk);
+ clk_disable_unprepare(priv->sclk);
+ break;
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dapm_widget kabylake_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
@@ -78,11 +138,14 @@ static const struct snd_soc_dapm_widget kabylake_widgets[] = {
SND_SOC_DAPM_SPK("HDMI1", NULL),
SND_SOC_DAPM_SPK("HDMI2", NULL),
SND_SOC_DAPM_SPK("HDMI3", NULL),
-
+ SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
+ platform_clock_control, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_route kabylake_map[] = {
/* HP jack connectors - unknown if we have jack detection */
+ { "Headphone Jack", NULL, "Platform Clock" },
{ "Headphone Jack", NULL, "HPOL" },
{ "Headphone Jack", NULL, "HPOR" },
@@ -91,6 +154,7 @@ static const struct snd_soc_dapm_route kabylake_map[] = {
{ "Right Spk", NULL, "Right BE_OUT" },
/* other jacks */
+ { "Headset Mic", NULL, "Platform Clock" },
{ "IN1P", NULL, "Headset Mic" },
{ "IN1N", NULL, "Headset Mic" },
{ "DMic", NULL, "SoC DMIC" },
@@ -901,6 +965,7 @@ static int kabylake_audio_probe(struct platform_device *pdev)
{
struct kbl_rt5663_private *ctx;
struct skl_machine_pdata *pdata;
+ int ret;
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_ATOMIC);
if (!ctx)
@@ -919,6 +984,34 @@ static int kabylake_audio_probe(struct platform_device *pdev)
dmic_constraints = pdata->dmic_num == 2 ?
&constraints_dmic_2ch : &constraints_dmic_channels;
+ ctx->mclk = devm_clk_get(&pdev->dev, "ssp1_mclk");
+ if (IS_ERR(ctx->mclk)) {
+ ret = PTR_ERR(ctx->mclk);
+ if (ret == -ENOENT) {
+ dev_info(&pdev->dev,
+ "Failed to get ssp1_sclk, defer probe\n");
+ return -EPROBE_DEFER;
+ }
+
+ dev_err(&pdev->dev, "Failed to get ssp1_mclk with err:%d\n",
+ ret);
+ return ret;
+ }
+
+ ctx->sclk = devm_clk_get(&pdev->dev, "ssp1_sclk");
+ if (IS_ERR(ctx->sclk)) {
+ ret = PTR_ERR(ctx->sclk);
+ if (ret == -ENOENT) {
+ dev_info(&pdev->dev,
+ "Failed to get ssp1_sclk, defer probe\n");
+ return -EPROBE_DEFER;
+ }
+
+ dev_err(&pdev->dev, "Failed to get ssp1_sclk with err:%d\n",
+ ret);
+ return ret;
+ }
+
return devm_snd_soc_register_card(&pdev->dev, kabylake_audio_card);
}
diff --git a/sound/soc/intel/skylake/Makefile b/sound/soc/intel/skylake/Makefile
index d1ccbecd141f..86f6e1d801af 100644
--- a/sound/soc/intel/skylake/Makefile
+++ b/sound/soc/intel/skylake/Makefile
@@ -14,3 +14,8 @@ snd-soc-skl-ipc-objs := skl-sst-ipc.o skl-sst-dsp.o cnl-sst-dsp.o \
skl-sst-utils.o
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl-ipc.o
+
+#Skylake Clock device support
+snd-soc-skl-ssp-clk-objs := skl-ssp-clk.o
+
+obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK) += snd-soc-skl-ssp-clk.o
diff --git a/sound/soc/intel/skylake/skl-i2s.h b/sound/soc/intel/skylake/skl-i2s.h
index dcf819bc688f..ad0a1bbca13c 100644
--- a/sound/soc/intel/skylake/skl-i2s.h
+++ b/sound/soc/intel/skylake/skl-i2s.h
@@ -27,6 +27,12 @@
#define SKL_SHIFT(x) (ffs(x) - 1)
#define SKL_MCLK_DIV_RATIO_MASK GENMASK(11, 0)
+#define is_legacy_blob(x) (x.signature != 0xEE)
+#define ext_to_legacy_blob(i2s_config_blob_ext) \
+ ((struct skl_i2s_config_blob_legacy *) i2s_config_blob_ext)
+
+#define get_clk_src(mclk, mask) \
+ ((mclk.mdivctrl & mask) >> SKL_SHIFT(mask))
struct skl_i2s_config {
u32 ssc0;
u32 ssc1;
@@ -45,6 +51,24 @@ struct skl_i2s_config_mclk {
u32 mdivr;
};
+struct skl_i2s_config_mclk_ext {
+ u32 mdivctrl;
+ u32 mdivr_count;
+ u32 mdivr[0];
+} __packed;
+
+struct skl_i2s_config_blob_signature {
+ u32 minor_ver : 8;
+ u32 major_ver : 8;
+ u32 resvdz : 8;
+ u32 signature : 8;
+} __packed;
+
+struct skl_i2s_config_blob_header {
+ struct skl_i2s_config_blob_signature sig;
+ u32 size;
+};
+
/**
* struct skl_i2s_config_blob_legacy - Structure defines I2S Gateway
* configuration legacy blob
@@ -61,4 +85,11 @@ struct skl_i2s_config_blob_legacy {
struct skl_i2s_config_mclk mclk;
};
+struct skl_i2s_config_blob_ext {
+ u32 gtw_attr;
+ struct skl_i2s_config_blob_header hdr;
+ u32 tdm_ts_group[SKL_I2S_MAX_TIME_SLOTS];
+ struct skl_i2s_config i2s_cfg;
+ struct skl_i2s_config_mclk_ext mclk;
+} __packed;
#endif /* __SOUND_SOC_SKL_I2S_H */
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 8cbf080c38b3..60d76adade43 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -675,6 +675,7 @@ int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
kfree(dma_ctrl);
return err;
}
+EXPORT_SYMBOL_GPL(skl_dsp_set_dma_control);
static void skl_setup_out_format(struct skl_sst *ctx,
struct skl_module_cfg *mconfig,
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c
index 3b1d2b828c1b..b9b140275be0 100644
--- a/sound/soc/intel/skylake/skl-nhlt.c
+++ b/sound/soc/intel/skylake/skl-nhlt.c
@@ -28,6 +28,7 @@ static guid_t osc_guid =
GUID_INIT(0xA69F886E, 0x6CEB, 0x4594,
0xA4, 0x1F, 0x7B, 0x5D, 0xCE, 0x24, 0xC5, 0x53);
+
struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
{
acpi_handle handle;
@@ -287,6 +288,7 @@ void skl_nhlt_remove_sysfs(struct skl *skl)
static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
struct nhlt_fmt *fmt, u8 id)
{
+ struct skl_i2s_config_blob_ext *i2s_config_ext;
struct skl_i2s_config_blob_legacy *i2s_config;
struct skl_clk_parent_src *parent;
struct skl_ssp_clk *sclk, *sclkfs;
@@ -347,12 +349,18 @@ static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
/* Fill rate and parent for sclk/sclkfs */
if (!present) {
- /* MCLK Divider Source Select */
- i2s_config = (struct skl_i2s_config_blob_legacy *)
+ i2s_config_ext = (struct skl_i2s_config_blob_ext *)
fmt->fmt_config[0].config.caps;
- clk_src = ((i2s_config->mclk.mdivctrl)
- & SKL_MNDSS_DIV_CLK_SRC_MASK) >>
- SKL_SHIFT(SKL_MNDSS_DIV_CLK_SRC_MASK);
+
+ /* MCLK Divider Source Select */
+ if (is_legacy_blob(i2s_config_ext->hdr.sig)) {
+ i2s_config = ext_to_legacy_blob(i2s_config_ext);
+ clk_src = get_clk_src(i2s_config->mclk,
+ SKL_MNDSS_DIV_CLK_SRC_MASK);
+ } else {
+ clk_src = get_clk_src(i2s_config_ext->mclk,
+ SKL_MNDSS_DIV_CLK_SRC_MASK);
+ }
parent = skl_get_parent_clk(clk_src);
@@ -378,6 +386,7 @@ static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks,
static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk,
struct nhlt_fmt *fmt, u8 id)
{
+ struct skl_i2s_config_blob_ext *i2s_config_ext;
struct skl_i2s_config_blob_legacy *i2s_config;
struct nhlt_specific_cfg *fmt_cfg;
struct skl_clk_parent_src *parent;
@@ -385,13 +394,21 @@ static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk,
u8 clk_src;
fmt_cfg = &fmt->fmt_config[0].config;
- i2s_config = (struct skl_i2s_config_blob_legacy *)fmt_cfg->caps;
-
- /* MCLK Divider Source Select */
- clk_src = ((i2s_config->mclk.mdivctrl) & SKL_MCLK_DIV_CLK_SRC_MASK) >>
- SKL_SHIFT(SKL_MCLK_DIV_CLK_SRC_MASK);
-
- clkdiv = i2s_config->mclk.mdivr & SKL_MCLK_DIV_RATIO_MASK;
+ i2s_config_ext = (struct skl_i2s_config_blob_ext *)fmt_cfg->caps;
+
+ /* MCLK Divider Source Select and divider */
+ if (is_legacy_blob(i2s_config_ext->hdr.sig)) {
+ i2s_config = ext_to_legacy_blob(i2s_config_ext);
+ clk_src = get_clk_src(i2s_config->mclk,
+ SKL_MCLK_DIV_CLK_SRC_MASK);
+ clkdiv = i2s_config->mclk.mdivr &
+ SKL_MCLK_DIV_RATIO_MASK;
+ } else {
+ clk_src = get_clk_src(i2s_config_ext->mclk,
+ SKL_MCLK_DIV_CLK_SRC_MASK);
+ clkdiv = i2s_config_ext->mclk.mdivr[0] &
+ SKL_MCLK_DIV_RATIO_MASK;
+ }
/* bypass divider */
div_ratio = 1;
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.c b/sound/soc/intel/skylake/skl-ssp-clk.c
new file mode 100644
index 000000000000..7fbddf5e3b00
--- /dev/null
+++ b/sound/soc/intel/skylake/skl-ssp-clk.c
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2015-17 Intel Corporation
+
+/*
+ * skl-ssp-clk.c - ASoC skylake ssp clock driver
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include "skl.h"
+#include "skl-ssp-clk.h"
+#include "skl-topology.h"
+
+#define to_skl_clk(_hw) container_of(_hw, struct skl_clk, hw)
+
+struct skl_clk_parent {
+ struct clk_hw *hw;
+ struct clk_lookup *lookup;
+};
+
+struct skl_clk {
+ struct clk_hw hw;
+ struct clk_lookup *lookup;
+ unsigned long rate;
+ struct skl_clk_pdata *pdata;
+ u32 id;
+};
+
+struct skl_clk_data {
+ struct skl_clk_parent parent[SKL_MAX_CLK_SRC];
+ struct skl_clk *clk[SKL_MAX_CLK_CNT];
+ u8 avail_clk_cnt;
+};
+
+static int skl_get_clk_type(u32 index)
+{
+ switch (index) {
+ case 0 ... (SKL_SCLK_OFS - 1):
+ return SKL_MCLK;
+
+ case SKL_SCLK_OFS ... (SKL_SCLKFS_OFS - 1):
+ return SKL_SCLK;
+
+ case SKL_SCLKFS_OFS ... (SKL_MAX_CLK_CNT - 1):
+ return SKL_SCLK_FS;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int skl_get_vbus_id(u32 index, u8 clk_type)
+{
+ switch (clk_type) {
+ case SKL_MCLK:
+ return index;
+
+ case SKL_SCLK:
+ return index - SKL_SCLK_OFS;
+
+ case SKL_SCLK_FS:
+ return index - SKL_SCLKFS_OFS;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static void skl_fill_clk_ipc(struct skl_clk_rate_cfg_table *rcfg, u8 clk_type)
+{
+ struct nhlt_fmt_cfg *fmt_cfg;
+ union skl_clk_ctrl_ipc *ipc;
+ struct wav_fmt *wfmt;
+
+ if (!rcfg)
+ return;
+
+ ipc = &rcfg->dma_ctl_ipc;
+ if (clk_type == SKL_SCLK_FS) {
+ fmt_cfg = (struct nhlt_fmt_cfg *)rcfg->config;
+ wfmt = &fmt_cfg->fmt_ext.fmt;
+
+ /* Remove TLV Header size */
+ ipc->sclk_fs.hdr.size = sizeof(struct skl_dmactrl_sclkfs_cfg) -
+ sizeof(struct skl_tlv_hdr);
+ ipc->sclk_fs.sampling_frequency = wfmt->samples_per_sec;
+ ipc->sclk_fs.bit_depth = wfmt->bits_per_sample;
+ ipc->sclk_fs.valid_bit_depth =
+ fmt_cfg->fmt_ext.sample.valid_bits_per_sample;
+ ipc->sclk_fs.number_of_channels = wfmt->channels;
+ } else {
+ ipc->mclk.hdr.type = DMA_CLK_CONTROLS;
+ /* Remove TLV Header size */
+ ipc->mclk.hdr.size = sizeof(struct skl_dmactrl_mclk_cfg) -
+ sizeof(struct skl_tlv_hdr);
+ }
+}
+
+/* Sends dma control IPC to turn the clock ON/OFF */
+static int skl_send_clk_dma_control(struct skl *skl,
+ struct skl_clk_rate_cfg_table *rcfg,
+ u32 vbus_id, u8 clk_type,
+ bool enable)
+{
+ struct nhlt_specific_cfg *sp_cfg;
+ u32 i2s_config_size, node_id = 0;
+ struct nhlt_fmt_cfg *fmt_cfg;
+ union skl_clk_ctrl_ipc *ipc;
+ void *i2s_config = NULL;
+ u8 *data, size;
+ int ret;
+
+ if (!rcfg)
+ return -EIO;
+
+ ipc = &rcfg->dma_ctl_ipc;
+ fmt_cfg = (struct nhlt_fmt_cfg *)rcfg->config;
+ sp_cfg = &fmt_cfg->config;
+
+ if (clk_type == SKL_SCLK_FS) {
+ ipc->sclk_fs.hdr.type =
+ enable ? DMA_TRANSMITION_START : DMA_TRANSMITION_STOP;
+ data = (u8 *)&ipc->sclk_fs;
+ size = sizeof(struct skl_dmactrl_sclkfs_cfg);
+ } else {
+ /* 1 to enable mclk, 0 to enable sclk */
+ if (clk_type == SKL_SCLK)
+ ipc->mclk.mclk = 0;
+ else
+ ipc->mclk.mclk = 1;
+
+ ipc->mclk.keep_running = enable;
+ ipc->mclk.warm_up_over = enable;
+ ipc->mclk.clk_stop_over = !enable;
+ data = (u8 *)&ipc->mclk;
+ size = sizeof(struct skl_dmactrl_mclk_cfg);
+ }
+
+ i2s_config_size = sp_cfg->size + size;
+ i2s_config = kzalloc(i2s_config_size, GFP_KERNEL);
+ if (!i2s_config)
+ return -ENOMEM;
+
+ /* copy blob */
+ memcpy(i2s_config, sp_cfg->caps, sp_cfg->size);
+
+ /* copy additional dma controls information */
+ memcpy(i2s_config + sp_cfg->size, data, size);
+
+ node_id = ((SKL_DMA_I2S_LINK_INPUT_CLASS << 8) | (vbus_id << 4));
+ ret = skl_dsp_set_dma_control(skl->skl_sst, (u32 *)i2s_config,
+ i2s_config_size, node_id);
+ kfree(i2s_config);
+
+ return ret;
+}
+
+static struct skl_clk_rate_cfg_table *skl_get_rate_cfg(
+ struct skl_clk_rate_cfg_table *rcfg,
+ unsigned long rate)
+{
+ int i;
+
+ for (i = 0; (i < SKL_MAX_CLK_RATES) && rcfg[i].rate; i++) {
+ if (rcfg[i].rate == rate)
+ return &rcfg[i];
+ }
+
+ return NULL;
+}
+
+static int skl_clk_change_status(struct skl_clk *clkdev,
+ bool enable)
+{
+ struct skl_clk_rate_cfg_table *rcfg;
+ int vbus_id, clk_type;
+
+ clk_type = skl_get_clk_type(clkdev->id);
+ if (clk_type < 0)
+ return clk_type;
+
+ vbus_id = skl_get_vbus_id(clkdev->id, clk_type);
+ if (vbus_id < 0)
+ return vbus_id;
+
+ rcfg = skl_get_rate_cfg(clkdev->pdata->ssp_clks[clkdev->id].rate_cfg,
+ clkdev->rate);
+ if (!rcfg)
+ return -EINVAL;
+
+ return skl_send_clk_dma_control(clkdev->pdata->pvt_data, rcfg,
+ vbus_id, clk_type, enable);
+}
+
+static int skl_clk_prepare(struct clk_hw *hw)
+{
+ struct skl_clk *clkdev = to_skl_clk(hw);
+
+ return skl_clk_change_status(clkdev, true);
+}
+
+static void skl_clk_unprepare(struct clk_hw *hw)
+{
+ struct skl_clk *clkdev = to_skl_clk(hw);
+
+ skl_clk_change_status(clkdev, false);
+}
+
+static int skl_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct skl_clk *clkdev = to_skl_clk(hw);
+ struct skl_clk_rate_cfg_table *rcfg;
+ int clk_type;
+
+ if (!rate)
+ return -EINVAL;
+
+ rcfg = skl_get_rate_cfg(clkdev->pdata->ssp_clks[clkdev->id].rate_cfg,
+ rate);
+ if (!rcfg)
+ return -EINVAL;
+
+ clk_type = skl_get_clk_type(clkdev->id);
+ if (clk_type < 0)
+ return clk_type;
+
+ skl_fill_clk_ipc(rcfg, clk_type);
+ clkdev->rate = rate;
+
+ return 0;
+}
+
+static unsigned long skl_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct skl_clk *clkdev = to_skl_clk(hw);
+
+ if (clkdev->rate)
+ return clkdev->rate;
+
+ return 0;
+}
+
+/* Not supported by clk driver. Implemented to satisfy clk fw */
+long skl_clk_round_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long *parent_rate)
+{
+ return rate;
+}
+
+/*
+ * prepare/unprepare are used instead of enable/disable as IPC will be sent
+ * in non-atomic context.
+ */
+static const struct clk_ops skl_clk_ops = {
+ .prepare = skl_clk_prepare,
+ .unprepare = skl_clk_unprepare,
+ .set_rate = skl_clk_set_rate,
+ .round_rate = skl_clk_round_rate,
+ .recalc_rate = skl_clk_recalc_rate,
+};
+
+static void unregister_parent_src_clk(struct skl_clk_parent *pclk,
+ unsigned int id)
+{
+ while (id--) {
+ clkdev_drop(pclk[id].lookup);
+ clk_hw_unregister_fixed_rate(pclk[id].hw);
+ }
+}
+
+static void unregister_src_clk(struct skl_clk_data *dclk)
+{
+ u8 cnt = dclk->avail_clk_cnt;
+
+ while (cnt--)
+ clkdev_drop(dclk->clk[cnt]->lookup);
+}
+
+static int skl_register_parent_clks(struct device *dev,
+ struct skl_clk_parent *parent,
+ struct skl_clk_parent_src *pclk)
+{
+ int i, ret;
+
+ for (i = 0; i < SKL_MAX_CLK_SRC; i++) {
+
+ /* Register Parent clock */
+ parent[i].hw = clk_hw_register_fixed_rate(dev, pclk[i].name,
+ pclk[i].parent_name, 0, pclk[i].rate);
+ if (IS_ERR(parent[i].hw)) {
+ ret = PTR_ERR(parent[i].hw);
+ goto err;
+ }
+
+ parent[i].lookup = clkdev_hw_create(parent[i].hw, pclk[i].name,
+ NULL);
+ if (!parent[i].lookup) {
+ clk_hw_unregister_fixed_rate(parent[i].hw);
+ ret = -ENOMEM;
+ goto err;
+ }
+ }
+
+ return 0;
+err:
+ unregister_parent_src_clk(parent, i);
+ return ret;
+}
+
+/* Assign fmt_config to clk_data */
+static struct skl_clk *register_skl_clk(struct device *dev,
+ struct skl_ssp_clk *clk,
+ struct skl_clk_pdata *clk_pdata, int id)
+{
+ struct clk_init_data init;
+ struct skl_clk *clkdev;
+ int ret;
+
+ clkdev = devm_kzalloc(dev, sizeof(*clkdev), GFP_KERNEL);
+ if (!clkdev)
+ return ERR_PTR(-ENOMEM);
+
+ init.name = clk->name;
+ init.ops = &skl_clk_ops;
+ init.flags = CLK_SET_RATE_GATE;
+ init.parent_names = &clk->parent_name;
+ init.num_parents = 1;
+ clkdev->hw.init = &init;
+ clkdev->pdata = clk_pdata;
+
+ clkdev->id = id;
+ ret = devm_clk_hw_register(dev, &clkdev->hw);
+ if (ret) {
+ clkdev = ERR_PTR(ret);
+ return clkdev;
+ }
+
+ clkdev->lookup = clkdev_hw_create(&clkdev->hw, init.name, NULL);
+ if (!clkdev->lookup)
+ clkdev = ERR_PTR(-ENOMEM);
+
+ return clkdev;
+}
+
+static int skl_clk_dev_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device *parent_dev = dev->parent;
+ struct skl_clk_parent_src *parent_clks;
+ struct skl_clk_pdata *clk_pdata;
+ struct skl_clk_data *data;
+ struct skl_ssp_clk *clks;
+ int ret, i;
+
+ clk_pdata = dev_get_platdata(&pdev->dev);
+ parent_clks = clk_pdata->parent_clks;
+ clks = clk_pdata->ssp_clks;
+ if (!parent_clks || !clks)
+ return -EIO;
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ /* Register Parent clock */
+ ret = skl_register_parent_clks(parent_dev, data->parent, parent_clks);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; i < clk_pdata->num_clks; i++) {
+ /*
+ * Only register valid clocks
+ * i.e. for which nhlt entry is present.
+ */
+ if (clks[i].rate_cfg[0].rate == 0)
+ continue;
+
+ data->clk[i] = register_skl_clk(dev, &clks[i], clk_pdata, i);
+ if (IS_ERR(data->clk[i])) {
+ ret = PTR_ERR(data->clk[i]);
+ goto err_unreg_skl_clk;
+ }
+
+ data->avail_clk_cnt++;
+ }
+
+ platform_set_drvdata(pdev, data);
+
+ return 0;
+
+err_unreg_skl_clk:
+ unregister_src_clk(data);
+ unregister_parent_src_clk(data->parent, SKL_MAX_CLK_SRC);
+
+ return ret;
+}
+
+static int skl_clk_dev_remove(struct platform_device *pdev)
+{
+ struct skl_clk_data *data;
+
+ data = platform_get_drvdata(pdev);
+ unregister_src_clk(data);
+ unregister_parent_src_clk(data->parent, SKL_MAX_CLK_SRC);
+
+ return 0;
+}
+
+static struct platform_driver skl_clk_driver = {
+ .driver = {
+ .name = "skl-ssp-clk",
+ },
+ .probe = skl_clk_dev_probe,
+ .remove = skl_clk_dev_remove,
+};
+
+module_platform_driver(skl_clk_driver);
+
+MODULE_DESCRIPTION("Skylake clock driver");
+MODULE_AUTHOR("Jaikrishna Nemallapudi <jaikrishnax.nemallapudi@intel.com>");
+MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:skl-ssp-clk");
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.h b/sound/soc/intel/skylake/skl-ssp-clk.h
index c9ea84004260..d1be50f96c05 100644
--- a/sound/soc/intel/skylake/skl-ssp-clk.h
+++ b/sound/soc/intel/skylake/skl-ssp-clk.h
@@ -54,8 +54,46 @@ struct skl_clk_parent_src {
const char *parent_name;
};
+struct skl_tlv_hdr {
+ u32 type;
+ u32 size;
+};
+
+struct skl_dmactrl_mclk_cfg {
+ struct skl_tlv_hdr hdr;
+ /* DMA Clk TLV params */
+ u32 clk_warm_up:16;
+ u32 mclk:1;
+ u32 warm_up_over:1;
+ u32 rsvd0:14;
+ u32 clk_stop_delay:16;
+ u32 keep_running:1;
+ u32 clk_stop_over:1;
+ u32 rsvd1:14;
+};
+
+struct skl_dmactrl_sclkfs_cfg {
+ struct skl_tlv_hdr hdr;
+ /* DMA SClk&FS TLV params */
+ u32 sampling_frequency;
+ u32 bit_depth;
+ u32 channel_map;
+ u32 channel_config;
+ u32 interleaving_style;
+ u32 number_of_channels : 8;
+ u32 valid_bit_depth : 8;
+ u32 sample_type : 8;
+ u32 reserved : 8;
+};
+
+union skl_clk_ctrl_ipc {
+ struct skl_dmactrl_mclk_cfg mclk;
+ struct skl_dmactrl_sclkfs_cfg sclk_fs;
+};
+
struct skl_clk_rate_cfg_table {
unsigned long rate;
+ union skl_clk_ctrl_ipc dma_ctl_ipc;
void *config;
};
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h
index f411579bc713..2d13f3fd988a 100644
--- a/sound/soc/intel/skylake/skl.h
+++ b/sound/soc/intel/skylake/skl.h
@@ -38,6 +38,10 @@
/* D0I3C Register fields */
#define AZX_REG_VS_D0I3C_CIP 0x1 /* Command in progress */
#define AZX_REG_VS_D0I3C_I3 0x4 /* D0i3 enable */
+#define SKL_MAX_DMACTRL_CFG 18
+#define DMA_CLK_CONTROLS 1
+#define DMA_TRANSMITION_START 2
+#define DMA_TRANSMITION_STOP 3
struct skl_dsp_resource {
u32 max_mcps;
@@ -147,6 +151,8 @@ int skl_nhlt_create_sysfs(struct skl *skl);
void skl_nhlt_remove_sysfs(struct skl *skl);
void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks);
struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id);
+int skl_dsp_set_dma_control(struct skl_sst *ctx, u32 *caps,
+ u32 caps_size, u32 node_id);
struct skl_module_cfg;
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index 5bc4e00a4a29..d68b53f7cefe 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -1405,9 +1405,24 @@ static int mt2701_afe_runtime_resume(struct device *dev)
return mt2701_afe_enable_clock(afe);
}
-static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+static int mt2701_afe_add_component(struct mtk_base_afe *afe)
{
struct snd_soc_component *component;
+
+ component = kzalloc(sizeof(*component), GFP_KERNEL);
+ if (!component)
+ return -ENOMEM;
+
+ component->regmap = afe->regmap;
+
+ return snd_soc_add_component(afe->dev, component,
+ &mt2701_afe_pcm_dai_component,
+ mt2701_afe_pcm_dais,
+ ARRAY_SIZE(mt2701_afe_pcm_dais));
+}
+
+static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
+{
struct mtk_base_afe *afe;
struct mt2701_afe_private *afe_priv;
struct device *dev;
@@ -1477,12 +1492,6 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
= &mt2701_i2s_data[i][I2S_IN];
}
- component = kzalloc(sizeof(*component), GFP_KERNEL);
- if (!component)
- return -ENOMEM;
-
- component->regmap = afe->regmap;
-
afe->mtk_afe_hardware = &mt2701_afe_hardware;
afe->memif_fs = mt2701_memif_fs;
afe->irq_fs = mt2701_irq_fs;
@@ -1495,7 +1504,7 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
ret = mt2701_init_clock(afe);
if (ret) {
dev_err(dev, "init clock error\n");
- goto err_init_clock;
+ return ret;
}
platform_set_drvdata(pdev, afe);
@@ -1514,10 +1523,7 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)
goto err_platform;
}
- ret = snd_soc_add_component(dev, component,
- &mt2701_afe_pcm_dai_component,
- mt2701_afe_pcm_dais,
- ARRAY_SIZE(mt2701_afe_pcm_dais));
+ ret = mt2701_afe_add_component(afe);
if (ret) {
dev_warn(dev, "err_dai_component\n");
goto err_dai_component;
@@ -1531,8 +1537,6 @@ err_platform:
pm_runtime_put_sync(dev);
err_pm_disable:
pm_runtime_disable(dev);
-err_init_clock:
- kfree(component);
return ret;
}
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index 40ebefd625c1..679fc8bea0a3 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -272,15 +272,10 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
}
mt8173_rt5650_codecs[1].of_node = mt8173_rt5650_codecs[0].of_node;
- if (of_find_node_by_name(platform_node, "codec-capture")) {
- np = of_get_child_by_name(pdev->dev.of_node, "codec-capture");
- if (!np) {
- dev_err(&pdev->dev,
- "%s: Can't find codec-capture DT node\n",
- __func__);
- return -EINVAL;
- }
+ np = of_get_child_by_name(pdev->dev.of_node, "codec-capture");
+ if (np) {
ret = snd_soc_of_get_dai_name(np, &codec_capture_dai);
+ of_node_put(np);
if (ret < 0) {
dev_err(&pdev->dev,
"%s codec_capture_dai name fail %d\n",
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
index fa6cd1de828b..214bfc78cf5c 100644
--- a/sound/soc/rockchip/rk3399_gru_sound.c
+++ b/sound/soc/rockchip/rk3399_gru_sound.c
@@ -368,7 +368,8 @@ static const struct snd_soc_dai_link rockchip_dais[] = {
[DAILINK_RT5514_DSP] = {
.name = "RT5514 DSP",
.stream_name = "Wake on Voice",
- .codec_dai_name = "rt5514-dsp-cpu-dai",
+ .codec_name = "snd-soc-dummy",
+ .codec_dai_name = "snd-soc-dummy-dai",
},
};
@@ -529,7 +530,18 @@ static int rockchip_sound_of_parse_dais(struct device *dev,
if (index < 0)
continue;
- np_cpu = (index == DAILINK_CDNDP) ? np_cpu1 : np_cpu0;
+ switch (index) {
+ case DAILINK_CDNDP:
+ np_cpu = np_cpu1;
+ break;
+ case DAILINK_RT5514_DSP:
+ np_cpu = np_codec;
+ break;
+ default:
+ np_cpu = np_cpu0;
+ break;
+ }
+
if (!np_cpu) {
dev_err(dev, "Missing 'rockchip,cpu' for %s\n",
rockchip_dais[index].name);
@@ -539,7 +551,8 @@ static int rockchip_sound_of_parse_dais(struct device *dev,
dai = &card->dai_link[card->num_links++];
*dai = rockchip_dais[index];
- dai->codec_of_node = np_codec;
+ if (!dai->codec_name)
+ dai->codec_of_node = np_codec;
dai->platform_of_node = np_cpu;
dai->cpu_of_node = np_cpu;
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index 81232f4ab614..82402688bd8e 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -40,7 +40,8 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
if (ret < 0) {
- dev_err(cpu_dai->dev, "Compress ASoC: can't open interface %s: %d\n",
+ dev_err(cpu_dai->dev,
+ "Compress ASoC: can't open interface %s: %d\n",
cpu_dai->name, ret);
goto out;
}
@@ -49,8 +50,9 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
if (platform && 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->component.name);
+ dev_err(platform->dev,
+ "Compress ASoC: can't open platform %s: %d\n",
+ platform->component.name, ret);
goto plat_err;
}
}
@@ -68,8 +70,9 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
__ret = component->driver->compr_ops->open(cstream);
if (__ret < 0) {
- pr_err("compress asoc: can't open platform %s\n",
- component->name);
+ dev_err(component->dev,
+ "Compress ASoC: can't open platform %s: %d\n",
+ component->name, __ret);
ret = __ret;
}
}
@@ -79,7 +82,9 @@ static int soc_compr_open(struct snd_compr_stream *cstream)
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);
+ dev_err(rtd->dev,
+ "Compress ASoC: %s startup failed: %d\n",
+ rtd->dai_link->name, ret);
goto machine_err;
}
}
@@ -139,18 +144,19 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
if (cpu_dai->driver->cops && cpu_dai->driver->cops->startup) {
ret = cpu_dai->driver->cops->startup(cstream, cpu_dai);
if (ret < 0) {
- dev_err(cpu_dai->dev, "Compress ASoC: can't open interface %s: %d\n",
+ dev_err(cpu_dai->dev,
+ "Compress ASoC: can't open interface %s: %d\n",
cpu_dai->name, ret);
goto out;
}
}
-
if (platform && 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->component.name);
+ dev_err(platform->dev,
+ "Compress ASoC: can't open platform %s: %d\n",
+ platform->component.name, ret);
goto plat_err;
}
}
@@ -168,8 +174,9 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
__ret = component->driver->compr_ops->open(cstream);
if (__ret < 0) {
- pr_err("compress asoc: can't open platform %s\n",
- component->name);
+ dev_err(component->dev,
+ "Compress ASoC: can't open platform %s: %d\n",
+ component->name, __ret);
ret = __ret;
}
}
@@ -179,7 +186,8 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->startup) {
ret = fe->dai_link->compr_ops->startup(cstream);
if (ret < 0) {
- pr_err("compress asoc: %s startup failed\n", fe->dai_link->name);
+ pr_err("Compress ASoC: %s startup failed: %d\n",
+ fe->dai_link->name, ret);
goto machine_err;
}
}
@@ -190,7 +198,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
if (ret < 0)
goto fe_err;
else if (ret == 0)
- dev_dbg(fe->dev, "ASoC: %s no valid %s route\n",
+ dev_dbg(fe->dev, "Compress ASoC: %s no valid %s route\n",
fe->dai_link->name, stream ? "capture" : "playback");
/* calculate valid and active FE <-> BE dpcms */
@@ -265,10 +273,11 @@ static void close_delayed_work(struct work_struct *work)
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
- dev_dbg(rtd->dev, "ASoC: pop wq checking: %s status: %s waiting: %s\n",
- codec_dai->driver->playback.stream_name,
- codec_dai->playback_active ? "active" : "inactive",
- rtd->pop_wait ? "yes" : "no");
+ dev_dbg(rtd->dev,
+ "Compress ASoC: pop wq checking: %s status: %s waiting: %s\n",
+ codec_dai->driver->playback.stream_name,
+ codec_dai->playback_active ? "active" : "inactive",
+ rtd->pop_wait ? "yes" : "no");
/* are we waiting on this codec DAI stream */
if (rtd->pop_wait == 1) {
@@ -307,7 +316,6 @@ static int soc_compr_free(struct snd_compr_stream *cstream)
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);
@@ -376,7 +384,7 @@ static int soc_compr_free_fe(struct snd_compr_stream *cstream)
ret = dpcm_be_dai_hw_free(fe, stream);
if (ret < 0)
- dev_err(fe->dev, "compressed hw_free failed %d\n", ret);
+ dev_err(fe->dev, "Compressed ASoC: hw_free failed: %d\n", ret);
ret = dpcm_be_dai_shutdown(fe, stream);
@@ -460,7 +468,6 @@ static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
if (cpu_dai->driver->cops && cpu_dai->driver->cops->trigger)
cpu_dai->driver->cops->trigger(cstream, cmd, cpu_dai);
-
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
snd_soc_dai_digital_mute(codec_dai, 0, cstream->direction);
@@ -944,7 +951,7 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_component *component;
struct snd_soc_rtdcom_list *rtdcom;
- int ret = 0, __ret;
+ int ret = 0;
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -965,10 +972,10 @@ static int soc_compr_copy(struct snd_compr_stream *cstream,
!component->driver->compr_ops->copy)
continue;
- __ret = component->driver->compr_ops->copy(cstream, buf, count);
- if (__ret < 0)
- ret = __ret;
+ ret = component->driver->compr_ops->copy(cstream, buf, count);
+ break;
}
+
err:
mutex_unlock(&rtd->pcm_mutex);
return ret;
@@ -1108,7 +1115,8 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
int playback = 0, capture = 0;
if (rtd->num_codecs > 1) {
- dev_err(rtd->card->dev, "Multicodec not supported for compressed stream\n");
+ dev_err(rtd->card->dev,
+ "Compress ASoC: Multicodec not supported\n");
return -EINVAL;
}
@@ -1126,8 +1134,9 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
* should be set, check for that (xor)
*/
if (playback + capture != 1) {
- dev_err(rtd->card->dev, "Invalid direction for compress P %d, C %d\n",
- playback, capture);
+ dev_err(rtd->card->dev,
+ "Compress ASoC: Invalid direction for P %d, C %d\n",
+ playback, capture);
return -EINVAL;
}
@@ -1155,8 +1164,9 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
rtd->dai_link->dpcm_playback,
rtd->dai_link->dpcm_capture, &be_pcm);
if (ret < 0) {
- dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n",
- rtd->dai_link->name);
+ dev_err(rtd->card->dev,
+ "Compress ASoC: can't create compressed for %s: %d\n",
+ rtd->dai_link->name, ret);
goto compr_err;
}
@@ -1199,8 +1209,9 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
new_name, compr);
if (ret < 0) {
component = rtd->codec_dai->component;
- pr_err("compress asoc: can't create compress for codec %s\n",
- component->name);
+ dev_err(component->dev,
+ "Compress ASoC: can't create compress for codec %s: %d\n",
+ component->name, ret);
goto compr_err;
}
@@ -1210,8 +1221,8 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
rtd->compr = compr;
compr->private_data = rtd;
- printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name,
- cpu_dai->name);
+ dev_info(rtd->card->dev, "Compress ASoC: %s <-> %s mapping ok\n",
+ codec_dai->name, cpu_dai->name);
return ret;
compr_err:
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 88efc84f3e7b..96c44f6576c9 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -553,9 +553,17 @@ struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd,
{
struct snd_soc_rtdcom_list *rtdcom;
+ if (!driver_name)
+ return NULL;
+
for_each_rtdcom(rtd, rtdcom) {
- if ((rtdcom->component->driver->name == driver_name) ||
- strcmp(rtdcom->component->driver->name, driver_name) == 0)
+ const char *component_name = rtdcom->component->driver->name;
+
+ if (!component_name)
+ continue;
+
+ if ((component_name == driver_name) ||
+ strcmp(component_name, driver_name) == 0)
return rtdcom->component;
}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d1977ced895f..92894d9cac19 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2026,7 +2026,7 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
snd_soc_dapm_for_each_direction(dir) {
rdir = SND_SOC_DAPM_DIR_REVERSE(dir);
snd_soc_dapm_widget_for_each_path(w, dir, p) {
- if (p->connected && !p->connected(w, p->node[rdir]))
+ if (p->connected && !p->connected(p->source, p->sink))
continue;
if (!p->connect)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 8075856668c2..084125463d10 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -144,7 +144,7 @@ bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd)
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
- ignore &= !component->driver->pmdown_time;
+ ignore &= !component->driver->use_pmdown_time;
}
/* this will be removed */
@@ -2831,10 +2831,9 @@ static void soc_pcm_private_free(struct snd_pcm *pcm)
struct snd_soc_rtdcom_list *rtdcom;
struct snd_soc_component *component;
+ /* need to sync the delayed work before releasing resources */
+ flush_delayed_work(&rtd->delayed_work);
for_each_rtdcom(rtd, rtdcom) {
- /* need to sync the delayed work before releasing resources */
-
- flush_delayed_work(&rtd->delayed_work);
component = rtdcom->component;
if (component->pcm_free)
diff --git a/sound/soc/stm/Kconfig b/sound/soc/stm/Kconfig
index 3ad881fc40a1..48f9ddd94016 100644
--- a/sound/soc/stm/Kconfig
+++ b/sound/soc/stm/Kconfig
@@ -2,7 +2,7 @@ menu "STMicroelectronics STM32 SOC audio support"
config SND_SOC_STM32_SAI
tristate "STM32 SAI interface (Serial Audio Interface) support"
- depends on ARCH_STM32 || COMPILE_TEST
+ depends on (ARCH_STM32 && OF) || COMPILE_TEST
depends on SND_SOC
select SND_SOC_GENERIC_DMAENGINE_PCM
select REGMAP_MMIO
@@ -11,7 +11,7 @@ config SND_SOC_STM32_SAI
config SND_SOC_STM32_I2S
tristate "STM32 I2S interface (SPI/I2S block) support"
- depends on ARCH_STM32 || COMPILE_TEST
+ depends on (ARCH_STM32 && OF) || COMPILE_TEST
depends on SND_SOC
select SND_SOC_GENERIC_DMAENGINE_PCM
select REGMAP_MMIO
@@ -20,7 +20,7 @@ config SND_SOC_STM32_I2S
config SND_SOC_STM32_SPDIFRX
tristate "STM32 S/PDIF receiver (SPDIFRX) support"
- depends on ARCH_STM32 || COMPILE_TEST
+ depends on (ARCH_STM32 && OF) || COMPILE_TEST
depends on SND_SOC
select SND_SOC_GENERIC_DMAENGINE_PCM
select REGMAP_MMIO
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index 3dd183be08a4..7a15df924316 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -37,9 +37,11 @@
#define SUN8I_SYSCLK_CTL_SYSCLK_SRC 0
#define SUN8I_MOD_CLK_ENA 0x010
#define SUN8I_MOD_CLK_ENA_AIF1 15
+#define SUN8I_MOD_CLK_ENA_ADC 3
#define SUN8I_MOD_CLK_ENA_DAC 2
#define SUN8I_MOD_RST_CTL 0x014
#define SUN8I_MOD_RST_CTL_AIF1 15
+#define SUN8I_MOD_RST_CTL_ADC 3
#define SUN8I_MOD_RST_CTL_DAC 2
#define SUN8I_SYS_SR_CTRL 0x018
#define SUN8I_SYS_SR_CTRL_AIF1_FS 12
@@ -54,9 +56,25 @@
#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ 4
#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_16 (1 << 4)
#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT 2
+#define SUN8I_AIF1_ADCDAT_CTRL 0x044
+#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_DA0L_ENA 15
+#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_DA0R_ENA 14
#define SUN8I_AIF1_DACDAT_CTRL 0x048
#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA 15
#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA 14
+#define SUN8I_AIF1_MXR_SRC 0x04c
+#define SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF1DA0L 15
+#define SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF2DACL 14
+#define SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_ADCL 13
+#define SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF2DACR 12
+#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R 11
+#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR 10
+#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR 9
+#define SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL 8
+#define SUN8I_ADC_DIG_CTRL 0x100
+#define SUN8I_ADC_DIG_CTRL_ENDA 15
+#define SUN8I_ADC_DIG_CTRL_ADOUT_DTS 2
+#define SUN8I_ADC_DIG_CTRL_ADOUT_DLY 1
#define SUN8I_DAC_DIG_CTRL 0x120
#define SUN8I_DAC_DIG_CTRL_ENDA 15
#define SUN8I_DAC_MXR_SRC 0x130
@@ -338,10 +356,30 @@ static const struct snd_kcontrol_new sun8i_dac_mixer_controls[] = {
SUN8I_DAC_MXR_SRC_DACR_MXR_SRC_ADCR, 1, 0),
};
+static const struct snd_kcontrol_new sun8i_input_mixer_controls[] = {
+ SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital ADC Capture Switch",
+ SUN8I_AIF1_MXR_SRC,
+ SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF1DA0L,
+ SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF1DA0R, 1, 0),
+ SOC_DAPM_DOUBLE("AIF2 Digital ADC Capture Switch", SUN8I_AIF1_MXR_SRC,
+ SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF2DACL,
+ SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACR, 1, 0),
+ SOC_DAPM_DOUBLE("AIF1 Data Digital ADC Capture Switch",
+ SUN8I_AIF1_MXR_SRC,
+ SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_ADCL,
+ SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_ADCR, 1, 0),
+ SOC_DAPM_DOUBLE("AIF2 Inv Digital ADC Capture Switch",
+ SUN8I_AIF1_MXR_SRC,
+ SUN8I_AIF1_MXR_SRC_AD0L_MXL_SRC_AIF2DACR,
+ SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL, 1, 0),
+};
+
static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
- /* Digital parts of the DACs */
+ /* Digital parts of the DACs and ADC */
SND_SOC_DAPM_SUPPLY("DAC", SUN8I_DAC_DIG_CTRL, SUN8I_DAC_DIG_CTRL_ENDA,
0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("ADC", SUN8I_ADC_DIG_CTRL, SUN8I_ADC_DIG_CTRL_ENDA,
+ 0, NULL, 0),
/* Analog DAC AIF */
SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Left", "Playback", 0,
@@ -351,17 +389,31 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
SUN8I_AIF1_DACDAT_CTRL,
SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
- /* DAC Mixers */
+ /* Analog ADC AIF */
+ SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Left ADC", "Capture", 0,
+ SUN8I_AIF1_ADCDAT_CTRL,
+ SUN8I_AIF1_ADCDAT_CTRL_AIF1_DA0L_ENA, 0),
+ SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Right ADC", "Capture", 0,
+ SUN8I_AIF1_ADCDAT_CTRL,
+ SUN8I_AIF1_ADCDAT_CTRL_AIF1_DA0R_ENA, 0),
+
+ /* DAC and ADC Mixers */
SOC_MIXER_ARRAY("Left Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
sun8i_dac_mixer_controls),
SOC_MIXER_ARRAY("Right Digital DAC Mixer", SND_SOC_NOPM, 0, 0,
sun8i_dac_mixer_controls),
+ SOC_MIXER_ARRAY("Left Digital ADC Mixer", SND_SOC_NOPM, 0, 0,
+ sun8i_input_mixer_controls),
+ SOC_MIXER_ARRAY("Right Digital ADC Mixer", SND_SOC_NOPM, 0, 0,
+ sun8i_input_mixer_controls),
/* Clocks */
SND_SOC_DAPM_SUPPLY("MODCLK AFI1", SUN8I_MOD_CLK_ENA,
SUN8I_MOD_CLK_ENA_AIF1, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("MODCLK DAC", SUN8I_MOD_CLK_ENA,
SUN8I_MOD_CLK_ENA_DAC, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("MODCLK ADC", SUN8I_MOD_CLK_ENA,
+ SUN8I_MOD_CLK_ENA_ADC, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("AIF1", SUN8I_SYSCLK_CTL,
SUN8I_SYSCLK_CTL_AIF1CLK_ENA, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("SYSCLK", SUN8I_SYSCLK_CTL,
@@ -378,6 +430,12 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
SUN8I_MOD_RST_CTL_AIF1, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("RST DAC", SUN8I_MOD_RST_CTL,
SUN8I_MOD_RST_CTL_DAC, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("RST ADC", SUN8I_MOD_RST_CTL,
+ SUN8I_MOD_RST_CTL_ADC, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Mic", NULL),
+
};
static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
@@ -387,11 +445,16 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
{ "RST AIF1", NULL, "AIF1 PLL" },
{ "MODCLK AFI1", NULL, "RST AIF1" },
{ "DAC", NULL, "MODCLK AFI1" },
+ { "ADC", NULL, "MODCLK AFI1" },
{ "RST DAC", NULL, "SYSCLK" },
{ "MODCLK DAC", NULL, "RST DAC" },
{ "DAC", NULL, "MODCLK DAC" },
+ { "RST ADC", NULL, "SYSCLK" },
+ { "MODCLK ADC", NULL, "RST ADC" },
+ { "ADC", NULL, "MODCLK ADC" },
+
/* DAC Routes */
{ "AIF1 Slot 0 Right", NULL, "DAC" },
{ "AIF1 Slot 0 Left", NULL, "DAC" },
@@ -401,6 +464,12 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
"AIF1 Slot 0 Left"},
{ "Right Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch",
"AIF1 Slot 0 Right"},
+
+ /* ADC routes */
+ { "Left Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch",
+ "AIF1 Slot 0 Left ADC" },
+ { "Right Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch",
+ "AIF1 Slot 0 Right ADC" },
};
static const struct snd_soc_dai_ops sun8i_codec_dai_ops = {
@@ -418,6 +487,15 @@ static struct snd_soc_dai_driver sun8i_codec_dai = {
.rates = SNDRV_PCM_RATE_8000_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
+ /* capture capabilities */
+ .capture = {
+ .stream_name = "Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .sig_bits = 24,
+ },
/* pcm operations */
.ops = &sun8i_codec_dai_ops,
};
diff --git a/tools/arch/powerpc/include/uapi/asm/kvm.h b/tools/arch/powerpc/include/uapi/asm/kvm.h
index 61d6049f4c1e..637b7263cb86 100644
--- a/tools/arch/powerpc/include/uapi/asm/kvm.h
+++ b/tools/arch/powerpc/include/uapi/asm/kvm.h
@@ -443,6 +443,31 @@ struct kvm_ppc_rmmu_info {
__u32 ap_encodings[8];
};
+/* For KVM_PPC_GET_CPU_CHAR */
+struct kvm_ppc_cpu_char {
+ __u64 character; /* characteristics of the CPU */
+ __u64 behaviour; /* recommended software behaviour */
+ __u64 character_mask; /* valid bits in character */
+ __u64 behaviour_mask; /* valid bits in behaviour */
+};
+
+/*
+ * Values for character and character_mask.
+ * These are identical to the values used by H_GET_CPU_CHARACTERISTICS.
+ */
+#define KVM_PPC_CPU_CHAR_SPEC_BAR_ORI31 (1ULL << 63)
+#define KVM_PPC_CPU_CHAR_BCCTRL_SERIALISED (1ULL << 62)
+#define KVM_PPC_CPU_CHAR_L1D_FLUSH_ORI30 (1ULL << 61)
+#define KVM_PPC_CPU_CHAR_L1D_FLUSH_TRIG2 (1ULL << 60)
+#define KVM_PPC_CPU_CHAR_L1D_THREAD_PRIV (1ULL << 59)
+#define KVM_PPC_CPU_CHAR_BR_HINT_HONOURED (1ULL << 58)
+#define KVM_PPC_CPU_CHAR_MTTRIG_THR_RECONF (1ULL << 57)
+#define KVM_PPC_CPU_CHAR_COUNT_CACHE_DIS (1ULL << 56)
+
+#define KVM_PPC_CPU_BEHAV_FAVOUR_SECURITY (1ULL << 63)
+#define KVM_PPC_CPU_BEHAV_L1D_FLUSH_PR (1ULL << 62)
+#define KVM_PPC_CPU_BEHAV_BNDS_CHK_SPEC_BAR (1ULL << 61)
+
/* Per-vcpu XICS interrupt controller state */
#define KVM_REG_PPC_ICP_STATE (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8c)
diff --git a/tools/arch/s390/include/uapi/asm/kvm.h b/tools/arch/s390/include/uapi/asm/kvm.h
index 38535a57fef8..4cdaa55fabfe 100644
--- a/tools/arch/s390/include/uapi/asm/kvm.h
+++ b/tools/arch/s390/include/uapi/asm/kvm.h
@@ -224,6 +224,7 @@ struct kvm_guest_debug_arch {
#define KVM_SYNC_RICCB (1UL << 7)
#define KVM_SYNC_FPRS (1UL << 8)
#define KVM_SYNC_GSCB (1UL << 9)
+#define KVM_SYNC_BPBC (1UL << 10)
/* length and alignment of the sdnx as a power of two */
#define SDNXC 8
#define SDNXL (1UL << SDNXC)
@@ -247,7 +248,9 @@ struct kvm_sync_regs {
};
__u8 reserved[512]; /* for future vector expansion */
__u32 fpc; /* valid on KVM_SYNC_VRS or KVM_SYNC_FPRS */
- __u8 padding1[52]; /* riccb needs to be 64byte aligned */
+ __u8 bpbc : 1; /* bp mode */
+ __u8 reserved2 : 7;
+ __u8 padding1[51]; /* riccb needs to be 64byte aligned */
__u8 riccb[64]; /* runtime instrumentation controls block */
__u8 padding2[192]; /* sdnx needs to be 256byte aligned */
union {
diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h
index 21ac898df2d8..1d9199e1c2ad 100644
--- a/tools/arch/x86/include/asm/cpufeatures.h
+++ b/tools/arch/x86/include/asm/cpufeatures.h
@@ -13,7 +13,7 @@
/*
* Defines x86 CPU feature bits
*/
-#define NCAPINTS 18 /* N 32-bit words worth of info */
+#define NCAPINTS 19 /* N 32-bit words worth of info */
#define NBUGINTS 1 /* N 32-bit bug flags */
/*
@@ -203,12 +203,15 @@
#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */
#define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation enabled */
+#define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
+#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
#define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */
-#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
-#define X86_FEATURE_AVX512_4VNNIW ( 7*32+16) /* AVX-512 Neural Network Instructions */
-#define X86_FEATURE_AVX512_4FMAPS ( 7*32+17) /* AVX-512 Multiply Accumulation Single precision */
+#define X86_FEATURE_CDP_L2 ( 7*32+15) /* Code and Data Prioritization L2 */
#define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */
+#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
+
+#define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */
/* Virtualization flags: Linux defined, word 8 */
#define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
@@ -243,6 +246,7 @@
#define X86_FEATURE_AVX512IFMA ( 9*32+21) /* AVX-512 Integer Fused Multiply-Add instructions */
#define X86_FEATURE_CLFLUSHOPT ( 9*32+23) /* CLFLUSHOPT instruction */
#define X86_FEATURE_CLWB ( 9*32+24) /* CLWB instruction */
+#define X86_FEATURE_INTEL_PT ( 9*32+25) /* Intel Processor Trace */
#define X86_FEATURE_AVX512PF ( 9*32+26) /* AVX-512 Prefetch */
#define X86_FEATURE_AVX512ER ( 9*32+27) /* AVX-512 Exponential and Reciprocal */
#define X86_FEATURE_AVX512CD ( 9*32+28) /* AVX-512 Conflict Detection */
@@ -268,6 +272,9 @@
#define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */
#define X86_FEATURE_IRPERF (13*32+ 1) /* Instructions Retired Count */
#define X86_FEATURE_XSAVEERPTR (13*32+ 2) /* Always save/restore FP error pointers */
+#define X86_FEATURE_IBPB (13*32+12) /* Indirect Branch Prediction Barrier */
+#define X86_FEATURE_IBRS (13*32+14) /* Indirect Branch Restricted Speculation */
+#define X86_FEATURE_STIBP (13*32+15) /* Single Thread Indirect Branch Predictors */
/* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
#define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
@@ -316,6 +323,13 @@
#define X86_FEATURE_SUCCOR (17*32+ 1) /* Uncorrectable error containment and recovery */
#define X86_FEATURE_SMCA (17*32+ 3) /* Scalable MCA */
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
+#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
+#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
+#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
+#define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
+#define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
+
/*
* BUG word(s)
*/
@@ -342,5 +356,7 @@
#define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake up remote CPU */
#define X86_BUG_AMD_E400 X86_BUG(13) /* CPU is among the affected by Erratum 400 */
#define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */
+#define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */
+#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */
#endif /* _ASM_X86_CPUFEATURES_H */
diff --git a/tools/arch/x86/include/asm/disabled-features.h b/tools/arch/x86/include/asm/disabled-features.h
index b027633e7300..33833d1909af 100644
--- a/tools/arch/x86/include/asm/disabled-features.h
+++ b/tools/arch/x86/include/asm/disabled-features.h
@@ -77,6 +77,7 @@
#define DISABLED_MASK15 0
#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57|DISABLE_UMIP)
#define DISABLED_MASK17 0
-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
+#define DISABLED_MASK18 0
+#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
#endif /* _ASM_X86_DISABLED_FEATURES_H */
diff --git a/tools/arch/x86/include/asm/required-features.h b/tools/arch/x86/include/asm/required-features.h
index d91ba04dd007..fb3a6de7440b 100644
--- a/tools/arch/x86/include/asm/required-features.h
+++ b/tools/arch/x86/include/asm/required-features.h
@@ -106,6 +106,7 @@
#define REQUIRED_MASK15 0
#define REQUIRED_MASK16 (NEED_LA57)
#define REQUIRED_MASK17 0
-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
+#define REQUIRED_MASK18 0
+#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 19)
#endif /* _ASM_X86_REQUIRED_FEATURES_H */
diff --git a/tools/include/asm-generic/bitops/find.h b/tools/include/asm-generic/bitops/find.h
index 9311fadaaab2..16ed1982cb34 100644
--- a/tools/include/asm-generic/bitops/find.h
+++ b/tools/include/asm-generic/bitops/find.h
@@ -16,6 +16,22 @@ extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
size, unsigned long offset);
#endif
+#ifndef find_next_and_bit
+/**
+ * find_next_and_bit - find the next set bit in both memory regions
+ * @addr1: The first address to base the search on
+ * @addr2: The second address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The bitmap size in bits
+ *
+ * Returns the bit number for the next set bit
+ * If no bits are set, returns @size.
+ */
+extern unsigned long find_next_and_bit(const unsigned long *addr1,
+ const unsigned long *addr2, unsigned long size,
+ unsigned long offset);
+#endif
+
#ifndef find_next_zero_bit
/**
diff --git a/tools/include/uapi/linux/if_link.h b/tools/include/uapi/linux/if_link.h
new file mode 100644
index 000000000000..8616131e2c61
--- /dev/null
+++ b/tools/include/uapi/linux/if_link.h
@@ -0,0 +1,943 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#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;
+
+ __u32 rx_nohandler; /* dropped, no handler found */
+};
+
+/* 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;
+
+ __u64 rx_nohandler; /* dropped, no handler found */
+};
+
+/* 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_CARRIER,
+ IFLA_PHYS_PORT_ID,
+ IFLA_CARRIER_CHANGES,
+ IFLA_PHYS_SWITCH_ID,
+ IFLA_LINK_NETNSID,
+ IFLA_PHYS_PORT_NAME,
+ IFLA_PROTO_DOWN,
+ IFLA_GSO_MAX_SEGS,
+ IFLA_GSO_MAX_SIZE,
+ IFLA_PAD,
+ IFLA_XDP,
+ IFLA_EVENT,
+ IFLA_NEW_NETNSID,
+ IFLA_IF_NETNSID,
+ IFLA_CARRIER_UP_COUNT,
+ IFLA_CARRIER_DOWN_COUNT,
+ __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_TOKEN, /* device token */
+ IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
+ __IFLA_INET6_MAX
+};
+
+#define IFLA_INET6_MAX (__IFLA_INET6_MAX - 1)
+
+enum in6_addr_gen_mode {
+ IN6_ADDR_GEN_MODE_EUI64,
+ IN6_ADDR_GEN_MODE_NONE,
+ IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
+ IN6_ADDR_GEN_MODE_RANDOM,
+};
+
+/* Bridge section */
+
+enum {
+ IFLA_BR_UNSPEC,
+ IFLA_BR_FORWARD_DELAY,
+ IFLA_BR_HELLO_TIME,
+ IFLA_BR_MAX_AGE,
+ IFLA_BR_AGEING_TIME,
+ IFLA_BR_STP_STATE,
+ IFLA_BR_PRIORITY,
+ IFLA_BR_VLAN_FILTERING,
+ IFLA_BR_VLAN_PROTOCOL,
+ IFLA_BR_GROUP_FWD_MASK,
+ IFLA_BR_ROOT_ID,
+ IFLA_BR_BRIDGE_ID,
+ IFLA_BR_ROOT_PORT,
+ IFLA_BR_ROOT_PATH_COST,
+ IFLA_BR_TOPOLOGY_CHANGE,
+ IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
+ IFLA_BR_HELLO_TIMER,
+ IFLA_BR_TCN_TIMER,
+ IFLA_BR_TOPOLOGY_CHANGE_TIMER,
+ IFLA_BR_GC_TIMER,
+ IFLA_BR_GROUP_ADDR,
+ IFLA_BR_FDB_FLUSH,
+ IFLA_BR_MCAST_ROUTER,
+ IFLA_BR_MCAST_SNOOPING,
+ IFLA_BR_MCAST_QUERY_USE_IFADDR,
+ IFLA_BR_MCAST_QUERIER,
+ IFLA_BR_MCAST_HASH_ELASTICITY,
+ IFLA_BR_MCAST_HASH_MAX,
+ IFLA_BR_MCAST_LAST_MEMBER_CNT,
+ IFLA_BR_MCAST_STARTUP_QUERY_CNT,
+ IFLA_BR_MCAST_LAST_MEMBER_INTVL,
+ IFLA_BR_MCAST_MEMBERSHIP_INTVL,
+ IFLA_BR_MCAST_QUERIER_INTVL,
+ IFLA_BR_MCAST_QUERY_INTVL,
+ IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
+ IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
+ IFLA_BR_NF_CALL_IPTABLES,
+ IFLA_BR_NF_CALL_IP6TABLES,
+ IFLA_BR_NF_CALL_ARPTABLES,
+ IFLA_BR_VLAN_DEFAULT_PVID,
+ IFLA_BR_PAD,
+ IFLA_BR_VLAN_STATS_ENABLED,
+ IFLA_BR_MCAST_STATS_ENABLED,
+ IFLA_BR_MCAST_IGMP_VERSION,
+ IFLA_BR_MCAST_MLD_VERSION,
+ __IFLA_BR_MAX,
+};
+
+#define IFLA_BR_MAX (__IFLA_BR_MAX - 1)
+
+struct ifla_bridge_id {
+ __u8 prio[2];
+ __u8 addr[6]; /* ETH_ALEN */
+};
+
+enum {
+ BRIDGE_MODE_UNSPEC,
+ BRIDGE_MODE_HAIRPIN,
+};
+
+enum {
+ IFLA_BRPORT_UNSPEC,
+ IFLA_BRPORT_STATE, /* Spanning tree state */
+ IFLA_BRPORT_PRIORITY, /* " priority */
+ IFLA_BRPORT_COST, /* " cost */
+ IFLA_BRPORT_MODE, /* mode (hairpin) */
+ IFLA_BRPORT_GUARD, /* bpdu guard */
+ IFLA_BRPORT_PROTECT, /* root port protection */
+ IFLA_BRPORT_FAST_LEAVE, /* multicast fast leave */
+ IFLA_BRPORT_LEARNING, /* mac learning */
+ IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */
+ IFLA_BRPORT_PROXYARP, /* proxy ARP */
+ IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */
+ IFLA_BRPORT_PROXYARP_WIFI, /* proxy ARP for Wi-Fi */
+ IFLA_BRPORT_ROOT_ID, /* designated root */
+ IFLA_BRPORT_BRIDGE_ID, /* designated bridge */
+ IFLA_BRPORT_DESIGNATED_PORT,
+ IFLA_BRPORT_DESIGNATED_COST,
+ IFLA_BRPORT_ID,
+ IFLA_BRPORT_NO,
+ IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
+ IFLA_BRPORT_CONFIG_PENDING,
+ IFLA_BRPORT_MESSAGE_AGE_TIMER,
+ IFLA_BRPORT_FORWARD_DELAY_TIMER,
+ IFLA_BRPORT_HOLD_TIMER,
+ IFLA_BRPORT_FLUSH,
+ IFLA_BRPORT_MULTICAST_ROUTER,
+ IFLA_BRPORT_PAD,
+ IFLA_BRPORT_MCAST_FLOOD,
+ IFLA_BRPORT_MCAST_TO_UCAST,
+ IFLA_BRPORT_VLAN_TUNNEL,
+ IFLA_BRPORT_BCAST_FLOOD,
+ IFLA_BRPORT_GROUP_FWD_MASK,
+ IFLA_BRPORT_NEIGH_SUPPRESS,
+ __IFLA_BRPORT_MAX
+};
+#define IFLA_BRPORT_MAX (__IFLA_BRPORT_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_SLAVE_KIND,
+ IFLA_INFO_SLAVE_DATA,
+ __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_PROTOCOL,
+ __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_MACADDR_MODE,
+ IFLA_MACVLAN_MACADDR,
+ IFLA_MACVLAN_MACADDR_DATA,
+ IFLA_MACVLAN_MACADDR_COUNT,
+ __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 */
+ MACVLAN_MODE_SOURCE = 16,/* use source MAC address list to assign */
+};
+
+enum macvlan_macaddr_mode {
+ MACVLAN_MACADDR_ADD,
+ MACVLAN_MACADDR_DEL,
+ MACVLAN_MACADDR_FLUSH,
+ MACVLAN_MACADDR_SET,
+};
+
+#define MACVLAN_FLAG_NOPROMISC 1
+
+/* VRF section */
+enum {
+ IFLA_VRF_UNSPEC,
+ IFLA_VRF_TABLE,
+ __IFLA_VRF_MAX
+};
+
+#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1)
+
+enum {
+ IFLA_VRF_PORT_UNSPEC,
+ IFLA_VRF_PORT_TABLE,
+ __IFLA_VRF_PORT_MAX
+};
+
+#define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1)
+
+/* MACSEC section */
+enum {
+ IFLA_MACSEC_UNSPEC,
+ IFLA_MACSEC_SCI,
+ IFLA_MACSEC_PORT,
+ IFLA_MACSEC_ICV_LEN,
+ IFLA_MACSEC_CIPHER_SUITE,
+ IFLA_MACSEC_WINDOW,
+ IFLA_MACSEC_ENCODING_SA,
+ IFLA_MACSEC_ENCRYPT,
+ IFLA_MACSEC_PROTECT,
+ IFLA_MACSEC_INC_SCI,
+ IFLA_MACSEC_ES,
+ IFLA_MACSEC_SCB,
+ IFLA_MACSEC_REPLAY_PROTECT,
+ IFLA_MACSEC_VALIDATION,
+ IFLA_MACSEC_PAD,
+ __IFLA_MACSEC_MAX,
+};
+
+#define IFLA_MACSEC_MAX (__IFLA_MACSEC_MAX - 1)
+
+enum macsec_validation_type {
+ MACSEC_VALIDATE_DISABLED = 0,
+ MACSEC_VALIDATE_CHECK = 1,
+ MACSEC_VALIDATE_STRICT = 2,
+ __MACSEC_VALIDATE_END,
+ MACSEC_VALIDATE_MAX = __MACSEC_VALIDATE_END - 1,
+};
+
+/* IPVLAN section */
+enum {
+ IFLA_IPVLAN_UNSPEC,
+ IFLA_IPVLAN_MODE,
+ IFLA_IPVLAN_FLAGS,
+ __IFLA_IPVLAN_MAX
+};
+
+#define IFLA_IPVLAN_MAX (__IFLA_IPVLAN_MAX - 1)
+
+enum ipvlan_mode {
+ IPVLAN_MODE_L2 = 0,
+ IPVLAN_MODE_L3,
+ IPVLAN_MODE_L3S,
+ IPVLAN_MODE_MAX
+};
+
+#define IPVLAN_F_PRIVATE 0x01
+#define IPVLAN_F_VEPA 0x02
+
+/* VXLAN section */
+enum {
+ IFLA_VXLAN_UNSPEC,
+ IFLA_VXLAN_ID,
+ IFLA_VXLAN_GROUP, /* group or remote address */
+ 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, /* source port */
+ IFLA_VXLAN_PROXY,
+ IFLA_VXLAN_RSC,
+ IFLA_VXLAN_L2MISS,
+ IFLA_VXLAN_L3MISS,
+ IFLA_VXLAN_PORT, /* destination port */
+ IFLA_VXLAN_GROUP6,
+ IFLA_VXLAN_LOCAL6,
+ IFLA_VXLAN_UDP_CSUM,
+ IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
+ IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
+ IFLA_VXLAN_REMCSUM_TX,
+ IFLA_VXLAN_REMCSUM_RX,
+ IFLA_VXLAN_GBP,
+ IFLA_VXLAN_REMCSUM_NOPARTIAL,
+ IFLA_VXLAN_COLLECT_METADATA,
+ IFLA_VXLAN_LABEL,
+ IFLA_VXLAN_GPE,
+ __IFLA_VXLAN_MAX
+};
+#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
+
+struct ifla_vxlan_port_range {
+ __be16 low;
+ __be16 high;
+};
+
+/* GENEVE section */
+enum {
+ IFLA_GENEVE_UNSPEC,
+ IFLA_GENEVE_ID,
+ IFLA_GENEVE_REMOTE,
+ IFLA_GENEVE_TTL,
+ IFLA_GENEVE_TOS,
+ IFLA_GENEVE_PORT, /* destination port */
+ IFLA_GENEVE_COLLECT_METADATA,
+ IFLA_GENEVE_REMOTE6,
+ IFLA_GENEVE_UDP_CSUM,
+ IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
+ IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
+ IFLA_GENEVE_LABEL,
+ __IFLA_GENEVE_MAX
+};
+#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
+
+/* PPP section */
+enum {
+ IFLA_PPP_UNSPEC,
+ IFLA_PPP_DEV_FD,
+ __IFLA_PPP_MAX
+};
+#define IFLA_PPP_MAX (__IFLA_PPP_MAX - 1)
+
+/* GTP section */
+
+enum ifla_gtp_role {
+ GTP_ROLE_GGSN = 0,
+ GTP_ROLE_SGSN,
+};
+
+enum {
+ IFLA_GTP_UNSPEC,
+ IFLA_GTP_FD0,
+ IFLA_GTP_FD1,
+ IFLA_GTP_PDP_HASHSIZE,
+ IFLA_GTP_ROLE,
+ __IFLA_GTP_MAX,
+};
+#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
+
+/* Bonding section */
+
+enum {
+ IFLA_BOND_UNSPEC,
+ IFLA_BOND_MODE,
+ IFLA_BOND_ACTIVE_SLAVE,
+ IFLA_BOND_MIIMON,
+ IFLA_BOND_UPDELAY,
+ IFLA_BOND_DOWNDELAY,
+ IFLA_BOND_USE_CARRIER,
+ IFLA_BOND_ARP_INTERVAL,
+ IFLA_BOND_ARP_IP_TARGET,
+ IFLA_BOND_ARP_VALIDATE,
+ IFLA_BOND_ARP_ALL_TARGETS,
+ IFLA_BOND_PRIMARY,
+ IFLA_BOND_PRIMARY_RESELECT,
+ IFLA_BOND_FAIL_OVER_MAC,
+ IFLA_BOND_XMIT_HASH_POLICY,
+ IFLA_BOND_RESEND_IGMP,
+ IFLA_BOND_NUM_PEER_NOTIF,
+ IFLA_BOND_ALL_SLAVES_ACTIVE,
+ IFLA_BOND_MIN_LINKS,
+ IFLA_BOND_LP_INTERVAL,
+ IFLA_BOND_PACKETS_PER_SLAVE,
+ IFLA_BOND_AD_LACP_RATE,
+ IFLA_BOND_AD_SELECT,
+ IFLA_BOND_AD_INFO,
+ IFLA_BOND_AD_ACTOR_SYS_PRIO,
+ IFLA_BOND_AD_USER_PORT_KEY,
+ IFLA_BOND_AD_ACTOR_SYSTEM,
+ IFLA_BOND_TLB_DYNAMIC_LB,
+ __IFLA_BOND_MAX,
+};
+
+#define IFLA_BOND_MAX (__IFLA_BOND_MAX - 1)
+
+enum {
+ IFLA_BOND_AD_INFO_UNSPEC,
+ IFLA_BOND_AD_INFO_AGGREGATOR,
+ IFLA_BOND_AD_INFO_NUM_PORTS,
+ IFLA_BOND_AD_INFO_ACTOR_KEY,
+ IFLA_BOND_AD_INFO_PARTNER_KEY,
+ IFLA_BOND_AD_INFO_PARTNER_MAC,
+ __IFLA_BOND_AD_INFO_MAX,
+};
+
+#define IFLA_BOND_AD_INFO_MAX (__IFLA_BOND_AD_INFO_MAX - 1)
+
+enum {
+ IFLA_BOND_SLAVE_UNSPEC,
+ IFLA_BOND_SLAVE_STATE,
+ IFLA_BOND_SLAVE_MII_STATUS,
+ IFLA_BOND_SLAVE_LINK_FAILURE_COUNT,
+ IFLA_BOND_SLAVE_PERM_HWADDR,
+ IFLA_BOND_SLAVE_QUEUE_ID,
+ IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
+ IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
+ IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
+ __IFLA_BOND_SLAVE_MAX,
+};
+
+#define IFLA_BOND_SLAVE_MAX (__IFLA_BOND_SLAVE_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, /* VLAN ID and QoS */
+ IFLA_VF_TX_RATE, /* Max TX Bandwidth Allocation */
+ IFLA_VF_SPOOFCHK, /* Spoof Checking on/off switch */
+ IFLA_VF_LINK_STATE, /* link state enable/disable/auto switch */
+ IFLA_VF_RATE, /* Min and Max TX Bandwidth Allocation */
+ IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query
+ * on/off switch
+ */
+ IFLA_VF_STATS, /* network device statistics */
+ IFLA_VF_TRUST, /* Trust VF */
+ IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */
+ IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */
+ IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */
+ __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;
+};
+
+enum {
+ IFLA_VF_VLAN_INFO_UNSPEC,
+ IFLA_VF_VLAN_INFO, /* VLAN ID, QoS and VLAN protocol */
+ __IFLA_VF_VLAN_INFO_MAX,
+};
+
+#define IFLA_VF_VLAN_INFO_MAX (__IFLA_VF_VLAN_INFO_MAX - 1)
+#define MAX_VLAN_LIST_LEN 1
+
+struct ifla_vf_vlan_info {
+ __u32 vf;
+ __u32 vlan; /* 0 - 4095, 0 disables VLAN filter */
+ __u32 qos;
+ __be16 vlan_proto; /* VLAN protocol either 802.1Q or 802.1ad */
+};
+
+struct ifla_vf_tx_rate {
+ __u32 vf;
+ __u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
+};
+
+struct ifla_vf_rate {
+ __u32 vf;
+ __u32 min_tx_rate; /* Min Bandwidth in Mbps */
+ __u32 max_tx_rate; /* Max Bandwidth in Mbps */
+};
+
+struct ifla_vf_spoofchk {
+ __u32 vf;
+ __u32 setting;
+};
+
+struct ifla_vf_guid {
+ __u32 vf;
+ __u64 guid;
+};
+
+enum {
+ IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */
+ IFLA_VF_LINK_STATE_ENABLE, /* link always up */
+ IFLA_VF_LINK_STATE_DISABLE, /* link always down */
+ __IFLA_VF_LINK_STATE_MAX,
+};
+
+struct ifla_vf_link_state {
+ __u32 vf;
+ __u32 link_state;
+};
+
+struct ifla_vf_rss_query_en {
+ __u32 vf;
+ __u32 setting;
+};
+
+enum {
+ IFLA_VF_STATS_RX_PACKETS,
+ IFLA_VF_STATS_TX_PACKETS,
+ IFLA_VF_STATS_RX_BYTES,
+ IFLA_VF_STATS_TX_BYTES,
+ IFLA_VF_STATS_BROADCAST,
+ IFLA_VF_STATS_MULTICAST,
+ IFLA_VF_STATS_PAD,
+ IFLA_VF_STATS_RX_DROPPED,
+ IFLA_VF_STATS_TX_DROPPED,
+ __IFLA_VF_STATS_MAX,
+};
+
+#define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1)
+
+struct ifla_vf_trust {
+ __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)
+
+
+/* HSR section */
+
+enum {
+ IFLA_HSR_UNSPEC,
+ IFLA_HSR_SLAVE1,
+ IFLA_HSR_SLAVE2,
+ IFLA_HSR_MULTICAST_SPEC, /* Last byte of supervision addr */
+ IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */
+ IFLA_HSR_SEQ_NR,
+ IFLA_HSR_VERSION, /* HSR version */
+ __IFLA_HSR_MAX,
+};
+
+#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
+
+/* STATS section */
+
+struct if_stats_msg {
+ __u8 family;
+ __u8 pad1;
+ __u16 pad2;
+ __u32 ifindex;
+ __u32 filter_mask;
+};
+
+/* A stats attribute can be netdev specific or a global stat.
+ * For netdev stats, lets use the prefix IFLA_STATS_LINK_*
+ */
+enum {
+ IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */
+ IFLA_STATS_LINK_64,
+ IFLA_STATS_LINK_XSTATS,
+ IFLA_STATS_LINK_XSTATS_SLAVE,
+ IFLA_STATS_LINK_OFFLOAD_XSTATS,
+ IFLA_STATS_AF_SPEC,
+ __IFLA_STATS_MAX,
+};
+
+#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1)
+
+#define IFLA_STATS_FILTER_BIT(ATTR) (1 << (ATTR - 1))
+
+/* These are embedded into IFLA_STATS_LINK_XSTATS:
+ * [IFLA_STATS_LINK_XSTATS]
+ * -> [LINK_XSTATS_TYPE_xxx]
+ * -> [rtnl link type specific attributes]
+ */
+enum {
+ LINK_XSTATS_TYPE_UNSPEC,
+ LINK_XSTATS_TYPE_BRIDGE,
+ __LINK_XSTATS_TYPE_MAX
+};
+#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)
+
+/* These are stats embedded into IFLA_STATS_LINK_OFFLOAD_XSTATS */
+enum {
+ IFLA_OFFLOAD_XSTATS_UNSPEC,
+ IFLA_OFFLOAD_XSTATS_CPU_HIT, /* struct rtnl_link_stats64 */
+ __IFLA_OFFLOAD_XSTATS_MAX
+};
+#define IFLA_OFFLOAD_XSTATS_MAX (__IFLA_OFFLOAD_XSTATS_MAX - 1)
+
+/* XDP section */
+
+#define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0)
+#define XDP_FLAGS_SKB_MODE (1U << 1)
+#define XDP_FLAGS_DRV_MODE (1U << 2)
+#define XDP_FLAGS_HW_MODE (1U << 3)
+#define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | \
+ XDP_FLAGS_DRV_MODE | \
+ XDP_FLAGS_HW_MODE)
+#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \
+ XDP_FLAGS_MODES)
+
+/* These are stored into IFLA_XDP_ATTACHED on dump. */
+enum {
+ XDP_ATTACHED_NONE = 0,
+ XDP_ATTACHED_DRV,
+ XDP_ATTACHED_SKB,
+ XDP_ATTACHED_HW,
+};
+
+enum {
+ IFLA_XDP_UNSPEC,
+ IFLA_XDP_FD,
+ IFLA_XDP_ATTACHED,
+ IFLA_XDP_FLAGS,
+ IFLA_XDP_PROG_ID,
+ __IFLA_XDP_MAX,
+};
+
+#define IFLA_XDP_MAX (__IFLA_XDP_MAX - 1)
+
+enum {
+ IFLA_EVENT_NONE,
+ IFLA_EVENT_REBOOT, /* internal reset / reboot */
+ IFLA_EVENT_FEATURES, /* change in offload features */
+ IFLA_EVENT_BONDING_FAILOVER, /* change in active slave */
+ IFLA_EVENT_NOTIFY_PEERS, /* re-sent grat. arp/ndisc */
+ IFLA_EVENT_IGMP_RESEND, /* re-sent IGMP JOIN */
+ IFLA_EVENT_BONDING_OPTIONS, /* change in bonding options */
+};
+
+#endif /* _UAPI_LINUX_IF_LINK_H */
diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h
index 496e59a2738b..8fb90a0819c3 100644
--- a/tools/include/uapi/linux/kvm.h
+++ b/tools/include/uapi/linux/kvm.h
@@ -932,6 +932,8 @@ struct kvm_ppc_resize_hpt {
#define KVM_CAP_HYPERV_SYNIC2 148
#define KVM_CAP_HYPERV_VP_INDEX 149
#define KVM_CAP_S390_AIS_MIGRATION 150
+#define KVM_CAP_PPC_GET_CPU_CHAR 151
+#define KVM_CAP_S390_BPB 152
#ifdef KVM_CAP_IRQ_ROUTING
@@ -1261,6 +1263,8 @@ struct kvm_s390_ucas_mapping {
#define KVM_PPC_CONFIGURE_V3_MMU _IOW(KVMIO, 0xaf, struct kvm_ppc_mmuv3_cfg)
/* Available with KVM_CAP_PPC_RADIX_MMU */
#define KVM_PPC_GET_RMMU_INFO _IOW(KVMIO, 0xb0, struct kvm_ppc_rmmu_info)
+/* Available with KVM_CAP_PPC_GET_CPU_CHAR */
+#define KVM_PPC_GET_CPU_CHAR _IOR(KVMIO, 0xb1, struct kvm_ppc_cpu_char)
/* ioctl for vm fd */
#define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device)
diff --git a/tools/include/uapi/linux/netlink.h b/tools/include/uapi/linux/netlink.h
new file mode 100644
index 000000000000..776bc92e9118
--- /dev/null
+++ b/tools/include/uapi/linux/netlink.h
@@ -0,0 +1,251 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI__LINUX_NETLINK_H
+#define _UAPI__LINUX_NETLINK_H
+
+#include <linux/kernel.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_SMC 22 /* SMC monitoring */
+
+#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 0x01 /* It is request message. */
+#define NLM_F_MULTI 0x02 /* Multipart message, terminated by NLMSG_DONE */
+#define NLM_F_ACK 0x04 /* Reply with ack, with zero or error code */
+#define NLM_F_ECHO 0x08 /* Echo this request */
+#define NLM_F_DUMP_INTR 0x10 /* Dump was inconsistent due to sequence change */
+#define NLM_F_DUMP_FILTERED 0x20 /* Dump was filtered as requested */
+
+/* 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 */
+
+/* Modifiers to DELETE request */
+#define NLM_F_NONREC 0x100 /* Do not delete recursively */
+
+/* Flags for ACK message */
+#define NLM_F_CAPPED 0x100 /* request was capped */
+#define NLM_F_ACK_TLVS 0x200 /* extended ACK TVLs were included */
+
+/*
+ 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_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;
+ /*
+ * followed by the message contents unless NETLINK_CAP_ACK was set
+ * or the ACK indicates success (error == 0)
+ * message length is aligned with NLMSG_ALIGN()
+ */
+ /*
+ * followed by TLVs defined in enum nlmsgerr_attrs
+ * if NETLINK_EXT_ACK was set
+ */
+};
+
+/**
+ * enum nlmsgerr_attrs - nlmsgerr attributes
+ * @NLMSGERR_ATTR_UNUSED: unused
+ * @NLMSGERR_ATTR_MSG: error message string (string)
+ * @NLMSGERR_ATTR_OFFS: offset of the invalid attribute in the original
+ * message, counting from the beginning of the header (u32)
+ * @NLMSGERR_ATTR_COOKIE: arbitrary subsystem specific cookie to
+ * be used - in the success case - to identify a created
+ * object or operation or similar (binary)
+ * @__NLMSGERR_ATTR_MAX: number of attributes
+ * @NLMSGERR_ATTR_MAX: highest attribute number
+ */
+enum nlmsgerr_attrs {
+ NLMSGERR_ATTR_UNUSED,
+ NLMSGERR_ATTR_MSG,
+ NLMSGERR_ATTR_OFFS,
+ NLMSGERR_ATTR_COOKIE,
+
+ __NLMSGERR_ATTR_MAX,
+ NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
+};
+
+#define NETLINK_ADD_MEMBERSHIP 1
+#define NETLINK_DROP_MEMBERSHIP 2
+#define NETLINK_PKTINFO 3
+#define NETLINK_BROADCAST_ERROR 4
+#define NETLINK_NO_ENOBUFS 5
+#ifndef __KERNEL__
+#define NETLINK_RX_RING 6
+#define NETLINK_TX_RING 7
+#endif
+#define NETLINK_LISTEN_ALL_NSID 8
+#define NETLINK_LIST_MEMBERSHIPS 9
+#define NETLINK_CAP_ACK 10
+#define NETLINK_EXT_ACK 11
+
+struct nl_pktinfo {
+ __u32 group;
+};
+
+struct nl_mmap_req {
+ unsigned int nm_block_size;
+ unsigned int nm_block_nr;
+ unsigned int nm_frame_size;
+ unsigned int nm_frame_nr;
+};
+
+struct nl_mmap_hdr {
+ unsigned int nm_status;
+ unsigned int nm_len;
+ __u32 nm_group;
+ /* credentials */
+ __u32 nm_pid;
+ __u32 nm_uid;
+ __u32 nm_gid;
+};
+
+#ifndef __KERNEL__
+enum nl_mmap_status {
+ NL_MMAP_STATUS_UNUSED,
+ NL_MMAP_STATUS_RESERVED,
+ NL_MMAP_STATUS_VALID,
+ NL_MMAP_STATUS_COPY,
+ NL_MMAP_STATUS_SKIP,
+};
+
+#define NL_MMAP_MSG_ALIGNMENT NLMSG_ALIGNTO
+#define NL_MMAP_MSG_ALIGN(sz) __ALIGN_KERNEL(sz, NL_MMAP_MSG_ALIGNMENT)
+#define NL_MMAP_HDRLEN NL_MMAP_MSG_ALIGN(sizeof(struct nl_mmap_hdr))
+#endif
+
+#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)))
+
+/* Generic 32 bitflags attribute content sent to the kernel.
+ *
+ * The value is a bitmap that defines the values being set
+ * The selector is a bitmask that defines which value is legit
+ *
+ * Examples:
+ * value = 0x0, and selector = 0x1
+ * implies we are selecting bit 1 and we want to set its value to 0.
+ *
+ * value = 0x2, and selector = 0x2
+ * implies we are selecting bit 2 and we want to set its value to 1.
+ *
+ */
+struct nla_bitfield32 {
+ __u32 value;
+ __u32 selector;
+};
+
+#endif /* _UAPI__LINUX_NETLINK_H */
diff --git a/tools/include/uapi/linux/sched.h b/tools/include/uapi/linux/sched.h
index 30a9e51bbb1e..22627f80063e 100644
--- a/tools/include/uapi/linux/sched.h
+++ b/tools/include/uapi/linux/sched.h
@@ -49,5 +49,10 @@
*/
#define SCHED_FLAG_RESET_ON_FORK 0x01
#define SCHED_FLAG_RECLAIM 0x02
+#define SCHED_FLAG_DL_OVERRUN 0x04
+
+#define SCHED_FLAG_ALL (SCHED_FLAG_RESET_ON_FORK | \
+ SCHED_FLAG_RECLAIM | \
+ SCHED_FLAG_DL_OVERRUN)
#endif /* _UAPI_LINUX_SCHED_H */
diff --git a/tools/include/uapi/sound/asound.h b/tools/include/uapi/sound/asound.h
index c227ccba60ae..07d61583fd02 100644
--- a/tools/include/uapi/sound/asound.h
+++ b/tools/include/uapi/sound/asound.h
@@ -214,6 +214,11 @@ typedef int __bitwise snd_pcm_format_t;
#define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22)
#define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23)
#define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24)
+#define SNDRV_PCM_FORMAT_S20_LE ((__force snd_pcm_format_t) 25) /* in four bytes, LSB justified */
+#define SNDRV_PCM_FORMAT_S20_BE ((__force snd_pcm_format_t) 26) /* in four bytes, LSB justified */
+#define SNDRV_PCM_FORMAT_U20_LE ((__force snd_pcm_format_t) 27) /* in four bytes, LSB justified */
+#define SNDRV_PCM_FORMAT_U20_BE ((__force snd_pcm_format_t) 28) /* in four bytes, LSB justified */
+/* gap in the numbering for a future standard linear format */
#define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31)
#define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32) /* in three bytes */
#define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33) /* in three bytes */
@@ -248,6 +253,8 @@ typedef int __bitwise snd_pcm_format_t;
#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_LE
#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_LE
#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
+#define SNDRV_PCM_FORMAT_S20 SNDRV_PCM_FORMAT_S20_LE
+#define SNDRV_PCM_FORMAT_U20 SNDRV_PCM_FORMAT_U20_LE
#endif
#ifdef SNDRV_BIG_ENDIAN
#define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_BE
@@ -259,6 +266,8 @@ typedef int __bitwise snd_pcm_format_t;
#define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_BE
#define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_BE
#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE
+#define SNDRV_PCM_FORMAT_S20 SNDRV_PCM_FORMAT_S20_BE
+#define SNDRV_PCM_FORMAT_U20 SNDRV_PCM_FORMAT_U20_BE
#endif
typedef int __bitwise snd_pcm_subformat_t;
diff --git a/tools/lib/bpf/Build b/tools/lib/bpf/Build
index d8749756352d..64c679d67109 100644
--- a/tools/lib/bpf/Build
+++ b/tools/lib/bpf/Build
@@ -1 +1 @@
-libbpf-y := libbpf.o bpf.o
+libbpf-y := libbpf.o bpf.o nlattr.o
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index 83714ca1f22b..e6d5f8d1477f 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -160,6 +160,12 @@ $(BPF_IN): force elfdep bpfdep
@(test -f ../../include/uapi/linux/bpf_common.h -a -f ../../../include/uapi/linux/bpf_common.h && ( \
(diff -B ../../include/uapi/linux/bpf_common.h ../../../include/uapi/linux/bpf_common.h >/dev/null) || \
echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/bpf_common.h' differs from latest version at 'include/uapi/linux/bpf_common.h'" >&2 )) || true
+ @(test -f ../../include/uapi/linux/netlink.h -a -f ../../../include/uapi/linux/netlink.h && ( \
+ (diff -B ../../include/uapi/linux/netlink.h ../../../include/uapi/linux/netlink.h >/dev/null) || \
+ echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/netlink.h' differs from latest version at 'include/uapi/linux/netlink.h'" >&2 )) || true
+ @(test -f ../../include/uapi/linux/if_link.h -a -f ../../../include/uapi/linux/if_link.h && ( \
+ (diff -B ../../include/uapi/linux/if_link.h ../../../include/uapi/linux/if_link.h >/dev/null) || \
+ echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_link.h' differs from latest version at 'include/uapi/linux/if_link.h'" >&2 )) || true
$(Q)$(MAKE) $(build)=libbpf
$(OUTPUT)libbpf.so: $(BPF_IN)
diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c
index 5128677e4117..592a58a2b681 100644
--- a/tools/lib/bpf/bpf.c
+++ b/tools/lib/bpf/bpf.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: LGPL-2.1
+
/*
* common eBPF ELF operations.
*
@@ -25,6 +27,16 @@
#include <asm/unistd.h>
#include <linux/bpf.h>
#include "bpf.h"
+#include "libbpf.h"
+#include "nlattr.h"
+#include <linux/rtnetlink.h>
+#include <linux/if_link.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
/*
* When building perf, unistd.h is overridden. __NR_bpf is
@@ -46,7 +58,9 @@
# endif
#endif
+#ifndef min
#define min(x, y) ((x) < (y) ? (x) : (y))
+#endif
static inline __u64 ptr_to_u64(const void *ptr)
{
@@ -413,3 +427,124 @@ int bpf_obj_get_info_by_fd(int prog_fd, void *info, __u32 *info_len)
return err;
}
+
+int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
+{
+ struct sockaddr_nl sa;
+ int sock, seq = 0, len, ret = -1;
+ char buf[4096];
+ struct nlattr *nla, *nla_xdp;
+ struct {
+ struct nlmsghdr nh;
+ struct ifinfomsg ifinfo;
+ char attrbuf[64];
+ } req;
+ struct nlmsghdr *nh;
+ struct nlmsgerr *err;
+ socklen_t addrlen;
+ int one = 1;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.nl_family = AF_NETLINK;
+
+ sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (sock < 0) {
+ return -errno;
+ }
+
+ if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK,
+ &one, sizeof(one)) < 0) {
+ fprintf(stderr, "Netlink error reporting not supported\n");
+ }
+
+ if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+ addrlen = sizeof(sa);
+ if (getsockname(sock, (struct sockaddr *)&sa, &addrlen) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+ if (addrlen != sizeof(sa)) {
+ ret = -LIBBPF_ERRNO__INTERNAL;
+ goto cleanup;
+ }
+
+ memset(&req, 0, sizeof(req));
+ req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ req.nh.nlmsg_type = RTM_SETLINK;
+ req.nh.nlmsg_pid = 0;
+ req.nh.nlmsg_seq = ++seq;
+ req.ifinfo.ifi_family = AF_UNSPEC;
+ req.ifinfo.ifi_index = ifindex;
+
+ /* started nested attribute for XDP */
+ nla = (struct nlattr *)(((char *)&req)
+ + NLMSG_ALIGN(req.nh.nlmsg_len));
+ nla->nla_type = NLA_F_NESTED | IFLA_XDP;
+ nla->nla_len = NLA_HDRLEN;
+
+ /* add XDP fd */
+ nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
+ nla_xdp->nla_type = IFLA_XDP_FD;
+ nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
+ memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
+ nla->nla_len += nla_xdp->nla_len;
+
+ /* if user passed in any flags, add those too */
+ if (flags) {
+ nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
+ nla_xdp->nla_type = IFLA_XDP_FLAGS;
+ nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
+ memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
+ nla->nla_len += nla_xdp->nla_len;
+ }
+
+ req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
+
+ if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+ len = recv(sock, buf, sizeof(buf), 0);
+ if (len < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+ for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
+ nh = NLMSG_NEXT(nh, len)) {
+ if (nh->nlmsg_pid != sa.nl_pid) {
+ ret = -LIBBPF_ERRNO__WRNGPID;
+ goto cleanup;
+ }
+ if (nh->nlmsg_seq != seq) {
+ ret = -LIBBPF_ERRNO__INVSEQ;
+ goto cleanup;
+ }
+ switch (nh->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = (struct nlmsgerr *)NLMSG_DATA(nh);
+ if (!err->error)
+ continue;
+ ret = err->error;
+ nla_dump_errormsg(nh);
+ goto cleanup;
+ case NLMSG_DONE:
+ break;
+ default:
+ break;
+ }
+ }
+
+ ret = 0;
+
+cleanup:
+ close(sock);
+ return ret;
+}
diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h
index 9f44c196931e..8d18fb73d7fb 100644
--- a/tools/lib/bpf/bpf.h
+++ b/tools/lib/bpf/bpf.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+
/*
* common eBPF ELF operations.
*
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 30c776375118..71ddc481f349 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: LGPL-2.1
+
/*
* Common eBPF ELF object loading operations.
*
@@ -106,6 +108,8 @@ static const char *libbpf_strerror_table[NR_ERRNO] = {
[ERRCODE_OFFSET(PROG2BIG)] = "Program too big",
[ERRCODE_OFFSET(KVER)] = "Incorrect kernel version",
[ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type",
+ [ERRCODE_OFFSET(WRNGPID)] = "Wrong pid in netlink message",
+ [ERRCODE_OFFSET(INVSEQ)] = "Invalid netlink sequence",
};
int libbpf_strerror(int err, char *buf, size_t size)
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 6e20003109e0..f85906533cdd 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+
/*
* Common eBPF ELF object loading operations.
*
@@ -42,6 +44,8 @@ enum libbpf_errno {
LIBBPF_ERRNO__PROG2BIG, /* Program too big */
LIBBPF_ERRNO__KVER, /* Incorrect kernel version */
LIBBPF_ERRNO__PROGTYPE, /* Kernel doesn't support this program type */
+ LIBBPF_ERRNO__WRNGPID, /* Wrong pid in netlink message */
+ LIBBPF_ERRNO__INVSEQ, /* Invalid netlink sequence */
__LIBBPF_ERRNO__END,
};
@@ -246,4 +250,6 @@ long libbpf_get_error(const void *ptr);
int bpf_prog_load(const char *file, enum bpf_prog_type type,
struct bpf_object **pobj, int *prog_fd);
+
+int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
#endif
diff --git a/tools/lib/bpf/nlattr.c b/tools/lib/bpf/nlattr.c
new file mode 100644
index 000000000000..4719434278b2
--- /dev/null
+++ b/tools/lib/bpf/nlattr.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: LGPL-2.1
+
+/*
+ * NETLINK Netlink attributes
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
+ */
+
+#include <errno.h>
+#include "nlattr.h"
+#include <linux/rtnetlink.h>
+#include <string.h>
+#include <stdio.h>
+
+static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
+ [NLA_U8] = sizeof(uint8_t),
+ [NLA_U16] = sizeof(uint16_t),
+ [NLA_U32] = sizeof(uint32_t),
+ [NLA_U64] = sizeof(uint64_t),
+ [NLA_STRING] = 1,
+ [NLA_FLAG] = 0,
+};
+
+static int nla_len(const struct nlattr *nla)
+{
+ return nla->nla_len - NLA_HDRLEN;
+}
+
+static struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
+{
+ int totlen = NLA_ALIGN(nla->nla_len);
+
+ *remaining -= totlen;
+ return (struct nlattr *) ((char *) nla + totlen);
+}
+
+static int nla_ok(const struct nlattr *nla, int remaining)
+{
+ return remaining >= sizeof(*nla) &&
+ nla->nla_len >= sizeof(*nla) &&
+ nla->nla_len <= remaining;
+}
+
+static void *nla_data(const struct nlattr *nla)
+{
+ return (char *) nla + NLA_HDRLEN;
+}
+
+static int nla_type(const struct nlattr *nla)
+{
+ return nla->nla_type & NLA_TYPE_MASK;
+}
+
+static int validate_nla(struct nlattr *nla, int maxtype,
+ struct nla_policy *policy)
+{
+ struct nla_policy *pt;
+ unsigned int minlen = 0;
+ int type = nla_type(nla);
+
+ if (type < 0 || type > maxtype)
+ return 0;
+
+ pt = &policy[type];
+
+ if (pt->type > NLA_TYPE_MAX)
+ return 0;
+
+ if (pt->minlen)
+ minlen = pt->minlen;
+ else if (pt->type != NLA_UNSPEC)
+ minlen = nla_attr_minlen[pt->type];
+
+ if (nla_len(nla) < minlen)
+ return -1;
+
+ if (pt->maxlen && nla_len(nla) > pt->maxlen)
+ return -1;
+
+ if (pt->type == NLA_STRING) {
+ char *data = nla_data(nla);
+ if (data[nla_len(nla) - 1] != '\0')
+ return -1;
+ }
+
+ return 0;
+}
+
+static inline int nlmsg_len(const struct nlmsghdr *nlh)
+{
+ return nlh->nlmsg_len - NLMSG_HDRLEN;
+}
+
+/**
+ * Create attribute index based on a stream of attributes.
+ * @arg tb Index array to be filled (maxtype+1 elements).
+ * @arg maxtype Maximum attribute type expected and accepted.
+ * @arg head Head of attribute stream.
+ * @arg len Length of attribute stream.
+ * @arg policy Attribute validation policy.
+ *
+ * Iterates over the stream of attributes and stores a pointer to each
+ * attribute in the index array using the attribute type as index to
+ * the array. Attribute with a type greater than the maximum type
+ * specified will be silently ignored in order to maintain backwards
+ * compatibility. If \a policy is not NULL, the attribute will be
+ * validated using the specified policy.
+ *
+ * @see nla_validate
+ * @return 0 on success or a negative error code.
+ */
+static int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len,
+ struct nla_policy *policy)
+{
+ struct nlattr *nla;
+ int rem, err;
+
+ memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
+
+ nla_for_each_attr(nla, head, len, rem) {
+ int type = nla_type(nla);
+
+ if (type > maxtype)
+ continue;
+
+ if (policy) {
+ err = validate_nla(nla, maxtype, policy);
+ if (err < 0)
+ goto errout;
+ }
+
+ if (tb[type])
+ fprintf(stderr, "Attribute of type %#x found multiple times in message, "
+ "previous attribute is being ignored.\n", type);
+
+ tb[type] = nla;
+ }
+
+ err = 0;
+errout:
+ return err;
+}
+
+/* dump netlink extended ack error message */
+int nla_dump_errormsg(struct nlmsghdr *nlh)
+{
+ struct nla_policy extack_policy[NLMSGERR_ATTR_MAX + 1] = {
+ [NLMSGERR_ATTR_MSG] = { .type = NLA_STRING },
+ [NLMSGERR_ATTR_OFFS] = { .type = NLA_U32 },
+ };
+ struct nlattr *tb[NLMSGERR_ATTR_MAX + 1], *attr;
+ struct nlmsgerr *err;
+ char *errmsg = NULL;
+ int hlen, alen;
+
+ /* no TLVs, nothing to do here */
+ if (!(nlh->nlmsg_flags & NLM_F_ACK_TLVS))
+ return 0;
+
+ err = (struct nlmsgerr *)NLMSG_DATA(nlh);
+ hlen = sizeof(*err);
+
+ /* if NLM_F_CAPPED is set then the inner err msg was capped */
+ if (!(nlh->nlmsg_flags & NLM_F_CAPPED))
+ hlen += nlmsg_len(&err->msg);
+
+ attr = (struct nlattr *) ((void *) err + hlen);
+ alen = nlh->nlmsg_len - hlen;
+
+ if (nla_parse(tb, NLMSGERR_ATTR_MAX, attr, alen, extack_policy) != 0) {
+ fprintf(stderr,
+ "Failed to parse extended error attributes\n");
+ return 0;
+ }
+
+ if (tb[NLMSGERR_ATTR_MSG])
+ errmsg = (char *) nla_data(tb[NLMSGERR_ATTR_MSG]);
+
+ fprintf(stderr, "Kernel error message: %s\n", errmsg);
+
+ return 0;
+}
diff --git a/tools/lib/bpf/nlattr.h b/tools/lib/bpf/nlattr.h
new file mode 100644
index 000000000000..931a71f68f93
--- /dev/null
+++ b/tools/lib/bpf/nlattr.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+
+/*
+ * NETLINK Netlink attributes
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation version 2.1
+ * of the License.
+ *
+ * Copyright (c) 2003-2013 Thomas Graf <tgraf@suug.ch>
+ */
+
+#ifndef __NLATTR_H
+#define __NLATTR_H
+
+#include <stdint.h>
+#include <linux/netlink.h>
+/* avoid multiple definition of netlink features */
+#define __LINUX_NETLINK_H
+
+/**
+ * Standard attribute types to specify validation policy
+ */
+enum {
+ NLA_UNSPEC, /**< Unspecified type, binary data chunk */
+ NLA_U8, /**< 8 bit integer */
+ NLA_U16, /**< 16 bit integer */
+ NLA_U32, /**< 32 bit integer */
+ NLA_U64, /**< 64 bit integer */
+ NLA_STRING, /**< NUL terminated character string */
+ NLA_FLAG, /**< Flag */
+ NLA_MSECS, /**< Micro seconds (64bit) */
+ NLA_NESTED, /**< Nested attributes */
+ __NLA_TYPE_MAX,
+};
+
+#define NLA_TYPE_MAX (__NLA_TYPE_MAX - 1)
+
+/**
+ * @ingroup attr
+ * Attribute validation policy.
+ *
+ * See section @core_doc{core_attr_parse,Attribute Parsing} for more details.
+ */
+struct nla_policy {
+ /** Type of attribute or NLA_UNSPEC */
+ uint16_t type;
+
+ /** Minimal length of payload required */
+ uint16_t minlen;
+
+ /** Maximal length of payload allowed */
+ uint16_t maxlen;
+};
+
+/**
+ * @ingroup attr
+ * Iterate over a stream of attributes
+ * @arg pos loop counter, set to current attribute
+ * @arg head head of attribute stream
+ * @arg len length of attribute stream
+ * @arg rem initialized to len, holds bytes currently remaining in stream
+ */
+#define nla_for_each_attr(pos, head, len, rem) \
+ for (pos = head, rem = len; \
+ nla_ok(pos, rem); \
+ pos = nla_next(pos, &(rem)))
+
+int nla_dump_errormsg(struct nlmsghdr *nlh);
+
+#endif /* __NLATTR_H */
diff --git a/tools/lib/find_bit.c b/tools/lib/find_bit.c
index 42c15f906aac..a88bd507091e 100644
--- a/tools/lib/find_bit.c
+++ b/tools/lib/find_bit.c
@@ -22,22 +22,29 @@
#include <linux/bitmap.h>
#include <linux/kernel.h>
-#if !defined(find_next_bit)
+#if !defined(find_next_bit) || !defined(find_next_zero_bit) || \
+ !defined(find_next_and_bit)
/*
- * This is a common helper function for find_next_bit and
- * find_next_zero_bit. The difference is the "invert" argument, which
- * is XORed with each fetched word before searching it for one bits.
+ * This is a common helper function for find_next_bit, find_next_zero_bit, and
+ * find_next_and_bit. The differences are:
+ * - The "invert" argument, which is XORed with each fetched word before
+ * searching it for one bits.
+ * - The optional "addr2", which is anded with "addr1" if present.
*/
-static unsigned long _find_next_bit(const unsigned long *addr,
- unsigned long nbits, unsigned long start, unsigned long invert)
+static inline unsigned long _find_next_bit(const unsigned long *addr1,
+ const unsigned long *addr2, unsigned long nbits,
+ unsigned long start, unsigned long invert)
{
unsigned long tmp;
if (unlikely(start >= nbits))
return nbits;
- tmp = addr[start / BITS_PER_LONG] ^ invert;
+ tmp = addr1[start / BITS_PER_LONG];
+ if (addr2)
+ tmp &= addr2[start / BITS_PER_LONG];
+ tmp ^= invert;
/* Handle 1st word. */
tmp &= BITMAP_FIRST_WORD_MASK(start);
@@ -48,7 +55,10 @@ static unsigned long _find_next_bit(const unsigned long *addr,
if (start >= nbits)
return nbits;
- tmp = addr[start / BITS_PER_LONG] ^ invert;
+ tmp = addr1[start / BITS_PER_LONG];
+ if (addr2)
+ tmp &= addr2[start / BITS_PER_LONG];
+ tmp ^= invert;
}
return min(start + __ffs(tmp), nbits);
@@ -62,7 +72,7 @@ static unsigned long _find_next_bit(const unsigned long *addr,
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
- return _find_next_bit(addr, size, offset, 0UL);
+ return _find_next_bit(addr, NULL, size, offset, 0UL);
}
#endif
@@ -104,6 +114,15 @@ unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
- return _find_next_bit(addr, size, offset, ~0UL);
+ return _find_next_bit(addr, NULL, size, offset, ~0UL);
+}
+#endif
+
+#ifndef find_next_and_bit
+unsigned long find_next_and_bit(const unsigned long *addr1,
+ const unsigned long *addr2, unsigned long size,
+ unsigned long offset)
+{
+ return _find_next_bit(addr1, addr2, size, offset, 0UL);
}
#endif
diff --git a/tools/lib/subcmd/pager.c b/tools/lib/subcmd/pager.c
index 5ba754d17952..9997a8805a82 100644
--- a/tools/lib/subcmd/pager.c
+++ b/tools/lib/subcmd/pager.c
@@ -30,10 +30,13 @@ static void pager_preexec(void)
* have real input
*/
fd_set in;
+ fd_set exception;
FD_ZERO(&in);
+ FD_ZERO(&exception);
FD_SET(0, &in);
- select(1, &in, NULL, &in, NULL);
+ FD_SET(0, &exception);
+ select(1, &in, NULL, &exception, NULL);
setenv("LESS", "FRSX", 0);
}
diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore
index 643cc4ba6872..3e5135dded16 100644
--- a/tools/perf/.gitignore
+++ b/tools/perf/.gitignore
@@ -31,5 +31,6 @@ config.mak.autogen
.config-detected
util/intel-pt-decoder/inat-tables.c
arch/*/include/generated/
+trace/beauty/generated/
pmu-events/pmu-events.c
pmu-events/jevents
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 65681a1a292a..bf4ca749d1ac 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -1566,7 +1566,8 @@ static struct option __record_options[] = {
OPT_BOOLEAN_SET('T', "timestamp", &record.opts.sample_time,
&record.opts.sample_time_set,
"Record the sample timestamps"),
- OPT_BOOLEAN('P', "period", &record.opts.period, "Record the sample period"),
+ OPT_BOOLEAN_SET('P', "period", &record.opts.period, &record.opts.period_set,
+ "Record the sample period"),
OPT_BOOLEAN('n', "no-samples", &record.opts.no_samples,
"don't sample"),
OPT_BOOLEAN_SET('N', "no-buildid-cache", &record.no_buildid_cache,
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 17d11deeb88d..e7f1b182fc15 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1661,9 +1661,12 @@ static int trace__resolve_callchain(struct trace *trace, struct perf_evsel *evse
struct callchain_cursor *cursor)
{
struct addr_location al;
+ int max_stack = evsel->attr.sample_max_stack ?
+ evsel->attr.sample_max_stack :
+ trace->max_stack;
if (machine__resolve(trace->host, &al, sample) < 0 ||
- thread__resolve_callchain(al.thread, cursor, evsel, sample, NULL, NULL, evsel->attr.sample_max_stack))
+ thread__resolve_callchain(al.thread, cursor, evsel, sample, NULL, NULL, max_stack))
return -1;
return 0;
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 2357f4ccc9c7..cfe46236a5e5 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -50,6 +50,7 @@ struct record_opts {
bool sample_time_set;
bool sample_cpu;
bool period;
+ bool period_set;
bool running_time;
bool full_auxtrace;
bool auxtrace_snapshot_mode;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 66fa45198a11..ff359c9ece2e 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -745,12 +745,14 @@ static void apply_config_terms(struct perf_evsel *evsel,
if (!(term->weak && opts->user_interval != ULLONG_MAX)) {
attr->sample_period = term->val.period;
attr->freq = 0;
+ perf_evsel__reset_sample_bit(evsel, PERIOD);
}
break;
case PERF_EVSEL__CONFIG_TERM_FREQ:
if (!(term->weak && opts->user_freq != UINT_MAX)) {
attr->sample_freq = term->val.freq;
attr->freq = 1;
+ perf_evsel__set_sample_bit(evsel, PERIOD);
}
break;
case PERF_EVSEL__CONFIG_TERM_TIME:
@@ -969,9 +971,6 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
if (target__has_cpu(&opts->target) || opts->sample_cpu)
perf_evsel__set_sample_bit(evsel, CPU);
- if (opts->period)
- perf_evsel__set_sample_bit(evsel, PERIOD);
-
/*
* When the user explicitly disabled time don't force it here.
*/
@@ -1073,6 +1072,14 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
apply_config_terms(evsel, opts, track);
evsel->ignore_missing_thread = opts->ignore_missing_thread;
+
+ /* The --period option takes the precedence. */
+ if (opts->period_set) {
+ if (opts->period)
+ perf_evsel__set_sample_bit(evsel, PERIOD);
+ else
+ perf_evsel__reset_sample_bit(evsel, PERIOD);
+ }
}
static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index db33b28c5ef3..0392153a0009 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -37,10 +37,12 @@ obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
nfit-y := $(ACPI_SRC)/core.o
nfit-$(CONFIG_X86_MCE) += $(ACPI_SRC)/mce.o
+nfit-y += acpi_nfit_test.o
nfit-y += config_check.o
nd_pmem-y := $(NVDIMM_SRC)/pmem.o
nd_pmem-y += pmem-dax.o
+nd_pmem-y += pmem_test.o
nd_pmem-y += config_check.o
nd_btt-y := $(NVDIMM_SRC)/btt.o
@@ -57,6 +59,7 @@ dax-y += config_check.o
device_dax-y := $(DAX_SRC)/device.o
device_dax-y += dax-dev.o
+device_dax-y += device_dax_test.o
device_dax-y += config_check.o
dax_pmem-y := $(DAX_SRC)/pmem.o
@@ -75,6 +78,7 @@ libnvdimm-$(CONFIG_ND_CLAIM) += $(NVDIMM_SRC)/claim.o
libnvdimm-$(CONFIG_BTT) += $(NVDIMM_SRC)/btt_devs.o
libnvdimm-$(CONFIG_NVDIMM_PFN) += $(NVDIMM_SRC)/pfn_devs.o
libnvdimm-$(CONFIG_NVDIMM_DAX) += $(NVDIMM_SRC)/dax_devs.o
+libnvdimm-y += libnvdimm_test.o
libnvdimm-y += config_check.o
obj-m += test/
diff --git a/tools/testing/nvdimm/acpi_nfit_test.c b/tools/testing/nvdimm/acpi_nfit_test.c
new file mode 100644
index 000000000000..43521512e577
--- /dev/null
+++ b/tools/testing/nvdimm/acpi_nfit_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(acpi_nfit);
diff --git a/tools/testing/nvdimm/device_dax_test.c b/tools/testing/nvdimm/device_dax_test.c
new file mode 100644
index 000000000000..24b17bf42429
--- /dev/null
+++ b/tools/testing/nvdimm/device_dax_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(device_dax);
diff --git a/tools/testing/nvdimm/libnvdimm_test.c b/tools/testing/nvdimm/libnvdimm_test.c
new file mode 100644
index 000000000000..00ca30b23932
--- /dev/null
+++ b/tools/testing/nvdimm/libnvdimm_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(libnvdimm);
diff --git a/tools/testing/nvdimm/pmem_test.c b/tools/testing/nvdimm/pmem_test.c
new file mode 100644
index 000000000000..fd38f92275cf
--- /dev/null
+++ b/tools/testing/nvdimm/pmem_test.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+#include <linux/module.h>
+#include <linux/printk.h>
+#include "watermark.h"
+
+nfit_test_watermark(pmem);
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index e1f75a1914a1..ff9d3a5825e1 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -104,15 +104,14 @@ void *__wrap_devm_memremap(struct device *dev, resource_size_t offset,
}
EXPORT_SYMBOL(__wrap_devm_memremap);
-void *__wrap_devm_memremap_pages(struct device *dev, struct resource *res,
- struct percpu_ref *ref, struct vmem_altmap *altmap)
+void *__wrap_devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap)
{
- resource_size_t offset = res->start;
+ resource_size_t offset = pgmap->res.start;
struct nfit_test_resource *nfit_res = get_nfit_res(offset);
if (nfit_res)
return nfit_res->buf + offset - nfit_res->res.start;
- return devm_memremap_pages(dev, res, ref, altmap);
+ return devm_memremap_pages(dev, pgmap);
}
EXPORT_SYMBOL(__wrap_devm_memremap_pages);
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 7217b2b953b5..620fa78b3b1b 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -27,6 +27,7 @@
#include <nfit.h>
#include <nd.h>
#include "nfit_test.h"
+#include "../watermark.h"
/*
* Generate an NFIT table to describe the following topology:
@@ -137,6 +138,14 @@ static u32 handle[] = {
static unsigned long dimm_fail_cmd_flags[NUM_DCR];
+struct nfit_test_fw {
+ enum intel_fw_update_state state;
+ u32 context;
+ u64 version;
+ u32 size_received;
+ u64 end_time;
+};
+
struct nfit_test {
struct acpi_nfit_desc acpi_desc;
struct platform_device pdev;
@@ -168,8 +177,11 @@ struct nfit_test {
spinlock_t lock;
} ars_state;
struct device *dimm_dev[NUM_DCR];
+ struct nd_intel_smart *smart;
+ struct nd_intel_smart_threshold *smart_threshold;
struct badrange badrange;
struct work_struct work;
+ struct nfit_test_fw *fw;
};
static struct workqueue_struct *nfit_wq;
@@ -181,6 +193,226 @@ static struct nfit_test *to_nfit_test(struct device *dev)
return container_of(pdev, struct nfit_test, pdev);
}
+static int nd_intel_test_get_fw_info(struct nfit_test *t,
+ struct nd_intel_fw_info *nd_cmd, unsigned int buf_len,
+ int idx)
+{
+ struct device *dev = &t->pdev.dev;
+ struct nfit_test_fw *fw = &t->fw[idx];
+
+ dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p, buf_len: %u, idx: %d\n",
+ __func__, t, nd_cmd, buf_len, idx);
+
+ if (buf_len < sizeof(*nd_cmd))
+ return -EINVAL;
+
+ nd_cmd->status = 0;
+ nd_cmd->storage_size = INTEL_FW_STORAGE_SIZE;
+ nd_cmd->max_send_len = INTEL_FW_MAX_SEND_LEN;
+ nd_cmd->query_interval = INTEL_FW_QUERY_INTERVAL;
+ nd_cmd->max_query_time = INTEL_FW_QUERY_MAX_TIME;
+ nd_cmd->update_cap = 0;
+ nd_cmd->fis_version = INTEL_FW_FIS_VERSION;
+ nd_cmd->run_version = 0;
+ nd_cmd->updated_version = fw->version;
+
+ return 0;
+}
+
+static int nd_intel_test_start_update(struct nfit_test *t,
+ struct nd_intel_fw_start *nd_cmd, unsigned int buf_len,
+ int idx)
+{
+ struct device *dev = &t->pdev.dev;
+ struct nfit_test_fw *fw = &t->fw[idx];
+
+ dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+ __func__, t, nd_cmd, buf_len, idx);
+
+ if (buf_len < sizeof(*nd_cmd))
+ return -EINVAL;
+
+ if (fw->state != FW_STATE_NEW) {
+ /* extended status, FW update in progress */
+ nd_cmd->status = 0x10007;
+ return 0;
+ }
+
+ fw->state = FW_STATE_IN_PROGRESS;
+ fw->context++;
+ fw->size_received = 0;
+ nd_cmd->status = 0;
+ nd_cmd->context = fw->context;
+
+ dev_dbg(dev, "%s: context issued: %#x\n", __func__, nd_cmd->context);
+
+ return 0;
+}
+
+static int nd_intel_test_send_data(struct nfit_test *t,
+ struct nd_intel_fw_send_data *nd_cmd, unsigned int buf_len,
+ int idx)
+{
+ struct device *dev = &t->pdev.dev;
+ struct nfit_test_fw *fw = &t->fw[idx];
+ u32 *status = (u32 *)&nd_cmd->data[nd_cmd->length];
+
+ dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+ __func__, t, nd_cmd, buf_len, idx);
+
+ if (buf_len < sizeof(*nd_cmd))
+ return -EINVAL;
+
+
+ dev_dbg(dev, "%s: cmd->status: %#x\n", __func__, *status);
+ dev_dbg(dev, "%s: cmd->data[0]: %#x\n", __func__, nd_cmd->data[0]);
+ dev_dbg(dev, "%s: cmd->data[%u]: %#x\n", __func__, nd_cmd->length-1,
+ nd_cmd->data[nd_cmd->length-1]);
+
+ if (fw->state != FW_STATE_IN_PROGRESS) {
+ dev_dbg(dev, "%s: not in IN_PROGRESS state\n", __func__);
+ *status = 0x5;
+ return 0;
+ }
+
+ if (nd_cmd->context != fw->context) {
+ dev_dbg(dev, "%s: incorrect context: in: %#x correct: %#x\n",
+ __func__, nd_cmd->context, fw->context);
+ *status = 0x10007;
+ return 0;
+ }
+
+ /*
+ * check offset + len > size of fw storage
+ * check length is > max send length
+ */
+ if (nd_cmd->offset + nd_cmd->length > INTEL_FW_STORAGE_SIZE ||
+ nd_cmd->length > INTEL_FW_MAX_SEND_LEN) {
+ *status = 0x3;
+ dev_dbg(dev, "%s: buffer boundary violation\n", __func__);
+ return 0;
+ }
+
+ fw->size_received += nd_cmd->length;
+ dev_dbg(dev, "%s: copying %u bytes, %u bytes so far\n",
+ __func__, nd_cmd->length, fw->size_received);
+ *status = 0;
+ return 0;
+}
+
+static int nd_intel_test_finish_fw(struct nfit_test *t,
+ struct nd_intel_fw_finish_update *nd_cmd,
+ unsigned int buf_len, int idx)
+{
+ struct device *dev = &t->pdev.dev;
+ struct nfit_test_fw *fw = &t->fw[idx];
+
+ dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+ __func__, t, nd_cmd, buf_len, idx);
+
+ if (fw->state == FW_STATE_UPDATED) {
+ /* update already done, need cold boot */
+ nd_cmd->status = 0x20007;
+ return 0;
+ }
+
+ dev_dbg(dev, "%s: context: %#x ctrl_flags: %#x\n",
+ __func__, nd_cmd->context, nd_cmd->ctrl_flags);
+
+ switch (nd_cmd->ctrl_flags) {
+ case 0: /* finish */
+ if (nd_cmd->context != fw->context) {
+ dev_dbg(dev, "%s: incorrect context: in: %#x correct: %#x\n",
+ __func__, nd_cmd->context,
+ fw->context);
+ nd_cmd->status = 0x10007;
+ return 0;
+ }
+ nd_cmd->status = 0;
+ fw->state = FW_STATE_VERIFY;
+ /* set 1 second of time for firmware "update" */
+ fw->end_time = jiffies + HZ;
+ break;
+
+ case 1: /* abort */
+ fw->size_received = 0;
+ /* successfully aborted status */
+ nd_cmd->status = 0x40007;
+ fw->state = FW_STATE_NEW;
+ dev_dbg(dev, "%s: abort successful\n", __func__);
+ break;
+
+ default: /* bad control flag */
+ dev_warn(dev, "%s: unknown control flag: %#x\n",
+ __func__, nd_cmd->ctrl_flags);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int nd_intel_test_finish_query(struct nfit_test *t,
+ struct nd_intel_fw_finish_query *nd_cmd,
+ unsigned int buf_len, int idx)
+{
+ struct device *dev = &t->pdev.dev;
+ struct nfit_test_fw *fw = &t->fw[idx];
+
+ dev_dbg(dev, "%s(nfit_test: %p nd_cmd: %p buf_len: %u idx: %d)\n",
+ __func__, t, nd_cmd, buf_len, idx);
+
+ if (buf_len < sizeof(*nd_cmd))
+ return -EINVAL;
+
+ if (nd_cmd->context != fw->context) {
+ dev_dbg(dev, "%s: incorrect context: in: %#x correct: %#x\n",
+ __func__, nd_cmd->context, fw->context);
+ nd_cmd->status = 0x10007;
+ return 0;
+ }
+
+ dev_dbg(dev, "%s context: %#x\n", __func__, nd_cmd->context);
+
+ switch (fw->state) {
+ case FW_STATE_NEW:
+ nd_cmd->updated_fw_rev = 0;
+ nd_cmd->status = 0;
+ dev_dbg(dev, "%s: new state\n", __func__);
+ break;
+
+ case FW_STATE_IN_PROGRESS:
+ /* sequencing error */
+ nd_cmd->status = 0x40007;
+ nd_cmd->updated_fw_rev = 0;
+ dev_dbg(dev, "%s: sequence error\n", __func__);
+ break;
+
+ case FW_STATE_VERIFY:
+ if (time_is_after_jiffies64(fw->end_time)) {
+ nd_cmd->updated_fw_rev = 0;
+ nd_cmd->status = 0x20007;
+ dev_dbg(dev, "%s: still verifying\n", __func__);
+ break;
+ }
+
+ dev_dbg(dev, "%s: transition out verify\n", __func__);
+ fw->state = FW_STATE_UPDATED;
+ /* we are going to fall through if it's "done" */
+ case FW_STATE_UPDATED:
+ nd_cmd->status = 0;
+ /* bogus test version */
+ fw->version = nd_cmd->updated_fw_rev =
+ INTEL_FW_FAKE_VERSION;
+ dev_dbg(dev, "%s: updated\n", __func__);
+ break;
+
+ default: /* we should never get here */
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int nfit_test_cmd_get_config_size(struct nd_cmd_get_config_size *nd_cmd,
unsigned int buf_len)
{
@@ -440,39 +672,66 @@ static int nfit_test_cmd_translate_spa(struct nvdimm_bus *bus,
return 0;
}
-static int nfit_test_cmd_smart(struct nd_cmd_smart *smart, unsigned int buf_len)
+static int nfit_test_cmd_smart(struct nd_intel_smart *smart, unsigned int buf_len,
+ struct nd_intel_smart *smart_data)
{
- static const struct nd_smart_payload smart_data = {
- .flags = ND_SMART_HEALTH_VALID | ND_SMART_TEMP_VALID
- | ND_SMART_SPARES_VALID | ND_SMART_ALARM_VALID
- | ND_SMART_USED_VALID | ND_SMART_SHUTDOWN_VALID,
- .health = ND_SMART_NON_CRITICAL_HEALTH,
- .temperature = 23 * 16,
- .spares = 75,
- .alarm_flags = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
- .life_used = 5,
- .shutdown_state = 0,
- .vendor_size = 0,
- };
-
if (buf_len < sizeof(*smart))
return -EINVAL;
- memcpy(smart->data, &smart_data, sizeof(smart_data));
+ memcpy(smart, smart_data, sizeof(*smart));
return 0;
}
-static int nfit_test_cmd_smart_threshold(struct nd_cmd_smart_threshold *smart_t,
- unsigned int buf_len)
+static int nfit_test_cmd_smart_threshold(
+ struct nd_intel_smart_threshold *out,
+ unsigned int buf_len,
+ struct nd_intel_smart_threshold *smart_t)
{
- static const struct nd_smart_threshold_payload smart_t_data = {
- .alarm_control = ND_SMART_SPARE_TRIP | ND_SMART_TEMP_TRIP,
- .temperature = 40 * 16,
- .spares = 5,
- };
-
if (buf_len < sizeof(*smart_t))
return -EINVAL;
- memcpy(smart_t->data, &smart_t_data, sizeof(smart_t_data));
+ memcpy(out, smart_t, sizeof(*smart_t));
+ return 0;
+}
+
+static void smart_notify(struct device *bus_dev,
+ struct device *dimm_dev, struct nd_intel_smart *smart,
+ struct nd_intel_smart_threshold *thresh)
+{
+ dev_dbg(dimm_dev, "%s: alarm: %#x spares: %d (%d) mtemp: %d (%d) ctemp: %d (%d)\n",
+ __func__, thresh->alarm_control, thresh->spares,
+ smart->spares, thresh->media_temperature,
+ smart->media_temperature, thresh->ctrl_temperature,
+ smart->ctrl_temperature);
+ if (((thresh->alarm_control & ND_INTEL_SMART_SPARE_TRIP)
+ && smart->spares
+ <= thresh->spares)
+ || ((thresh->alarm_control & ND_INTEL_SMART_TEMP_TRIP)
+ && smart->media_temperature
+ >= thresh->media_temperature)
+ || ((thresh->alarm_control & ND_INTEL_SMART_CTEMP_TRIP)
+ && smart->ctrl_temperature
+ >= thresh->ctrl_temperature)) {
+ device_lock(bus_dev);
+ __acpi_nvdimm_notify(dimm_dev, 0x81);
+ device_unlock(bus_dev);
+ }
+}
+
+static int nfit_test_cmd_smart_set_threshold(
+ struct nd_intel_smart_set_threshold *in,
+ unsigned int buf_len,
+ struct nd_intel_smart_threshold *thresh,
+ struct nd_intel_smart *smart,
+ struct device *bus_dev, struct device *dimm_dev)
+{
+ unsigned int size;
+
+ size = sizeof(*in) - 4;
+ if (buf_len < size)
+ return -EINVAL;
+ memcpy(thresh->data, in, size);
+ in->status = 0;
+ smart_notify(bus_dev, dimm_dev, smart, thresh);
+
return 0;
}
@@ -563,6 +822,52 @@ static int nfit_test_cmd_ars_inject_status(struct nfit_test *t,
return 0;
}
+static int nd_intel_test_cmd_set_lss_status(struct nfit_test *t,
+ struct nd_intel_lss *nd_cmd, unsigned int buf_len)
+{
+ struct device *dev = &t->pdev.dev;
+
+ if (buf_len < sizeof(*nd_cmd))
+ return -EINVAL;
+
+ switch (nd_cmd->enable) {
+ case 0:
+ nd_cmd->status = 0;
+ dev_dbg(dev, "%s: Latch System Shutdown Status disabled\n",
+ __func__);
+ break;
+ case 1:
+ nd_cmd->status = 0;
+ dev_dbg(dev, "%s: Latch System Shutdown Status enabled\n",
+ __func__);
+ break;
+ default:
+ dev_warn(dev, "Unknown enable value: %#x\n", nd_cmd->enable);
+ nd_cmd->status = 0x3;
+ break;
+ }
+
+
+ return 0;
+}
+
+static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
+{
+ int i;
+
+ /* lookup per-dimm data */
+ for (i = 0; i < ARRAY_SIZE(handle); i++)
+ if (__to_nfit_memdev(nfit_mem)->device_handle == handle[i])
+ break;
+ if (i >= ARRAY_SIZE(handle))
+ return -ENXIO;
+
+ if ((1 << func) & dimm_fail_cmd_flags[i])
+ return -EIO;
+
+ return i;
+}
+
static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
struct nvdimm *nvdimm, unsigned int cmd, void *buf,
unsigned int buf_len, int *cmd_rc)
@@ -591,22 +896,57 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
func = call_pkg->nd_command;
if (call_pkg->nd_family != nfit_mem->family)
return -ENOTTY;
+
+ i = get_dimm(nfit_mem, func);
+ if (i < 0)
+ return i;
+
+ switch (func) {
+ case ND_INTEL_ENABLE_LSS_STATUS:
+ return nd_intel_test_cmd_set_lss_status(t,
+ buf, buf_len);
+ case ND_INTEL_FW_GET_INFO:
+ return nd_intel_test_get_fw_info(t, buf,
+ buf_len, i - t->dcr_idx);
+ case ND_INTEL_FW_START_UPDATE:
+ return nd_intel_test_start_update(t, buf,
+ buf_len, i - t->dcr_idx);
+ case ND_INTEL_FW_SEND_DATA:
+ return nd_intel_test_send_data(t, buf,
+ buf_len, i - t->dcr_idx);
+ case ND_INTEL_FW_FINISH_UPDATE:
+ return nd_intel_test_finish_fw(t, buf,
+ buf_len, i - t->dcr_idx);
+ case ND_INTEL_FW_FINISH_QUERY:
+ return nd_intel_test_finish_query(t, buf,
+ buf_len, i - t->dcr_idx);
+ case ND_INTEL_SMART:
+ return nfit_test_cmd_smart(buf, buf_len,
+ &t->smart[i - t->dcr_idx]);
+ case ND_INTEL_SMART_THRESHOLD:
+ return nfit_test_cmd_smart_threshold(buf,
+ buf_len,
+ &t->smart_threshold[i -
+ t->dcr_idx]);
+ case ND_INTEL_SMART_SET_THRESHOLD:
+ return nfit_test_cmd_smart_set_threshold(buf,
+ buf_len,
+ &t->smart_threshold[i -
+ t->dcr_idx],
+ &t->smart[i - t->dcr_idx],
+ &t->pdev.dev, t->dimm_dev[i]);
+ default:
+ return -ENOTTY;
+ }
}
if (!test_bit(cmd, &cmd_mask)
|| !test_bit(func, &nfit_mem->dsm_mask))
return -ENOTTY;
- /* lookup label space for the given dimm */
- for (i = 0; i < ARRAY_SIZE(handle); i++)
- if (__to_nfit_memdev(nfit_mem)->device_handle ==
- handle[i])
- break;
- if (i >= ARRAY_SIZE(handle))
- return -ENXIO;
-
- if ((1 << func) & dimm_fail_cmd_flags[i])
- return -EIO;
+ i = get_dimm(nfit_mem, func);
+ if (i < 0)
+ return i;
switch (func) {
case ND_CMD_GET_CONFIG_SIZE:
@@ -620,15 +960,6 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
rc = nfit_test_cmd_set_config_data(buf, buf_len,
t->label[i - t->dcr_idx]);
break;
- case ND_CMD_SMART:
- rc = nfit_test_cmd_smart(buf, buf_len);
- break;
- case ND_CMD_SMART_THRESHOLD:
- rc = nfit_test_cmd_smart_threshold(buf, buf_len);
- device_lock(&t->pdev.dev);
- __acpi_nvdimm_notify(t->dimm_dev[i], 0x81);
- device_unlock(&t->pdev.dev);
- break;
default:
return -ENOTTY;
}
@@ -872,6 +1203,44 @@ static const struct attribute_group *nfit_test_dimm_attribute_groups[] = {
NULL,
};
+static void smart_init(struct nfit_test *t)
+{
+ int i;
+ const struct nd_intel_smart_threshold smart_t_data = {
+ .alarm_control = ND_INTEL_SMART_SPARE_TRIP
+ | ND_INTEL_SMART_TEMP_TRIP,
+ .media_temperature = 40 * 16,
+ .ctrl_temperature = 30 * 16,
+ .spares = 5,
+ };
+ const struct nd_intel_smart smart_data = {
+ .flags = ND_INTEL_SMART_HEALTH_VALID
+ | ND_INTEL_SMART_SPARES_VALID
+ | ND_INTEL_SMART_ALARM_VALID
+ | ND_INTEL_SMART_USED_VALID
+ | ND_INTEL_SMART_SHUTDOWN_VALID
+ | ND_INTEL_SMART_MTEMP_VALID,
+ .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
+ .media_temperature = 23 * 16,
+ .ctrl_temperature = 30 * 16,
+ .pmic_temperature = 40 * 16,
+ .spares = 75,
+ .alarm_flags = ND_INTEL_SMART_SPARE_TRIP
+ | ND_INTEL_SMART_TEMP_TRIP,
+ .ait_status = 1,
+ .life_used = 5,
+ .shutdown_state = 0,
+ .vendor_size = 0,
+ .shutdown_count = 100,
+ };
+
+ for (i = 0; i < t->num_dcr; i++) {
+ memcpy(&t->smart[i], &smart_data, sizeof(smart_data));
+ memcpy(&t->smart_threshold[i], &smart_t_data,
+ sizeof(smart_t_data));
+ }
+}
+
static int nfit_test0_alloc(struct nfit_test *t)
{
size_t nfit_size = sizeof(struct acpi_nfit_system_address) * NUM_SPA
@@ -881,7 +1250,8 @@ static int nfit_test0_alloc(struct nfit_test *t)
window_size) * NUM_DCR
+ sizeof(struct acpi_nfit_data_region) * NUM_BDW
+ (sizeof(struct acpi_nfit_flush_address)
- + sizeof(u64) * NUM_HINTS) * NUM_DCR;
+ + sizeof(u64) * NUM_HINTS) * NUM_DCR
+ + sizeof(struct acpi_nfit_capabilities);
int i;
t->nfit_buf = test_alloc(t, nfit_size, &t->nfit_dma);
@@ -939,6 +1309,7 @@ static int nfit_test0_alloc(struct nfit_test *t)
return -ENOMEM;
}
+ smart_init(t);
return ars_state_init(&t->pdev.dev, &t->ars_state);
}
@@ -969,6 +1340,7 @@ static int nfit_test1_alloc(struct nfit_test *t)
if (!t->spa_set[1])
return -ENOMEM;
+ smart_init(t);
return ars_state_init(&t->pdev.dev, &t->ars_state);
}
@@ -993,6 +1365,7 @@ static void nfit_test0_setup(struct nfit_test *t)
struct acpi_nfit_control_region *dcr;
struct acpi_nfit_data_region *bdw;
struct acpi_nfit_flush_address *flush;
+ struct acpi_nfit_capabilities *pcap;
unsigned int offset, i;
/*
@@ -1500,8 +1873,16 @@ static void nfit_test0_setup(struct nfit_test *t)
for (i = 0; i < NUM_HINTS; i++)
flush->hint_address[i] = t->flush_dma[3] + i * sizeof(u64);
+ /* platform capabilities */
+ pcap = nfit_buf + offset + flush_hint_size * 4;
+ pcap->header.type = ACPI_NFIT_TYPE_CAPABILITIES;
+ pcap->header.length = sizeof(*pcap);
+ pcap->highest_capability = 1;
+ pcap->capabilities = ACPI_NFIT_CAPABILITY_CACHE_FLUSH |
+ ACPI_NFIT_CAPABILITY_MEM_FLUSH;
+
if (t->setup_hotplug) {
- offset = offset + flush_hint_size * 4;
+ offset = offset + flush_hint_size * 4 + sizeof(*pcap);
/* dcr-descriptor4: blk */
dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
@@ -1642,17 +2023,24 @@ static void nfit_test0_setup(struct nfit_test *t)
set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en);
set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
- set_bit(ND_CMD_SMART, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_SMART, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_SMART_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_SMART_SET_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en);
set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
set_bit(ND_CMD_CALL, &acpi_desc->bus_cmd_force_en);
- set_bit(ND_CMD_SMART_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
set_bit(NFIT_CMD_TRANSLATE_SPA, &acpi_desc->bus_nfit_cmd_force_en);
set_bit(NFIT_CMD_ARS_INJECT_SET, &acpi_desc->bus_nfit_cmd_force_en);
set_bit(NFIT_CMD_ARS_INJECT_CLEAR, &acpi_desc->bus_nfit_cmd_force_en);
set_bit(NFIT_CMD_ARS_INJECT_GET, &acpi_desc->bus_nfit_cmd_force_en);
+ set_bit(ND_INTEL_FW_GET_INFO, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_FW_START_UPDATE, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_FW_SEND_DATA, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_FW_FINISH_UPDATE, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_FW_FINISH_QUERY, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_ENABLE_LSS_STATUS, &acpi_desc->dimm_cmd_force_en);
}
static void nfit_test1_setup(struct nfit_test *t)
@@ -1750,6 +2138,7 @@ static void nfit_test1_setup(struct nfit_test *t)
set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
+ set_bit(ND_INTEL_ENABLE_LSS_STATUS, &acpi_desc->dimm_cmd_force_en);
}
static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
@@ -2054,10 +2443,18 @@ static int nfit_test_probe(struct platform_device *pdev)
sizeof(struct nfit_test_dcr *), GFP_KERNEL);
nfit_test->dcr_dma = devm_kcalloc(dev, num,
sizeof(dma_addr_t), GFP_KERNEL);
+ nfit_test->smart = devm_kcalloc(dev, num,
+ sizeof(struct nd_intel_smart), GFP_KERNEL);
+ nfit_test->smart_threshold = devm_kcalloc(dev, num,
+ sizeof(struct nd_intel_smart_threshold),
+ GFP_KERNEL);
+ nfit_test->fw = devm_kcalloc(dev, num,
+ sizeof(struct nfit_test_fw), GFP_KERNEL);
if (nfit_test->dimm && nfit_test->dimm_dma && nfit_test->label
&& nfit_test->label_dma && nfit_test->dcr
&& nfit_test->dcr_dma && nfit_test->flush
- && nfit_test->flush_dma)
+ && nfit_test->flush_dma
+ && nfit_test->fw)
/* pass */;
else
return -ENOMEM;
@@ -2159,6 +2556,11 @@ static __init int nfit_test_init(void)
{
int rc, i;
+ pmem_test();
+ libnvdimm_test();
+ acpi_nfit_test();
+ device_dax_test();
+
nfit_test_setup(nfit_test_lookup, nfit_test_evaluate_dsm);
nfit_wq = create_singlethread_workqueue("nfit");
diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h
index 113b44675a71..428344519cdf 100644
--- a/tools/testing/nvdimm/test/nfit_test.h
+++ b/tools/testing/nvdimm/test/nfit_test.h
@@ -84,6 +84,140 @@ struct nd_cmd_ars_err_inj_stat {
} __packed record[0];
} __packed;
+#define ND_INTEL_SMART 1
+#define ND_INTEL_SMART_THRESHOLD 2
+#define ND_INTEL_ENABLE_LSS_STATUS 10
+#define ND_INTEL_FW_GET_INFO 12
+#define ND_INTEL_FW_START_UPDATE 13
+#define ND_INTEL_FW_SEND_DATA 14
+#define ND_INTEL_FW_FINISH_UPDATE 15
+#define ND_INTEL_FW_FINISH_QUERY 16
+#define ND_INTEL_SMART_SET_THRESHOLD 17
+
+#define ND_INTEL_SMART_HEALTH_VALID (1 << 0)
+#define ND_INTEL_SMART_SPARES_VALID (1 << 1)
+#define ND_INTEL_SMART_USED_VALID (1 << 2)
+#define ND_INTEL_SMART_MTEMP_VALID (1 << 3)
+#define ND_INTEL_SMART_CTEMP_VALID (1 << 4)
+#define ND_INTEL_SMART_SHUTDOWN_COUNT_VALID (1 << 5)
+#define ND_INTEL_SMART_AIT_STATUS_VALID (1 << 6)
+#define ND_INTEL_SMART_PTEMP_VALID (1 << 7)
+#define ND_INTEL_SMART_ALARM_VALID (1 << 9)
+#define ND_INTEL_SMART_SHUTDOWN_VALID (1 << 10)
+#define ND_INTEL_SMART_VENDOR_VALID (1 << 11)
+#define ND_INTEL_SMART_SPARE_TRIP (1 << 0)
+#define ND_INTEL_SMART_TEMP_TRIP (1 << 1)
+#define ND_INTEL_SMART_CTEMP_TRIP (1 << 2)
+#define ND_INTEL_SMART_NON_CRITICAL_HEALTH (1 << 0)
+#define ND_INTEL_SMART_CRITICAL_HEALTH (1 << 1)
+#define ND_INTEL_SMART_FATAL_HEALTH (1 << 2)
+
+struct nd_intel_smart {
+ __u32 status;
+ union {
+ struct {
+ __u32 flags;
+ __u8 reserved0[4];
+ __u8 health;
+ __u8 spares;
+ __u8 life_used;
+ __u8 alarm_flags;
+ __u16 media_temperature;
+ __u16 ctrl_temperature;
+ __u32 shutdown_count;
+ __u8 ait_status;
+ __u16 pmic_temperature;
+ __u8 reserved1[8];
+ __u8 shutdown_state;
+ __u32 vendor_size;
+ __u8 vendor_data[92];
+ } __packed;
+ __u8 data[128];
+ };
+} __packed;
+
+struct nd_intel_smart_threshold {
+ __u32 status;
+ union {
+ struct {
+ __u16 alarm_control;
+ __u8 spares;
+ __u16 media_temperature;
+ __u16 ctrl_temperature;
+ __u8 reserved[1];
+ } __packed;
+ __u8 data[8];
+ };
+} __packed;
+
+struct nd_intel_smart_set_threshold {
+ __u16 alarm_control;
+ __u8 spares;
+ __u16 media_temperature;
+ __u16 ctrl_temperature;
+ __u32 status;
+} __packed;
+
+#define INTEL_FW_STORAGE_SIZE 0x100000
+#define INTEL_FW_MAX_SEND_LEN 0xFFEC
+#define INTEL_FW_QUERY_INTERVAL 250000
+#define INTEL_FW_QUERY_MAX_TIME 3000000
+#define INTEL_FW_FIS_VERSION 0x0105
+#define INTEL_FW_FAKE_VERSION 0xffffffffabcd
+
+enum intel_fw_update_state {
+ FW_STATE_NEW = 0,
+ FW_STATE_IN_PROGRESS,
+ FW_STATE_VERIFY,
+ FW_STATE_UPDATED,
+};
+
+struct nd_intel_fw_info {
+ __u32 status;
+ __u32 storage_size;
+ __u32 max_send_len;
+ __u32 query_interval;
+ __u32 max_query_time;
+ __u8 update_cap;
+ __u8 reserved[3];
+ __u32 fis_version;
+ __u64 run_version;
+ __u64 updated_version;
+} __packed;
+
+struct nd_intel_fw_start {
+ __u32 status;
+ __u32 context;
+} __packed;
+
+/* this one has the output first because the variable input data size */
+struct nd_intel_fw_send_data {
+ __u32 context;
+ __u32 offset;
+ __u32 length;
+ __u8 data[0];
+/* this field is not declared due ot variable data from input */
+/* __u32 status; */
+} __packed;
+
+struct nd_intel_fw_finish_update {
+ __u8 ctrl_flags;
+ __u8 reserved[3];
+ __u32 context;
+ __u32 status;
+} __packed;
+
+struct nd_intel_fw_finish_query {
+ __u32 context;
+ __u32 status;
+ __u64 updated_fw_rev;
+} __packed;
+
+struct nd_intel_lss {
+ __u8 enable;
+ __u32 status;
+} __packed;
+
union acpi_object;
typedef void *acpi_handle;
diff --git a/tools/testing/nvdimm/watermark.h b/tools/testing/nvdimm/watermark.h
new file mode 100644
index 000000000000..ed0528757bd4
--- /dev/null
+++ b/tools/testing/nvdimm/watermark.h
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright(c) 2018 Intel Corporation. All rights reserved.
+#ifndef _TEST_NVDIMM_WATERMARK_H_
+#define _TEST_NVDIMM_WATERMARK_H_
+int pmem_test(void);
+int libnvdimm_test(void);
+int acpi_nfit_test(void);
+int device_dax_test(void);
+
+/*
+ * dummy routine for nfit_test to validate it is linking to the properly
+ * mocked module and not the standard one from the base tree.
+ */
+#define nfit_test_watermark(x) \
+int x##_test(void) \
+{ \
+ pr_debug("%s for nfit_test\n", KBUILD_MODNAME); \
+ return 0; \
+} \
+EXPORT_SYMBOL(x##_test)
+#endif /* _TEST_NVDIMM_WATERMARK_H_ */
diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore
index 1e09d77f1948..cc15af2e54fe 100644
--- a/tools/testing/selftests/bpf/.gitignore
+++ b/tools/testing/selftests/bpf/.gitignore
@@ -8,5 +8,6 @@ fixdep
test_align
test_dev_cgroup
test_progs
+test_tcpbpf_user
test_verifier_log
feature
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index bf05bc5e36e5..566d6adc172a 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -27,7 +27,7 @@ TEST_PROGS := test_kmod.sh test_xdp_redirect.sh test_xdp_meta.sh \
include ../lib.mk
-BPFOBJ := $(OUTPUT)/libbpf.a $(OUTPUT)/cgroup_helpers.c
+BPFOBJ := $(OUTPUT)/libbpf.a cgroup_helpers.c
$(TEST_GEN_PROGS): $(BPFOBJ)
@@ -58,7 +58,7 @@ CLANG_FLAGS = -I. -I./include/uapi -I../../../include/uapi \
$(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline
$(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline
-%.o: %.c
+$(OUTPUT)/%.o: %.c
$(CLANG) $(CLANG_FLAGS) \
-O2 -target bpf -emit-llvm -c $< -o - | \
$(LLC) -march=bpf -mcpu=$(CPU) -filetype=obj -o $@
diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c
index 697bd83de295..c0f16e93f9bd 100644
--- a/tools/testing/selftests/bpf/test_verifier.c
+++ b/tools/testing/selftests/bpf/test_verifier.c
@@ -7780,6 +7780,20 @@ static struct bpf_test tests[] = {
.result = REJECT,
},
{
+ "XDP, using ifindex from netdev",
+ .insns = {
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
+ offsetof(struct xdp_md, ingress_ifindex)),
+ BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 1, 1),
+ BPF_MOV64_IMM(BPF_REG_0, 1),
+ BPF_EXIT_INSN(),
+ },
+ .result = ACCEPT,
+ .prog_type = BPF_PROG_TYPE_XDP,
+ .retval = 1,
+ },
+ {
"meta access, test1",
.insns = {
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
diff --git a/tools/testing/selftests/membarrier/membarrier_test.c b/tools/testing/selftests/membarrier/membarrier_test.c
index 9e674d9514d1..22bffd55a523 100644
--- a/tools/testing/selftests/membarrier/membarrier_test.c
+++ b/tools/testing/selftests/membarrier/membarrier_test.c
@@ -16,49 +16,210 @@ static int sys_membarrier(int cmd, int flags)
static int test_membarrier_cmd_fail(void)
{
int cmd = -1, flags = 0;
+ const char *test_name = "sys membarrier invalid command";
if (sys_membarrier(cmd, flags) != -1) {
ksft_exit_fail_msg(
- "sys membarrier invalid command test: command = %d, flags = %d. Should fail, but passed\n",
- cmd, flags);
+ "%s test: command = %d, flags = %d. Should fail, but passed\n",
+ test_name, cmd, flags);
+ }
+ if (errno != EINVAL) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
+ test_name, flags, EINVAL, strerror(EINVAL),
+ errno, strerror(errno));
}
ksft_test_result_pass(
- "sys membarrier invalid command test: command = %d, flags = %d. Failed as expected\n",
- cmd, flags);
+ "%s test: command = %d, flags = %d, errno = %d. Failed as expected\n",
+ test_name, cmd, flags, errno);
return 0;
}
static int test_membarrier_flags_fail(void)
{
int cmd = MEMBARRIER_CMD_QUERY, flags = 1;
+ const char *test_name = "sys membarrier MEMBARRIER_CMD_QUERY invalid flags";
+
+ if (sys_membarrier(cmd, flags) != -1) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d. Should fail, but passed\n",
+ test_name, flags);
+ }
+ if (errno != EINVAL) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
+ test_name, flags, EINVAL, strerror(EINVAL),
+ errno, strerror(errno));
+ }
+
+ ksft_test_result_pass(
+ "%s test: flags = %d, errno = %d. Failed as expected\n",
+ test_name, flags, errno);
+ return 0;
+}
+
+static int test_membarrier_global_success(void)
+{
+ int cmd = MEMBARRIER_CMD_GLOBAL, flags = 0;
+ const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL";
+
+ if (sys_membarrier(cmd, flags) != 0) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d, errno = %d\n",
+ test_name, flags, errno);
+ }
+
+ ksft_test_result_pass(
+ "%s test: flags = %d\n", test_name, flags);
+ return 0;
+}
+
+static int test_membarrier_private_expedited_fail(void)
+{
+ int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
+ const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED not registered failure";
+
+ if (sys_membarrier(cmd, flags) != -1) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d. Should fail, but passed\n",
+ test_name, flags);
+ }
+ if (errno != EPERM) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
+ test_name, flags, EPERM, strerror(EPERM),
+ errno, strerror(errno));
+ }
+
+ ksft_test_result_pass(
+ "%s test: flags = %d, errno = %d\n",
+ test_name, flags, errno);
+ return 0;
+}
+
+static int test_membarrier_register_private_expedited_success(void)
+{
+ int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, flags = 0;
+ const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED";
+
+ if (sys_membarrier(cmd, flags) != 0) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d, errno = %d\n",
+ test_name, flags, errno);
+ }
+
+ ksft_test_result_pass(
+ "%s test: flags = %d\n",
+ test_name, flags);
+ return 0;
+}
+
+static int test_membarrier_private_expedited_success(void)
+{
+ int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
+ const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED";
+
+ if (sys_membarrier(cmd, flags) != 0) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d, errno = %d\n",
+ test_name, flags, errno);
+ }
+
+ ksft_test_result_pass(
+ "%s test: flags = %d\n",
+ test_name, flags);
+ return 0;
+}
+
+static int test_membarrier_private_expedited_sync_core_fail(void)
+{
+ int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;
+ const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE not registered failure";
if (sys_membarrier(cmd, flags) != -1) {
ksft_exit_fail_msg(
- "sys membarrier MEMBARRIER_CMD_QUERY invalid flags test: flags = %d. Should fail, but passed\n",
- flags);
+ "%s test: flags = %d. Should fail, but passed\n",
+ test_name, flags);
+ }
+ if (errno != EPERM) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
+ test_name, flags, EPERM, strerror(EPERM),
+ errno, strerror(errno));
+ }
+
+ ksft_test_result_pass(
+ "%s test: flags = %d, errno = %d\n",
+ test_name, flags, errno);
+ return 0;
+}
+
+static int test_membarrier_register_private_expedited_sync_core_success(void)
+{
+ int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;
+ const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE";
+
+ if (sys_membarrier(cmd, flags) != 0) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d, errno = %d\n",
+ test_name, flags, errno);
+ }
+
+ ksft_test_result_pass(
+ "%s test: flags = %d\n",
+ test_name, flags);
+ return 0;
+}
+
+static int test_membarrier_private_expedited_sync_core_success(void)
+{
+ int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
+ const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE";
+
+ if (sys_membarrier(cmd, flags) != 0) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d, errno = %d\n",
+ test_name, flags, errno);
}
ksft_test_result_pass(
- "sys membarrier MEMBARRIER_CMD_QUERY invalid flags test: flags = %d. Failed as expected\n",
- flags);
+ "%s test: flags = %d\n",
+ test_name, flags);
return 0;
}
-static int test_membarrier_success(void)
+static int test_membarrier_register_global_expedited_success(void)
{
- int cmd = MEMBARRIER_CMD_SHARED, flags = 0;
- const char *test_name = "sys membarrier MEMBARRIER_CMD_SHARED\n";
+ int cmd = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, flags = 0;
+ const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED";
if (sys_membarrier(cmd, flags) != 0) {
ksft_exit_fail_msg(
- "sys membarrier MEMBARRIER_CMD_SHARED test: flags = %d\n",
- flags);
+ "%s test: flags = %d, errno = %d\n",
+ test_name, flags, errno);
}
ksft_test_result_pass(
- "sys membarrier MEMBARRIER_CMD_SHARED test: flags = %d\n",
- flags);
+ "%s test: flags = %d\n",
+ test_name, flags);
+ return 0;
+}
+
+static int test_membarrier_global_expedited_success(void)
+{
+ int cmd = MEMBARRIER_CMD_GLOBAL_EXPEDITED, flags = 0;
+ const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL_EXPEDITED";
+
+ if (sys_membarrier(cmd, flags) != 0) {
+ ksft_exit_fail_msg(
+ "%s test: flags = %d, errno = %d\n",
+ test_name, flags, errno);
+ }
+
+ ksft_test_result_pass(
+ "%s test: flags = %d\n",
+ test_name, flags);
return 0;
}
@@ -72,7 +233,45 @@ static int test_membarrier(void)
status = test_membarrier_flags_fail();
if (status)
return status;
- status = test_membarrier_success();
+ status = test_membarrier_global_success();
+ if (status)
+ return status;
+ status = test_membarrier_private_expedited_fail();
+ if (status)
+ return status;
+ status = test_membarrier_register_private_expedited_success();
+ if (status)
+ return status;
+ status = test_membarrier_private_expedited_success();
+ if (status)
+ return status;
+ status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);
+ if (status < 0) {
+ ksft_test_result_fail("sys_membarrier() failed\n");
+ return status;
+ }
+ if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) {
+ status = test_membarrier_private_expedited_sync_core_fail();
+ if (status)
+ return status;
+ status = test_membarrier_register_private_expedited_sync_core_success();
+ if (status)
+ return status;
+ status = test_membarrier_private_expedited_sync_core_success();
+ if (status)
+ return status;
+ }
+ /*
+ * It is valid to send a global membarrier from a non-registered
+ * process.
+ */
+ status = test_membarrier_global_expedited_success();
+ if (status)
+ return status;
+ status = test_membarrier_register_global_expedited_success();
+ if (status)
+ return status;
+ status = test_membarrier_global_expedited_success();
if (status)
return status;
return 0;
@@ -94,8 +293,10 @@ static int test_membarrier_query(void)
}
ksft_exit_fail_msg("sys_membarrier() failed\n");
}
- if (!(ret & MEMBARRIER_CMD_SHARED))
+ if (!(ret & MEMBARRIER_CMD_GLOBAL)) {
+ ksft_test_result_fail("sys_membarrier() CMD_GLOBAL query failed\n");
ksft_exit_fail_msg("sys_membarrier is not supported.\n");
+ }
ksft_test_result_pass("sys_membarrier available\n");
return 0;
@@ -108,5 +309,5 @@ int main(int argc, char **argv)
test_membarrier_query();
test_membarrier();
- ksft_exit_pass();
+ return ksft_exit_pass();
}